kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			epson2: allow get_devices to be called multiple times
The probing code has been streamlined and is now more maintenable. The backend will probe when required and the get_devices hook can be called multiple times. Transfer buffers are now selected based on the connection type.merge-requests/1/head
							rodzic
							
								
									581b94fb88
								
							
						
					
					
						commit
						e73177a177
					
				| 
						 | 
				
			
			@ -189,12 +189,13 @@ static const SANE_Range outline_emphasis_range = { -2, 2, 0 };
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
e2_dev_init(Epson_Device *dev)
 | 
			
		||||
e2_dev_init(Epson_Device *dev, const char *devname, int conntype)
 | 
			
		||||
{
 | 
			
		||||
	dev->name = NULL;
 | 
			
		||||
	dev->model = NULL;
 | 
			
		||||
	dev->connection = conntype;
 | 
			
		||||
 | 
			
		||||
	dev->sane.name = NULL;
 | 
			
		||||
	dev->sane.name = devname;
 | 
			
		||||
	dev->sane.model = NULL;
 | 
			
		||||
 | 
			
		||||
	dev->sane.type = "flatbed scanner";
 | 
			
		||||
| 
						 | 
				
			
			@ -586,7 +587,7 @@ e2_discover_capabilities(Epson_Scanner *s)
 | 
			
		|||
 | 
			
		||||
		free(es);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	/* FS I, request extended identity */
 | 
			
		||||
	if (dev->extended_commands && dev->cmd->request_extended_identity) {
 | 
			
		||||
		unsigned char buf[80];
 | 
			
		||||
| 
						 | 
				
			
			@ -1146,13 +1147,21 @@ e2_set_scanning_parameters(Epson_Scanner * s)
 | 
			
		|||
void
 | 
			
		||||
e2_setup_block_mode(Epson_Scanner * s)
 | 
			
		||||
{
 | 
			
		||||
	s->block = SANE_TRUE;
 | 
			
		||||
	s->lcount = sanei_scsi_max_request_size / s->params.bytes_per_line;
 | 
			
		||||
	int maxreq;
 | 
			
		||||
 | 
			
		||||
	/* XXX Check if we can do this with other scanners,
 | 
			
		||||
	 * by bus type
 | 
			
		||||
	 */
 | 
			
		||||
	DBG(1, "max req size: %d\n", sanei_scsi_max_request_size);
 | 
			
		||||
	if (s->hw->connection == SANE_EPSON_SCSI)
 | 
			
		||||
		maxreq = sanei_scsi_max_request_size;
 | 
			
		||||
	else if (s->hw->connection == SANE_EPSON_USB)
 | 
			
		||||
		maxreq = 128 * 1024;
 | 
			
		||||
	else if (s->hw->connection == SANE_EPSON_NET)
 | 
			
		||||
		maxreq = 128 * 1024;
 | 
			
		||||
	else
 | 
			
		||||
		maxreq = 32 * 1024;
 | 
			
		||||
 | 
			
		||||
	s->block = SANE_TRUE;
 | 
			
		||||
	s->lcount = maxreq / s->params.bytes_per_line;
 | 
			
		||||
 | 
			
		||||
	DBG(1, "max req size: %d\n", maxreq);
 | 
			
		||||
 | 
			
		||||
	if (s->lcount < 3 && e2_model(s, "GT-X800")) {
 | 
			
		||||
		s->lcount = 21;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
extern int sanei_scsi_max_request_size;
 | 
			
		||||
extern int *gamma_params;
 | 
			
		||||
 | 
			
		||||
extern void e2_dev_init(Epson_Device *dev);
 | 
			
		||||
extern void e2_dev_init(Epson_Device *dev, const char *devname, int conntype);
 | 
			
		||||
extern SANE_Bool e2_model(Epson_Scanner *s, const char *model);
 | 
			
		||||
extern void e2_set_cmd_level(SANE_Handle handle, unsigned char *level);
 | 
			
		||||
extern SANE_Status e2_set_model(Epson_Scanner *s, unsigned char *model, size_t len);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										573
									
								
								backend/epson2.c
								
								
								
								
							
							
						
						
									
										573
									
								
								backend/epson2.c
								
								
								
								
							| 
						 | 
				
			
			@ -24,9 +24,10 @@
 | 
			
		|||
 *     127	e2_recv buffer
 | 
			
		||||
 *     125	e2_send buffer
 | 
			
		||||
 *	24	network header
 | 
			
		||||
 *	23	network info
 | 
			
		||||
 *	20	usb cmd counters
 | 
			
		||||
 *	18	sane_read
 | 
			
		||||
 *	17	setvalue
 | 
			
		||||
 *	17	setvalue, getvalue, control_option
 | 
			
		||||
 *	15	e2_send, e2_recv calls
 | 
			
		||||
 *	13	e2_cmd_info_block
 | 
			
		||||
 *	12	epson_cmd_simple
 | 
			
		||||
| 
						 | 
				
			
			@ -357,7 +358,6 @@ close_scanner(Epson_Scanner *s)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	s->fd = -1;
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -419,7 +419,7 @@ open_scanner(Epson_Scanner *s)
 | 
			
		|||
{
 | 
			
		||||
	SANE_Status status = 0;
 | 
			
		||||
 | 
			
		||||
	DBG(7, "%s\n", __func__);
 | 
			
		||||
	DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
 | 
			
		||||
 | 
			
		||||
	if (s->fd != -1) {
 | 
			
		||||
		DBG(5, "scanner is already open: fd = %d\n", s->fd);
 | 
			
		||||
| 
						 | 
				
			
			@ -430,18 +430,20 @@ open_scanner(Epson_Scanner *s)
 | 
			
		|||
		unsigned char buf[5];
 | 
			
		||||
 | 
			
		||||
		/* Sleep a bit or the network scanner will not be ready */
 | 
			
		||||
		sleep(1);
 | 
			
		||||
		sleep(2);
 | 
			
		||||
 | 
			
		||||
		status = sanei_tcp_open(s->hw->sane.name, 1865, &s->fd);
 | 
			
		||||
		if (status != SANE_STATUS_GOOD)
 | 
			
		||||
			goto end;
 | 
			
		||||
		if (status == SANE_STATUS_GOOD) {
 | 
			
		||||
 | 
			
		||||
		s->netlen = 0;
 | 
			
		||||
		/* the scanner sends a kind of welcome msg */
 | 
			
		||||
		e2_recv(s, buf, 5, &status);
 | 
			
		||||
			s->netlen = 0;
 | 
			
		||||
 | 
			
		||||
		/* lock the scanner for use by sane */
 | 
			
		||||
		sanei_epson_net_lock(s);
 | 
			
		||||
			/* the scanner sends a kind of welcome msg */
 | 
			
		||||
			e2_recv(s, buf, 5, &status);
 | 
			
		||||
 | 
			
		||||
			/* lock the scanner for use by sane */
 | 
			
		||||
			sanei_epson_net_lock(s);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	} else if (s->hw->connection == SANE_EPSON_SCSI)
 | 
			
		||||
		status = sanei_scsi_open(s->hw->sane.name, &s->fd,
 | 
			
		||||
					 sanei_epson2_scsi_sense_handler,
 | 
			
		||||
| 
						 | 
				
			
			@ -451,19 +453,140 @@ open_scanner(Epson_Scanner *s)
 | 
			
		|||
	else if (s->hw->connection == SANE_EPSON_USB)
 | 
			
		||||
		status = sanei_usb_open(s->hw->sane.name, &s->fd);
 | 
			
		||||
 | 
			
		||||
end:
 | 
			
		||||
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		DBG(1, "%s open failed: %s\n", s->hw->sane.name,
 | 
			
		||||
		    sane_strstatus(status));
 | 
			
		||||
 | 
			
		||||
	if (status == SANE_STATUS_ACCESS_DENIED) {
 | 
			
		||||
		DBG(1, "please check that you have permissions on the device.\n");
 | 
			
		||||
		DBG(1, "if this is a multi-function device with a printer,\n");
 | 
			
		||||
		DBG(1, "disable any conflicting driver (like usblp).\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SANE_Status detect_scsi(struct Epson_Scanner *s)
 | 
			
		||||
{
 | 
			
		||||
	SANE_Status status;
 | 
			
		||||
	struct Epson_Device *dev = s->hw;
 | 
			
		||||
 | 
			
		||||
static int num_devices = 0;	/* number of scanners attached to backend */
 | 
			
		||||
static Epson_Device *first_dev = NULL;	/* first EPSON scanner in list */
 | 
			
		||||
static Epson_Scanner *first_handle = NULL;
 | 
			
		||||
	char buf[INQUIRY_BUF_SIZE + 1];
 | 
			
		||||
	size_t buf_size = INQUIRY_BUF_SIZE;
 | 
			
		||||
 | 
			
		||||
	char *vendor = buf + 8;
 | 
			
		||||
	char *model = buf + 16;
 | 
			
		||||
	char *rev = buf + 32;
 | 
			
		||||
 | 
			
		||||
	status = sanei_epson2_scsi_inquiry(s->fd, buf, &buf_size);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
		DBG(1, "%s: inquiry failed: %s\n", __func__,
 | 
			
		||||
		    sane_strstatus(status));
 | 
			
		||||
		return status;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buf[INQUIRY_BUF_SIZE] = 0;
 | 
			
		||||
	DBG(1, "inquiry data:\n");
 | 
			
		||||
	DBG(1, " vendor  : %.8s\n", vendor);
 | 
			
		||||
	DBG(1, " model   : %.16s\n", model);
 | 
			
		||||
	DBG(1, " revision: %.4s\n", rev);
 | 
			
		||||
 | 
			
		||||
	if (buf[0] != TYPE_PROCESSOR) {
 | 
			
		||||
		DBG(1, "%s: device is not of processor type (%d)\n",
 | 
			
		||||
		    __func__, buf[0]);
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strncmp(vendor, "EPSON", 5) != 0) {
 | 
			
		||||
		DBG(1,
 | 
			
		||||
		    "%s: device doesn't look like an EPSON scanner\n",
 | 
			
		||||
		    __func__);
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strncmp(model, "SCANNER ", 8) != 0
 | 
			
		||||
	    && strncmp(model, "FilmScan 200", 12) != 0
 | 
			
		||||
	    && strncmp(model, "Perfection", 10) != 0
 | 
			
		||||
	    && strncmp(model, "Expression", 10) != 0
 | 
			
		||||
	    && strncmp(model, "GT", 2) != 0) {
 | 
			
		||||
		DBG(1, "%s: this EPSON scanner is not supported\n",
 | 
			
		||||
		    __func__);
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strncmp(model, "FilmScan 200", 12) == 0) {
 | 
			
		||||
		dev->sane.type = "film scanner";
 | 
			
		||||
		e2_set_model(s, (unsigned char *) model, 12);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Issue a test unit ready SCSI command. The FilmScan 200
 | 
			
		||||
	 * requires it for a sort of "wake up". We might eventually
 | 
			
		||||
	 * get the return code and reissue it in case of failure.
 | 
			
		||||
	 */
 | 
			
		||||
	sanei_epson2_scsi_test_unit_ready(s->fd);
 | 
			
		||||
 | 
			
		||||
	return SANE_STATUS_GOOD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SANE_Status
 | 
			
		||||
detect_usb(struct Epson_Scanner *s)
 | 
			
		||||
{
 | 
			
		||||
	SANE_Status status;
 | 
			
		||||
	int vendor, product;
 | 
			
		||||
	int i, numIds;
 | 
			
		||||
	SANE_Bool is_valid;
 | 
			
		||||
 | 
			
		||||
	/* if the sanei_usb_get_vendor_product call is not supported,
 | 
			
		||||
	 * then we just ignore this and rely on the user to config
 | 
			
		||||
	 * the correct device.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	status = sanei_usb_get_vendor_product(s->fd, &vendor, &product);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
		DBG(1,
 | 
			
		||||
		    "cannot use IOCTL interface to verify that device is a scanner - will continue\n");
 | 
			
		||||
	 	return SANE_STATUS_GOOD;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* check the vendor ID to see if we are dealing with an EPSON device */
 | 
			
		||||
	if (vendor != SANE_EPSON_VENDOR_ID) {
 | 
			
		||||
		/* this is not a supported vendor ID */
 | 
			
		||||
		DBG(1,
 | 
			
		||||
		    "the device at %s is not manufactured by EPSON (vendor id=0x%x)\n",
 | 
			
		||||
		    s->hw->sane.name, vendor);
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	numIds = sanei_epson_getNumberOfUSBProductIds();
 | 
			
		||||
	is_valid = SANE_FALSE;
 | 
			
		||||
	i = 0;
 | 
			
		||||
 | 
			
		||||
	/* check all known product IDs to verify that we know
 | 
			
		||||
	   about the device */
 | 
			
		||||
	while (i != numIds && !is_valid) {
 | 
			
		||||
		if (product == sanei_epson_usb_product_ids[i])
 | 
			
		||||
			is_valid = SANE_TRUE;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (is_valid == SANE_FALSE) {
 | 
			
		||||
		DBG(1,
 | 
			
		||||
		    "the device at %s is not a supported EPSON scanner (product id=0x%x)\n",
 | 
			
		||||
		    s->hw->sane.name, product);
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	DBG(1,
 | 
			
		||||
	    "found valid EPSON scanner: 0x%x/0x%x (vendorID/productID)\n",
 | 
			
		||||
	    vendor, product);
 | 
			
		||||
 | 
			
		||||
	return SANE_STATUS_GOOD;	    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int num_devices;		/* number of scanners attached to backend */
 | 
			
		||||
static Epson_Device *first_dev;	/* first EPSON scanner in list */
 | 
			
		||||
 | 
			
		||||
/* attach device to backend */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -475,9 +598,6 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	struct Epson_Device *dev;
 | 
			
		||||
	int port;
 | 
			
		||||
 | 
			
		||||
	DBG(1, "epson2 backend, version %i.%i.%i\n",
 | 
			
		||||
		EPSON2_VERSION, EPSON2_REVISION, EPSON2_BUILD);
 | 
			
		||||
 | 
			
		||||
	DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
 | 
			
		||||
 | 
			
		||||
	for (dev = first_dev; dev; dev = dev->next) {
 | 
			
		||||
| 
						 | 
				
			
			@ -489,7 +609,6 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* alloc and clear our device structure */
 | 
			
		||||
	dev = malloc(sizeof(*dev));
 | 
			
		||||
	if (!dev) {
 | 
			
		||||
| 
						 | 
				
			
			@ -516,9 +635,6 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
		type = SANE_EPSON_PIO;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->connection = type;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	s = malloc(sizeof(struct Epson_Scanner));
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		return SANE_STATUS_NO_MEM;
 | 
			
		||||
| 
						 | 
				
			
			@ -528,181 +644,30 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	s->fd = -1;
 | 
			
		||||
	s->hw = dev;
 | 
			
		||||
 | 
			
		||||
	e2_dev_init(dev);
 | 
			
		||||
	e2_dev_init(dev, name, type);
 | 
			
		||||
 | 
			
		||||
	if (dev->connection == SANE_EPSON_NET) {
 | 
			
		||||
		unsigned char buf[5];
 | 
			
		||||
 | 
			
		||||
		if (strncmp(name, "autodiscovery", 13) == 0) {
 | 
			
		||||
			e2_network_discovery();
 | 
			
		||||
			status = SANE_STATUS_INVAL;
 | 
			
		||||
			goto free;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		status = sanei_tcp_open(name, 1865, &s->fd);
 | 
			
		||||
		if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
			DBG(1, "%s: %s open failed: %s\n", __func__,
 | 
			
		||||
			    name, sane_strstatus(status));
 | 
			
		||||
			goto free;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s->netlen = 0;
 | 
			
		||||
 | 
			
		||||
		/* the scanner sends a kind of welcome msg */
 | 
			
		||||
		/* XXX use a shorter timeout here */
 | 
			
		||||
		e2_recv(s, buf, 5, &status);
 | 
			
		||||
 | 
			
		||||
		/* lock the scanner for use by sane */
 | 
			
		||||
		sanei_epson_net_lock(s);
 | 
			
		||||
 | 
			
		||||
	} else if (dev->connection == SANE_EPSON_SCSI) {
 | 
			
		||||
		char buf[INQUIRY_BUF_SIZE + 1];
 | 
			
		||||
		size_t buf_size = INQUIRY_BUF_SIZE;
 | 
			
		||||
 | 
			
		||||
		char *vendor = buf + 8;
 | 
			
		||||
		char *model = buf + 16;
 | 
			
		||||
		char *rev = buf + 32;
 | 
			
		||||
 | 
			
		||||
		status = sanei_scsi_open(name, &s->fd,
 | 
			
		||||
					 sanei_epson2_scsi_sense_handler,
 | 
			
		||||
					 NULL);
 | 
			
		||||
		if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
			DBG(1, "%s: open failed: %s\n", __func__,
 | 
			
		||||
			    sane_strstatus(status));
 | 
			
		||||
			goto free;
 | 
			
		||||
		}
 | 
			
		||||
		status = sanei_epson2_scsi_inquiry(s->fd, buf, &buf_size);
 | 
			
		||||
		if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
			DBG(1, "%s: inquiry failed: %s\n", __func__,
 | 
			
		||||
			    sane_strstatus(status));
 | 
			
		||||
			goto free;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		buf[INQUIRY_BUF_SIZE] = 0;
 | 
			
		||||
		DBG(1, "inquiry data:\n");
 | 
			
		||||
		DBG(1, " vendor  : %.8s\n", vendor);
 | 
			
		||||
		DBG(1, " model   : %.16s\n", model);
 | 
			
		||||
		DBG(1, " revision: %.4s\n", rev);
 | 
			
		||||
 | 
			
		||||
		if (buf[0] != TYPE_PROCESSOR) {
 | 
			
		||||
			DBG(1, "%s: device is not of processor type (%d)\n",
 | 
			
		||||
			    __func__, buf[0]);
 | 
			
		||||
			return SANE_STATUS_INVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strncmp(vendor, "EPSON", 5) != 0) {
 | 
			
		||||
			DBG(1,
 | 
			
		||||
			    "%s: device doesn't look like an EPSON scanner\n",
 | 
			
		||||
			    __func__);
 | 
			
		||||
			close_scanner(s);
 | 
			
		||||
			return SANE_STATUS_INVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strncmp(model, "SCANNER ", 8) != 0
 | 
			
		||||
		    && strncmp(model, "FilmScan 200", 12) != 0
 | 
			
		||||
		    && strncmp(model, "Perfection", 10) != 0
 | 
			
		||||
		    && strncmp(model, "Expression", 10) != 0
 | 
			
		||||
		    && strncmp(model, "GT", 2) != 0) {
 | 
			
		||||
			DBG(1, "%s: this EPSON scanner is not supported\n",
 | 
			
		||||
			    __func__);
 | 
			
		||||
			close_scanner(s);
 | 
			
		||||
			return SANE_STATUS_INVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strncmp(model, "FilmScan 200", 12) == 0) {
 | 
			
		||||
			dev->sane.type = "film scanner";
 | 
			
		||||
			e2_set_model(s, (unsigned char *) model, 12);
 | 
			
		||||
		}
 | 
			
		||||
	status = open_scanner(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
		free(s);
 | 
			
		||||
		return status;
 | 
			
		||||
	}
 | 
			
		||||
	/* use the SANEI functions to handle a PIO device */
 | 
			
		||||
	else if (dev->connection == SANE_EPSON_PIO) {
 | 
			
		||||
		if (SANE_STATUS_GOOD !=
 | 
			
		||||
		    (status = sanei_pio_open(name, &s->fd))) {
 | 
			
		||||
			DBG(1,
 | 
			
		||||
			    "cannot open %s as a parallel-port device: %s\n",
 | 
			
		||||
			    name, sane_strstatus(status));
 | 
			
		||||
			goto free;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	/* from now on, close_scanner() must be called */
 | 
			
		||||
 | 
			
		||||
	/* SCSI and USB requires special care */
 | 
			
		||||
	if (dev->connection == SANE_EPSON_SCSI) {
 | 
			
		||||
 | 
			
		||||
		status = detect_scsi(s);
 | 
			
		||||
 | 
			
		||||
	} else if (dev->connection == SANE_EPSON_USB) {
 | 
			
		||||
 | 
			
		||||
		status = detect_usb(s);
 | 
			
		||||
	}
 | 
			
		||||
	/* use the SANEI functions to handle a USB device */
 | 
			
		||||
	else if (dev->connection == SANE_EPSON_USB) {
 | 
			
		||||
		SANE_Word vendor;
 | 
			
		||||
		SANE_Word product;
 | 
			
		||||
		SANE_Bool isLibUSB;
 | 
			
		||||
 | 
			
		||||
		isLibUSB = (strncmp(name, "libusb:", strlen("libusb:")) == 0);
 | 
			
		||||
 | 
			
		||||
		if ((!isLibUSB) && (strlen(name) == 0)) {
 | 
			
		||||
			int i;
 | 
			
		||||
			int numIds;
 | 
			
		||||
 | 
			
		||||
			numIds = sanei_epson_getNumberOfUSBProductIds();
 | 
			
		||||
 | 
			
		||||
			for (i = 0; i < numIds; i++) {
 | 
			
		||||
				product = sanei_epson_usb_product_ids[i];
 | 
			
		||||
				vendor = 0x4b8;
 | 
			
		||||
 | 
			
		||||
				status = sanei_usb_find_devices(vendor,
 | 
			
		||||
								product,
 | 
			
		||||
								attach_one_usb);
 | 
			
		||||
			}
 | 
			
		||||
			return SANE_STATUS_INVAL;	/* return - the attach_one_usb()
 | 
			
		||||
							   will take care of this */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		status = sanei_usb_open(name, &s->fd);
 | 
			
		||||
 | 
			
		||||
		if (status != SANE_STATUS_GOOD)
 | 
			
		||||
			goto free;
 | 
			
		||||
 | 
			
		||||
		/* if the sanei_usb_get_vendor_product call is not supported,
 | 
			
		||||
		   then we just ignore this and rely on the user to config
 | 
			
		||||
		   the correct device.
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		if (sanei_usb_get_vendor_product(s->fd, &vendor, &product) ==
 | 
			
		||||
		    SANE_STATUS_GOOD) {
 | 
			
		||||
			int i;	/* loop variable */
 | 
			
		||||
			int numIds;
 | 
			
		||||
			SANE_Bool is_valid;
 | 
			
		||||
 | 
			
		||||
			/* check the vendor ID to see if we are dealing with an EPSON device */
 | 
			
		||||
			if (vendor != SANE_EPSON_VENDOR_ID) {
 | 
			
		||||
				/* this is not a supported vendor ID */
 | 
			
		||||
				DBG(1,
 | 
			
		||||
				    "the device at %s is not manufactured by EPSON (vendor id=0x%x)\n",
 | 
			
		||||
				    name, vendor);
 | 
			
		||||
				sanei_usb_close(s->fd);
 | 
			
		||||
				s->fd = -1;
 | 
			
		||||
				return SANE_STATUS_INVAL;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			numIds = sanei_epson_getNumberOfUSBProductIds();
 | 
			
		||||
			is_valid = SANE_FALSE;
 | 
			
		||||
			i = 0;
 | 
			
		||||
 | 
			
		||||
			/* check all known product IDs to verify that we know
 | 
			
		||||
			   about the device */
 | 
			
		||||
			while (i != numIds && !is_valid) {
 | 
			
		||||
				if (product == sanei_epson_usb_product_ids[i])
 | 
			
		||||
					is_valid = SANE_TRUE;
 | 
			
		||||
				i++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (is_valid == SANE_FALSE) {
 | 
			
		||||
				DBG(1,
 | 
			
		||||
				    "the device at %s is not a supported EPSON scanner (product id=0x%x)\n",
 | 
			
		||||
				    name, product);
 | 
			
		||||
				sanei_usb_close(s->fd);
 | 
			
		||||
				s->fd = -1;
 | 
			
		||||
				return SANE_STATUS_INVAL;
 | 
			
		||||
			}
 | 
			
		||||
			DBG(1,
 | 
			
		||||
			    "found valid EPSON scanner: 0x%x/0x%x (vendorID/productID)\n",
 | 
			
		||||
			    vendor, product);
 | 
			
		||||
		} else
 | 
			
		||||
			DBG(1,
 | 
			
		||||
			    "cannot use IOCTL interface to verify that device is a scanner - will continue\n");
 | 
			
		||||
	if (status != SANE_STATUS_GOOD) {
 | 
			
		||||
		close_scanner(s);
 | 
			
		||||
		free(s);
 | 
			
		||||
		return status;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* set name and model (if not already set) */
 | 
			
		||||
| 
						 | 
				
			
			@ -712,21 +677,21 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	dev->name = strdup(name);
 | 
			
		||||
	dev->sane.name = dev->name;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Issue a test unit ready SCSI command. The FilmScan 200
 | 
			
		||||
	 * requires it for a sort of "wake up". We might eventually
 | 
			
		||||
	 * get the return code and reissue it in case of failure.
 | 
			
		||||
	 */
 | 
			
		||||
	if (dev->connection == SANE_EPSON_SCSI)
 | 
			
		||||
		sanei_epson2_scsi_test_unit_ready(s->fd);
 | 
			
		||||
 | 
			
		||||
	/* ESC @, reset */
 | 
			
		||||
	esci_reset(s);
 | 
			
		||||
	status = esci_reset(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		goto free;
 | 
			
		||||
 | 
			
		||||
	status = e2_discover_capabilities(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		goto free;
 | 
			
		||||
 | 
			
		||||
	if (source_list[0] == NULL || dev->dpi_range.min == 0) {
 | 
			
		||||
		DBG(1, "something is wrong in the discovery process, aborting.\n");
 | 
			
		||||
		status = SANE_STATUS_IO_ERROR;
 | 
			
		||||
		goto free;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If we have been unable to obtain supported resolutions
 | 
			
		||||
	 * due to the fact we are on the network transport,
 | 
			
		||||
	 * add some convenient ones
 | 
			
		||||
| 
						 | 
				
			
			@ -771,8 +736,9 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	memcpy(&(dev->resolution_list[1]), dev->res_list,
 | 
			
		||||
	       dev->res_list_size * sizeof(SANE_Word));
 | 
			
		||||
 | 
			
		||||
	/* XXX necessary? */
 | 
			
		||||
	esci_reset(s);
 | 
			
		||||
	status = esci_reset(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		goto free;
 | 
			
		||||
 | 
			
		||||
	DBG(1, "scanner model: %s\n", dev->model);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -792,6 +758,7 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/* we are done with this one, prepare for the next scanner */
 | 
			
		||||
 | 
			
		||||
	num_devices++;
 | 
			
		||||
	dev->next = first_dev;
 | 
			
		||||
	first_dev = dev;
 | 
			
		||||
| 
						 | 
				
			
			@ -799,7 +766,7 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
	if (devp)
 | 
			
		||||
		*devp = dev;
 | 
			
		||||
 | 
			
		||||
      free:
 | 
			
		||||
free:
 | 
			
		||||
      	close_scanner(s);
 | 
			
		||||
	free(s);
 | 
			
		||||
	return status;
 | 
			
		||||
| 
						 | 
				
			
			@ -810,7 +777,7 @@ attach(const char *name, Epson_Device **devp, int type)
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
static SANE_Status
 | 
			
		||||
attach_one(const char *dev)
 | 
			
		||||
attach_one_scsi(const char *dev)
 | 
			
		||||
{
 | 
			
		||||
	DBG(7, "%s: dev = %s\n", __func__, dev);
 | 
			
		||||
	return attach(dev, 0, SANE_EPSON_SCSI);
 | 
			
		||||
| 
						 | 
				
			
			@ -830,88 +797,62 @@ attach_one_net(const char *dev)
 | 
			
		|||
	return attach(dev, 0, SANE_EPSON_NET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SANE_Status
 | 
			
		||||
sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize)
 | 
			
		||||
static SANE_Status
 | 
			
		||||
attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
 | 
			
		||||
{
 | 
			
		||||
	size_t len;
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	int vendor, product;
 | 
			
		||||
 | 
			
		||||
	authorize = authorize;	/* get rid of compiler warning */
 | 
			
		||||
	int len = strlen(line);
 | 
			
		||||
 | 
			
		||||
	/* sanei_authorization(devicename, STRINGIFY(BACKEND_NAME), auth_callback); */
 | 
			
		||||
	DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
 | 
			
		||||
	
 | 
			
		||||
	if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
 | 
			
		||||
		/* add the vendor and product IDs to the list of
 | 
			
		||||
		   known devices before we call the attach function */
 | 
			
		||||
 | 
			
		||||
	DBG_INIT();
 | 
			
		||||
	DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
 | 
			
		||||
		int numIds = sanei_epson_getNumberOfUSBProductIds();
 | 
			
		||||
 | 
			
		||||
	if (version_code != NULL)
 | 
			
		||||
		*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR,
 | 
			
		||||
					  EPSON2_BUILD);
 | 
			
		||||
		if (vendor != 0x4b8)
 | 
			
		||||
			return SANE_STATUS_INVAL; /* this is not an EPSON device */
 | 
			
		||||
 | 
			
		||||
	sanei_usb_init();
 | 
			
		||||
		sanei_epson_usb_product_ids[numIds - 1] = product;
 | 
			
		||||
		sanei_usb_attach_matching_devices(line, attach_one_usb);
 | 
			
		||||
 | 
			
		||||
	if ((fp = sanei_config_open(EPSON2_CONFIG_FILE))) {
 | 
			
		||||
		char line[PATH_MAX];
 | 
			
		||||
	} else if (strncmp(line, "usb", 3) == 0 && len == 3) {
 | 
			
		||||
 | 
			
		||||
		DBG(3, "%s: reading config file, %s\n", __func__,
 | 
			
		||||
		    EPSON2_CONFIG_FILE);
 | 
			
		||||
		int i, numIds;
 | 
			
		||||
 | 
			
		||||
		while (sanei_config_read(line, sizeof(line), fp)) {
 | 
			
		||||
			int vendor, product;
 | 
			
		||||
		numIds = sanei_epson_getNumberOfUSBProductIds();
 | 
			
		||||
 | 
			
		||||
			if (line[0] == '#')	/* ignore line comments */
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			len = strlen(line);
 | 
			
		||||
			if (len == 0)
 | 
			
		||||
				continue;	/* ignore empty lines */
 | 
			
		||||
 | 
			
		||||
			DBG(120, " %s\n", line);
 | 
			
		||||
 | 
			
		||||
			if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
 | 
			
		||||
				int numIds;
 | 
			
		||||
 | 
			
		||||
				/* add the vendor and product IDs to the list of
 | 
			
		||||
				   known devices before we call the attach function */
 | 
			
		||||
				numIds = sanei_epson_getNumberOfUSBProductIds
 | 
			
		||||
					();
 | 
			
		||||
				if (vendor != 0x4b8)
 | 
			
		||||
					continue;	/* this is not an EPSON device */
 | 
			
		||||
 | 
			
		||||
				sanei_epson_usb_product_ids[numIds - 1] =
 | 
			
		||||
					product;
 | 
			
		||||
				sanei_usb_attach_matching_devices(line,
 | 
			
		||||
								  attach_one_usb);
 | 
			
		||||
			} else if (strncmp(line, "usb", 3) == 0) {
 | 
			
		||||
				const char *name;
 | 
			
		||||
				/* remove the "usb" sub string */
 | 
			
		||||
				name = sanei_config_skip_whitespace(line + 3);
 | 
			
		||||
				attach_one_usb(name);
 | 
			
		||||
			} else if (strncmp(line, "net", 3) == 0) {
 | 
			
		||||
				const char *name;
 | 
			
		||||
				/* remove the "net" sub string */
 | 
			
		||||
				name = sanei_config_skip_whitespace(line + 3);
 | 
			
		||||
				attach_one_net(name);
 | 
			
		||||
			} else {
 | 
			
		||||
				sanei_config_attach_matching_devices(line,
 | 
			
		||||
								     attach_one);
 | 
			
		||||
			}
 | 
			
		||||
		for (i = 0; i < numIds; i++) {
 | 
			
		||||
			sanei_usb_find_devices(0x4b8,
 | 
			
		||||
					sanei_epson_usb_product_ids[i], attach_one_usb);
 | 
			
		||||
		}
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* read the option section and assign the connection type to the
 | 
			
		||||
	   scanner structure - which we don't have at this time. So I have
 | 
			
		||||
	   to come up with something :-) */
 | 
			
		||||
	} else if (strncmp(line, "net", 3) == 0) {
 | 
			
		||||
 | 
			
		||||
		/* remove the "net" sub string */
 | 
			
		||||
		const char *name = sanei_config_skip_whitespace(line + 3);
 | 
			
		||||
 | 
			
		||||
		if (strncmp(name, "autodiscovery", 13) == 0)
 | 
			
		||||
			e2_network_discovery();
 | 
			
		||||
		else
 | 
			
		||||
			attach_one_net(name);
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
		sanei_config_attach_matching_devices(line, attach_one_scsi);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return SANE_STATUS_GOOD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clean up the list of attached scanners. */
 | 
			
		||||
void
 | 
			
		||||
sane_exit(void)
 | 
			
		||||
static void
 | 
			
		||||
free_devices(void)
 | 
			
		||||
{
 | 
			
		||||
	Epson_Device *dev, *next;
 | 
			
		||||
 | 
			
		||||
	DBG(5, "%s\n", __func__);
 | 
			
		||||
 | 
			
		||||
	for (dev = first_dev; dev; dev = next) {
 | 
			
		||||
		next = dev->next;
 | 
			
		||||
		free(dev->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -920,20 +861,56 @@ sane_exit(void)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	free(devlist);
 | 
			
		||||
 | 
			
		||||
	first_dev = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
probe_devices(void)
 | 
			
		||||
{
 | 
			
		||||
	DBG(5, "%s\n", __func__);
 | 
			
		||||
 | 
			
		||||
	free_devices();
 | 
			
		||||
 | 
			
		||||
	sanei_configure_attach(EPSON2_CONFIG_FILE, NULL,
 | 
			
		||||
		attach_one_config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SANE_Status
 | 
			
		||||
sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
 | 
			
		||||
sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
 | 
			
		||||
{
 | 
			
		||||
	DBG_INIT();
 | 
			
		||||
	DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
 | 
			
		||||
 | 
			
		||||
	DBG(1, "epson2 backend, version %i.%i.%i\n",
 | 
			
		||||
		EPSON2_VERSION, EPSON2_REVISION, EPSON2_BUILD);
 | 
			
		||||
 | 
			
		||||
	if (version_code != NULL)
 | 
			
		||||
		*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR,
 | 
			
		||||
					  EPSON2_BUILD);
 | 
			
		||||
 | 
			
		||||
	sanei_usb_init();
 | 
			
		||||
 | 
			
		||||
	return SANE_STATUS_GOOD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clean up the list of attached scanners. */
 | 
			
		||||
void
 | 
			
		||||
sane_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	DBG(5, "%s\n", __func__);
 | 
			
		||||
	free_devices();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SANE_Status
 | 
			
		||||
sane_get_devices(const SANE_Device ***device_list, SANE_Bool __sane_unused__ local_only)
 | 
			
		||||
{
 | 
			
		||||
	Epson_Device *dev;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	DBG(5, "%s\n", __func__);
 | 
			
		||||
 | 
			
		||||
	local_only = local_only;	/* just to get rid of the compailer warning */
 | 
			
		||||
 | 
			
		||||
	if (devlist)
 | 
			
		||||
		free(devlist);
 | 
			
		||||
	probe_devices();
 | 
			
		||||
 | 
			
		||||
	devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
 | 
			
		||||
	if (!devlist) {
 | 
			
		||||
| 
						 | 
				
			
			@ -941,8 +918,10 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
 | 
			
		|||
		return SANE_STATUS_NO_MEM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DBG(5, "%s - results:\n", __func__);
 | 
			
		||||
 | 
			
		||||
	for (i = 0, dev = first_dev; i < num_devices; dev = dev->next, i++) {
 | 
			
		||||
		DBG(1, " %d: %s\n", i, dev->model);
 | 
			
		||||
		DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
 | 
			
		||||
		devlist[i] = &dev->sane;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1559,6 +1538,10 @@ sane_open(SANE_String_Const name, SANE_Handle *handle)
 | 
			
		|||
 | 
			
		||||
	DBG(7, "%s: name = %s\n", __func__, name);
 | 
			
		||||
 | 
			
		||||
	/* do a scan if the devices list is empty */
 | 
			
		||||
	if (first_dev == NULL)
 | 
			
		||||
		probe_devices();
 | 
			
		||||
 | 
			
		||||
	/* search for device */
 | 
			
		||||
	if (name[0]) {
 | 
			
		||||
		for (dev = first_dev; dev; dev = dev->next)
 | 
			
		||||
| 
						 | 
				
			
			@ -1572,28 +1555,28 @@ sane_open(SANE_String_Const name, SANE_Handle *handle)
 | 
			
		|||
		return SANE_STATUS_INVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s = calloc(sizeof(Epson_Scanner), 1);
 | 
			
		||||
	s = malloc(sizeof(Epson_Scanner));
 | 
			
		||||
	if (!s) {
 | 
			
		||||
		DBG(1, "out of memory (line %d)\n", __LINE__);
 | 
			
		||||
		return SANE_STATUS_NO_MEM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memset(s, 0x00, sizeof(struct Epson_Scanner));
 | 
			
		||||
 | 
			
		||||
	s->fd = -1;
 | 
			
		||||
	s->hw = dev;
 | 
			
		||||
 | 
			
		||||
	init_options(s);
 | 
			
		||||
 | 
			
		||||
	/* insert newly opened handle into list of open handles */
 | 
			
		||||
	s->next = first_handle;
 | 
			
		||||
	first_handle = s;
 | 
			
		||||
 | 
			
		||||
	*handle = (SANE_Handle) s;
 | 
			
		||||
 | 
			
		||||
	status = open_scanner(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		return status;
 | 
			
		||||
 | 
			
		||||
	esci_reset(s);
 | 
			
		||||
	status = esci_reset(s);
 | 
			
		||||
	if (status != SANE_STATUS_GOOD)
 | 
			
		||||
		return status;
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1602,7 +1585,7 @@ void
 | 
			
		|||
sane_close(SANE_Handle handle)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	Epson_Scanner *s, *prev;
 | 
			
		||||
	Epson_Scanner *s;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * XXX Test if there is still data pending from
 | 
			
		||||
| 
						 | 
				
			
			@ -1611,24 +1594,6 @@ sane_close(SANE_Handle handle)
 | 
			
		|||
 | 
			
		||||
	s = (Epson_Scanner *) handle;
 | 
			
		||||
 | 
			
		||||
	/* remove handle from list of open handles */
 | 
			
		||||
	prev = 0;
 | 
			
		||||
	for (s = first_handle; s; s = s->next) {
 | 
			
		||||
		if (s == handle)
 | 
			
		||||
			break;
 | 
			
		||||
		prev = s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!s) {
 | 
			
		||||
		DBG(1, "%s: invalid handle (0x%p)\n", __func__, handle);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (prev)
 | 
			
		||||
		prev->next = s->next;
 | 
			
		||||
	else
 | 
			
		||||
		first_handle = s->next;
 | 
			
		||||
 | 
			
		||||
	if (s->fd != -1)
 | 
			
		||||
		close_scanner(s);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1702,6 +1667,8 @@ getvalue(SANE_Handle handle, SANE_Int option, void *value)
 | 
			
		|||
	SANE_Option_Descriptor *sopt = &(s->opt[option]);
 | 
			
		||||
	Option_Value *sval = &(s->val[option]);
 | 
			
		||||
 | 
			
		||||
	DBG(17, "%s: option = %d\n", __func__, option);
 | 
			
		||||
 | 
			
		||||
	switch (option) {
 | 
			
		||||
 | 
			
		||||
/* 	case OPT_GAMMA_VECTOR: */
 | 
			
		||||
| 
						 | 
				
			
			@ -2143,6 +2110,8 @@ SANE_Status
 | 
			
		|||
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
 | 
			
		||||
		    void *value, SANE_Int *info)
 | 
			
		||||
{
 | 
			
		||||
	DBG(17, "%s: action = %x, option = %d\n", __func__, action, option);
 | 
			
		||||
 | 
			
		||||
	if (option < 0 || option >= NUM_OPTIONS)
 | 
			
		||||
		return SANE_STATUS_INVAL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2486,7 +2455,7 @@ sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length,
 | 
			
		|||
	else
 | 
			
		||||
		status = e2_block_sane_read(handle);
 | 
			
		||||
 | 
			
		||||
	DBG(18, "moving data\n");
 | 
			
		||||
	DBG(18, "moving data %d %p %p\n", max_length, s->ptr, s->end);
 | 
			
		||||
	e2_copy_image_data(s, data, max_length, length);
 | 
			
		||||
 | 
			
		||||
	/* continue reading if appropriate */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
 | 
			
		|||
 | 
			
		||||
	/* read from buffer, if available */
 | 
			
		||||
	if (s->netptr != s->netbuf) {
 | 
			
		||||
		DBG(15, "reading %lu from buffer at %p, %lu available\n",
 | 
			
		||||
		DBG(23, "reading %lu from buffer at %p, %lu available\n",
 | 
			
		||||
			(u_long) wanted, s->netptr, (u_long) s->netlen);
 | 
			
		||||
 | 
			
		||||
		memcpy(buf, s->netptr, wanted);
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
 | 
			
		|||
		s->netlen -= wanted;
 | 
			
		||||
 | 
			
		||||
		if (s->netlen == 0) {
 | 
			
		||||
			DBG(15, "%s: freeing %p\n", __func__, s->netbuf);
 | 
			
		||||
			DBG(23, "%s: freeing %p\n", __func__, s->netbuf);
 | 
			
		||||
			free(s->netbuf);
 | 
			
		||||
			s->netbuf = s->netptr = NULL;
 | 
			
		||||
			s->netlen = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
 | 
			
		|||
 | 
			
		||||
	size = be32atoh(&header[6]);
 | 
			
		||||
 | 
			
		||||
	DBG(15, "%s: wanted = %lu, available = %lu\n", __FUNCTION__,
 | 
			
		||||
	DBG(23, "%s: wanted = %lu, available = %lu\n", __FUNCTION__,
 | 
			
		||||
		(u_long) wanted, (u_long) size);
 | 
			
		||||
 | 
			
		||||
	*status = SANE_STATUS_GOOD;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
 | 
			
		|||
		}
 | 
			
		||||
		
 | 
			
		||||
	} else if (wanted < size && s->netlen == size) {
 | 
			
		||||
		DBG(15, "%s: partial read\n", __func__);
 | 
			
		||||
		DBG(23, "%s: partial read\n", __func__);
 | 
			
		||||
 | 
			
		||||
		sanei_tcp_read(s->fd, s->netbuf, size);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,8 +114,8 @@ sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
 | 
			
		|||
		s->netptr += wanted;
 | 
			
		||||
		read = wanted;
 | 
			
		||||
 | 
			
		||||
		DBG(15, "0,4 %02x %02x\n", s->netbuf[0], s->netbuf[4]);
 | 
			
		||||
		DBG(15, "storing %lu to buffer at %p, next read at %p, %lu bytes left\n",
 | 
			
		||||
		DBG(23, "0,4 %02x %02x\n", s->netbuf[0], s->netbuf[4]);
 | 
			
		||||
		DBG(23, "storing %lu to buffer at %p, next read at %p, %lu bytes left\n",
 | 
			
		||||
			(u_long) size, s->netbuf, s->netptr, (u_long) s->netlen);
 | 
			
		||||
 | 
			
		||||
		memcpy(buf, s->netbuf, wanted);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue