Exemplo n.º 1
0
/* Sends a CDB to the scanner. Also sends the parameters and receives
 * the data, if necessary. When this function returns with a
 * SANE_STATUS_GOOD, the SCSI command has been completed. 
 *
 * Note: I don't know about deferred commands.
 */
static SANE_Status sanei_umaxusb_cmd(int fd, const void *src, size_t src_size, void *dst, size_t * dst_size)
{
	unsigned char result;
	size_t cmd_size = CDB_SIZE (*(const char *) src);
	size_t param_size = src_size - cmd_size;
	const char * param_ptr = ((const char *) src) + cmd_size;
	size_t tmp_len;
	
	DBG(DBG_info, "Sending SCSI cmd 0x%02x cdb len %ld, param len %ld, result len %ld\n", ((const unsigned char *)src)[0], (long)cmd_size, (long)param_size, dst_size? (long)*dst_size:(long)0);

	/* This looks like some kind of pre-initialization. */
	sanei_pv8630_write_byte(fd, PV8630_UNKNOWN, 0x0c);
	sanei_pv8630_wait_byte(fd, PV8630_RSTATUS, 0xf0, 0xff, 1000);
	sanei_pv8630_write_byte(fd, PV8630_UNKNOWN, 0x04);

	/* Send the CDB and check it's been received OK. */
	sanei_pv8630_write_byte(fd, PV8630_RMODE, 0x16);
	sanei_pv8630_flush_buffer(fd);
	sanei_pv8630_prep_bulkwrite(fd, cmd_size);
	
	tmp_len = cmd_size;
	sanei_pv8630_bulkwrite(fd, src, &tmp_len);
	sanei_pv8630_wait_byte(fd, PV8630_RSTATUS, 0xf8, 0xff, 1000);

	sanei_pv8630_flush_buffer(fd);
	sanei_pv8630_prep_bulkread(fd, 1);

	result = 0xA5;				/* to be sure */
	tmp_len = 1;
	sanei_pv8630_bulkread(fd, &result, &tmp_len);
	if (result != 0) {
		DBG(DBG_info, "error in sanei_pv8630_bulkread (got %02x)\n", result);
		if (result == 8) {
			pv8630_mini_init_scanner(fd);
		}
		return(SANE_STATUS_IO_ERROR);
	}
	
	/* Send the parameters and check they've been received OK. */
	if (param_size) {
		sanei_pv8630_flush_buffer(fd);
		sanei_pv8630_prep_bulkwrite(fd, param_size);
		
		tmp_len = param_size;
		sanei_pv8630_bulkwrite(fd, param_ptr, &tmp_len);
		sanei_pv8630_wait_byte(fd, PV8630_RSTATUS, 0xf8, 0xff, 1000);
		
		sanei_pv8630_flush_buffer(fd);
		sanei_pv8630_prep_bulkread(fd, 1);
		
		result = 0xA5;				/* to be sure */
		tmp_len = 1;
		sanei_pv8630_bulkread(fd, &result, &tmp_len);
		if (result != 0) {
			DBG(DBG_info, "error in sanei_pv8630_bulkread (got %02x)\n", result);
			if (result == 8) {
				pv8630_mini_init_scanner(fd);
			}
			return(SANE_STATUS_IO_ERROR);
		}
	}

	/* If the SCSI command expect a return, get it. */
	if (dst_size != NULL && *dst_size != 0 && dst != NULL) {
		sanei_pv8630_flush_buffer(fd);
		sanei_pv8630_prep_bulkread(fd, *dst_size);
		sanei_pv8630_bulkread(fd, dst, dst_size);

		DBG(DBG_info, "  SCSI cmd returned %lu bytes\n", (u_long) *dst_size);

		sanei_pv8630_wait_byte(fd, PV8630_RSTATUS, 0xf8, 0xff, 1000);

		sanei_pv8630_flush_buffer(fd);
		sanei_pv8630_prep_bulkread(fd, 1);

		result = 0x5A;			/* just to be sure */
		tmp_len = 1;
		sanei_pv8630_bulkread(fd, &result, &tmp_len);
		if (result != 0) {
			DBG(DBG_info, "error in sanei_pv8630_bulkread (got %02x)\n", result);
			if (result == 8) {
				pv8630_mini_init_scanner(fd);
			}
			return(SANE_STATUS_IO_ERROR);
		}
	}

	sanei_pv8630_write_byte(fd, PV8630_UNKNOWN, 0x04);
	sanei_pv8630_write_byte(fd, PV8630_RMODE, 0x02);
	sanei_pv8630_write_byte(fd, PV8630_RMODE, 0x02);
	sanei_pv8630_wait_byte(fd, PV8630_RSTATUS, 0xd0, 0xff, 1000);

	DBG(DBG_info, "  SCSI command successfully executed\n");
 
	return(SANE_STATUS_GOOD);
}
Exemplo n.º 2
0
int get_scsi_cdb_size(struct scsi_cmd *cmd)
{
	return CDB_SIZE(cmd);
}