/* 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); }
int get_scsi_cdb_size(struct scsi_cmd *cmd) { return CDB_SIZE(cmd); }