sinfonia: Unify a pile of common commands across four backends

* docmd
 * flashled
 * setparam
 * getparam
 * canceljob
 * getfwinfo
 * geterrorlog
 * resetcurve
 * gettonecurve
 * settonecurve

(And the EK605 river no longer uses raw bytestreams for commands!)

Overall a ~600 line reduction of code size.  Added some functionality too.
This commit is contained in:
Solomon Peachy 2019-05-24 23:49:51 -04:00
parent 401f43f682
commit d72a4702c6
7 changed files with 677 additions and 1279 deletions

15
README
View File

@ -465,10 +465,17 @@
Valid commands:
-C filename Set tone curve [1]
-m Query media information
-s Query printer status
-c filename Query User tone curve from flash [1]
-C filename Store User tone curve in flash [1]
-e Query error log
-F Flash printer LEDs for 5 seconds
-i Query printer firmware information
-l filename Query Current tone curve from RAM [1]
-L filename Store Current tone curve in RAM [1]
-m Query media information
-r Reset User tone curve to default [3]
-R Reset printer to factory defaults
-s Query printer status
-X id Cancel print job 'id' [2]
Notes:
@ -486,6 +493,8 @@
To see which jobs are active/pending, see the output of the
'-s' command, specifically the 'Bank' output.
[3] Default printer tone curve is a linear 'val << 3'
***************************************************************************
BACKEND=shinkos2145

View File

@ -97,10 +97,8 @@ struct kodak605_status {
/* Private data structure */
struct kodak605_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
struct sinfonia_usbdev dev;
uint8_t jobid;
struct kodak605_media_list *media;
@ -286,67 +284,36 @@ static const char *error_codes(uint8_t major, uint8_t minor)
static int kodak605_get_media(struct kodak605_ctx *ctx, struct kodak605_media_list *media)
{
uint8_t cmdbuf[4];
struct sinfonia_cmd_hdr cmd;
int ret, num = 0;
/* Send Media Query */
cmdbuf[0] = 0x02;
cmdbuf[1] = 0x00;
cmdbuf[2] = 0x00;
cmdbuf[3] = 0x00;
if ((ret = send_data(ctx->dev, ctx->endp_down,
cmdbuf, sizeof(cmdbuf))))
return ret;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
/* Read the media response */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) media, MAX_MEDIA_LEN, &num);
if (ret < 0)
if ((ret =sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)media, MAX_MEDIA_LEN,
&num))) {
return ret;
if (num < (int)sizeof(*media)) {
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*media));
return CUPS_BACKEND_FAILED;
}
if (media->hdr.result != RESULT_SUCCESS) {
ERROR("Unexpected response from media query (%x)!\n", media->hdr.result);
return CUPS_BACKEND_FAILED;
}
return 0;
}
static int kodak605_get_status(struct kodak605_ctx *ctx, struct kodak605_status *sts)
{
uint8_t cmdbuf[4];
struct sinfonia_cmd_hdr cmd;
int ret, num = 0;
/* Send Status Query */
cmdbuf[0] = 0x01;
cmdbuf[1] = 0x00;
cmdbuf[2] = 0x00;
cmdbuf[3] = 0x00;
if ((ret = send_data(ctx->dev, ctx->endp_down,
cmdbuf, sizeof(cmdbuf))))
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)sts, sizeof(*sts), &num)) < 0) {
return ret;
/* Read in the printer status */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) sts, sizeof(*sts), &num);
if (ret < 0)
return ret;
if (num < (int)sizeof(*sts)) {
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(*sts));
return CUPS_BACKEND_FAILED;
}
if (sts->hdr.result != RESULT_SUCCESS) {
ERROR("Unexpected response from status query (%x)!\n", sts->hdr.result);
return CUPS_BACKEND_FAILED;
}
return 0;
@ -371,10 +338,11 @@ static int kodak605_attach(void *vctx, struct libusb_device_handle *dev, int typ
{
struct kodak605_ctx *ctx = vctx;
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->dev.dev = dev;
ctx->dev.endp_up = endp_up;
ctx->dev.endp_down = endp_down;
ctx->dev.type = type;
ctx->dev.error_codes = &error_codes;
/* Make sure jobid is sane */
ctx->jobid = jobid & 0x7f;
@ -443,7 +411,6 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
int num, ret;
const struct sinfonia_printjob *job = vjob;
struct sinfonia_printcmd10_hdr hdr;
if (!ctx)
return CUPS_BACKEND_FAILED;
@ -502,29 +469,28 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
sleep(1);
}
/* Use specified jobid */
hdr.jobid = ctx->jobid;
/* Set up header */
hdr.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
hdr.hdr.len = cpu_to_le16(10);
hdr.rows = cpu_to_le16(job->jp.rows);
hdr.columns = cpu_to_le16(job->jp.columns);
hdr.copies = cpu_to_le16(job->jp.copies);
hdr.media = job->jp.media;
hdr.oc_mode = job->jp.oc_mode;
hdr.method = job->jp.method;
do {
INFO("Sending image header (internal id %u)\n", ctx->jobid);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*)&hdr, sizeof(hdr))))
return CUPS_BACKEND_FAILED;
struct sinfonia_printcmd10_hdr hdr;
struct sinfonia_status_hdr resp;
if ((ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &resp, sizeof(resp), &num)))
return CUPS_BACKEND_FAILED;
INFO("Sending print job (internal id %u)\n", ctx->jobid);
/* Set up header */
hdr.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
hdr.hdr.len = cpu_to_le16(10);
hdr.jobid = ctx->jobid;
hdr.rows = cpu_to_le16(job->jp.rows);
hdr.columns = cpu_to_le16(job->jp.columns);
hdr.copies = cpu_to_le16(job->jp.copies);
hdr.media = job->jp.media;
hdr.oc_mode = job->jp.oc_mode;
hdr.method = job->jp.method;
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&hdr, sizeof(hdr),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
if (resp.result != RESULT_SUCCESS) {
if (resp.error == ERROR_BUFFER_FULL) {
@ -550,7 +516,7 @@ static int kodak605_main_loop(void *vctx, const void *vjob) {
sleep(1);
INFO("Sending image data\n");
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@ -645,42 +611,6 @@ static void kodak605_dump_status(struct kodak605_ctx *ctx, struct kodak605_statu
INFO("Donor : %u%%\n", sts->donor);
}
static int kodak605_get_errorlog(struct kodak605_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_errorlog_resp resp;
int ret, num = 0;
int i;
/* Initial Request */
cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
cmd.len = cpu_to_le16(0);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd))))
goto done;
/* Get response back */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &resp, sizeof(resp), &num);
if (ret < 0)
goto done;
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
return -2;
INFO("Stored Error Events: %u entries:\n", resp.count);
for (i = 0 ; i < resp.count ; i++) {
INFO(" %02d: @ %08u prints : 0x%02x/0x%02x\n", i,
le32_to_cpu(resp.items[i].print_counter),
resp.items[i].major, resp.items[i].minor);
}
done:
return ret;
}
static void kodak605_dump_mediainfo(struct kodak605_media_list *media)
{
int i;
@ -700,115 +630,18 @@ static void kodak605_dump_mediainfo(struct kodak605_media_list *media)
DEBUG("\n");
}
static int kodak605_set_tonecurve(struct kodak605_ctx *ctx, char *fname)
{
libusb_device_handle *dev = ctx->dev;
uint8_t endp_down = ctx->endp_down;
uint8_t endp_up = ctx->endp_up;
uint8_t cmdbuf[16];
uint8_t respbuf[16];
int ret, num = 0;
uint16_t *data = malloc(TONE_CURVE_SIZE);
INFO("Set Tone Curve from '%s'\n", fname);
/* Read in file */
if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE, NULL))) {
ERROR("Failed to read Tone Curve file\n");
goto done;
}
/* Byteswap data to printer's format */
for (ret = 0; ret < (TONE_CURVE_SIZE/2) ; ret++) {
data[ret] = cpu_to_le16(be16_to_cpu(data[ret]));
}
/* Initial Request */
cmdbuf[0] = 0x04;
cmdbuf[1] = 0xc0;
cmdbuf[2] = 0x0a;
cmdbuf[3] = 0x00;
cmdbuf[4] = 0x03;
cmdbuf[5] = 0x01;
cmdbuf[6] = 0x00;
cmdbuf[7] = 0x00;
cmdbuf[8] = 0x00;
cmdbuf[9] = 0x00;
cmdbuf[10] = 0x00; /* 00 06 in LE means 1536 bytes */
cmdbuf[11] = 0x06;
cmdbuf[12] = 0x00;
cmdbuf[13] = 0x00;
if ((ret = send_data(dev, endp_down,
cmdbuf, 14)))
goto done;
/* Get response back */
ret = read_data(dev, endp_up,
respbuf, sizeof(respbuf), &num);
if (ret < 0)
goto done;
if (num != 10) {
ERROR("Short Read! (%d/%d)\n", num, 10);
ret = 4;
goto done;
}
/* Send the data over! */
ret = send_data(dev, endp_up,
(uint8_t*)data, sizeof(data));
done:
/* We're done */
free(data);
return ret;
}
static int kodak605_cancel_job(struct kodak605_ctx *ctx, char *str)
{
struct sinfonia_cancel_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
if (!str)
return -1;
/* Send Job Cancel */
cmd.id = atoi(str);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*)&cmd, sizeof(cmd))))
return ret;
/* Read the media response */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) &resp, sizeof(resp), &num);
if (ret < 0)
return ret;
if (num < (int)sizeof(resp)) {
ERROR("Short Read! (%d/%d)\n", num, (int)sizeof(resp));
return CUPS_BACKEND_FAILED;
}
if (resp.result != RESULT_SUCCESS) {
ERROR("Unexpected response from job cancel query (%x)!\n", resp.result);
return CUPS_BACKEND_FAILED;
}
return 0;
}
static void kodak605_cmdline(void)
{
DEBUG("\t\t[ -c filename ] # Get user/NV tone curve\n");
DEBUG("\t\t[ -C filename ] # Set tone curve\n");
DEBUG("\t\t[ -e ] # Query error log\n");
DEBUG("\t\t[ -F ] # Flash Printer LED\n");
DEBUG("\t\t[ -i ] # Query printer info\n");
DEBUG("\t\t[ -l filename ] # Get current tone curve\n");
DEBUG("\t\t[ -L filename ] # Set current tone curve\n");
DEBUG("\t\t[ -m ] # Query media\n");
DEBUG("\t\t[ -r ] # Reset user/NV tone curve\n");
DEBUG("\t\t[ -R ] # Reset printer to factory defaults\n");
DEBUG("\t\t[ -s ] # Query status\n");
DEBUG("\t\t[ -X jobid ] # Cancel job\n");
}
@ -821,18 +654,39 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
if (!ctx)
return -1;
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "C:emsX:")) >= 0) {
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFil:L:mrRsX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'c':
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'C':
j = kodak605_set_tonecurve(ctx, optarg);
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'e':
j = kodak605_get_errorlog(ctx);
j = sinfonia_geterrorlog(&ctx->dev);
break;
case 'F':
j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
j = sinfonia_getfwinfo(&ctx->dev);
break;
case 'l':
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'L':
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
kodak605_dump_mediainfo(ctx->media);
break;
case 'r':
j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
break;
case 'R':
j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
break;
case 's': {
struct kodak605_status sts;
@ -841,7 +695,7 @@ static int kodak605_cmdline_arg(void *vctx, int argc, char **argv)
kodak605_dump_status(ctx, &sts);
break;
case 'X':
j = kodak605_cancel_job(ctx, optarg);
j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
}
default:
@ -880,7 +734,7 @@ static const char *kodak605_prefixes[] = {
/* Exported */
struct dyesub_backend kodak605_backend = {
.name = "Kodak 605/70xx",
.version = "0.41" " (lib " LIBSINFONIA_VER ")",
.version = "0.42" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = kodak605_prefixes,
.cmdline_usage = kodak605_cmdline,
.cmdline_arg = kodak605_cmdline_arg,

View File

@ -54,17 +54,6 @@ enum {
};
/* Structs for printer */
struct s2145_print_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t id;
uint16_t count;
uint16_t columns;
uint16_t rows;
uint8_t media;
uint8_t mode;
uint8_t method;
} __attribute__((packed));
static int print_counts (uint8_t v) {
switch (v) {
case CODE_4x6:
@ -176,7 +165,7 @@ struct s2145_setunique_cmd {
uint8_t data[23]; /* Not necessarily all used. */
} __attribute__((packed));
static char *error_codes(uint8_t major, uint8_t minor)
static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
case 0x01: /* "Controller Error" */
@ -420,60 +409,15 @@ struct s2145_getunique_resp {
/* Private data structure */
struct shinkos2145_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
struct sinfonia_usbdev dev;
uint8_t jobid;
int type;
struct s2145_mediainfo_resp media;
struct marker marker;
int media_code;
};
static int s2145_do_cmd(struct shinkos2145_ctx *ctx,
uint8_t *cmd, int cmdlen,
uint8_t *resp, int resplen,
int *num)
{
int ret;
struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
libusb_device_handle *dev = ctx->dev;
uint8_t endp_up = ctx->endp_up;
uint8_t endp_down = ctx->endp_down;
if ((ret = send_data(dev, endp_down,
cmd, cmdlen)))
goto fail;
ret = read_data(dev, endp_up,
resp, resplen, num);
if (ret < 0)
goto fail;
if (resphdr->result != RESULT_SUCCESS) {
INFO("Printer Status: %02x (%s)\n", resphdr->status,
sinfonia_status_str(resphdr->status));
INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
resphdr->result, resphdr->error, resphdr->printer_major,
resphdr->printer_minor, error_codes(resphdr->printer_major, resphdr->printer_minor));
goto fail;
}
return 0;
fail:
ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
if (ret < 0)
return ret;
else
return -99;
}
static int get_status(struct shinkos2145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
@ -483,7 +427,7 @@ static int get_status(struct shinkos2145_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -546,7 +490,7 @@ static int get_fwinfo(struct shinkos2145_ctx *ctx)
int ret;
cmd.target = i;
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -569,36 +513,6 @@ static int get_fwinfo(struct shinkos2145_ctx *ctx)
return 0;
}
static int get_errorlog(struct shinkos2145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_errorlog_resp resp;
int ret, num = 0;
int i;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
return -2;
INFO("Stored Error Events: %u entries:\n", resp.count);
for (i = 0 ; i < resp.count ; i++) {
INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i,
le32_to_cpu(resp.items[i].print_counter),
resp.items[i].major, resp.items[i].minor,
error_codes(resp.items[i].major, resp.items[i].minor));
}
return 0;
}
static void dump_mediainfo(struct s2145_mediainfo_resp *resp)
{
int i;
@ -624,7 +538,7 @@ static int get_user_string(struct shinkos2145_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETUNIQUE);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -659,7 +573,7 @@ static int set_user_string(struct shinkos2145_ctx *ctx, char *str)
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETUNIQUE);
cmd.hdr.len = cpu_to_le16(cmd.len + 1);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, cmd.len + 1 + sizeof(cmd.hdr),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -669,49 +583,6 @@ static int set_user_string(struct shinkos2145_ctx *ctx, char *str)
return 0;
}
static int cancel_job(struct shinkos2145_ctx *ctx, char *str)
{
struct sinfonia_cancel_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
if (!str)
return -1;
cmd.id = atoi(str);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s2145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int flash_led(struct shinkos2145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int reset_curve(struct shinkos2145_ctx *ctx, int target)
{
struct s2145_reset_cmd cmd;
@ -724,7 +595,7 @@ static int reset_curve(struct shinkos2145_ctx *ctx, int target)
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -745,7 +616,7 @@ static int button_set(struct shinkos2145_ctx *ctx, int enable)
cmd.enabled = enable;
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&cmd, sizeof(resp),
&num)) < 0) {
@ -773,7 +644,7 @@ static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -791,7 +662,7 @@ static int get_tonecurve(struct shinkos2145_ctx *ctx, int type, char *fname)
i = 0;
while (i < resp.total_size) {
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->dev.dev, ctx->dev.endp_up,
data + i,
resp.total_size * 2 - i,
&num);
@ -874,7 +745,7 @@ static int set_tonecurve(struct shinkos2145_ctx *ctx, int target, char *fname)
data[ret] = cpu_to_le16(data[ret]);
}
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
@ -882,7 +753,7 @@ static int set_tonecurve(struct shinkos2145_ctx *ctx, int target, char *fname)
}
/* Sent transfer */
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
(uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
goto done;
}
@ -938,10 +809,10 @@ int shinkos2145_cmdline_arg(void *vctx, int argc, char **argv)
j = set_tonecurve(ctx, TONECURVE_USER, optarg);
break;
case 'e':
j = get_errorlog(ctx);
j = sinfonia_geterrorlog(&ctx->dev);
break;
case 'F':
j = flash_led(ctx);
j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
j = get_fwinfo(ctx);
@ -971,7 +842,7 @@ int shinkos2145_cmdline_arg(void *vctx, int argc, char **argv)
j = set_user_string(ctx, optarg);
break;
case 'X':
j = cancel_job(ctx, optarg);
j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@ -1002,10 +873,11 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
{
struct shinkos2145_ctx *ctx = vctx;
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->dev.dev = dev;
ctx->dev.endp_up = endp_up;
ctx->dev.endp_down = endp_down;
ctx->dev.type = type;
ctx->dev.error_codes = &error_codes;
/* Ensure jobid is sane */
ctx->jobid = (jobid & 0x7f);
@ -1022,7 +894,7 @@ static int shinkos2145_attach(void *vctx, struct libusb_device_handle *dev, int
cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
if (s2145_do_cmd(ctx,
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&ctx->media, sizeof(ctx->media),
&num)) {
@ -1127,7 +999,7 @@ top:
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
@ -1178,7 +1050,7 @@ top:
break;
case S_PRINTER_READY_CMD: {
struct s2145_print_cmd print;
struct sinfonia_printcmd10_hdr print;
INFO("Sending print job (internal id %u)\n", ctx->jobid);
@ -1186,15 +1058,15 @@ top:
print.hdr.cmd = cpu_to_le16(SINFONIA_CMD_PRINTJOB);
print.hdr.len = cpu_to_le16(sizeof(print) - sizeof(print.hdr));
print.id = ctx->jobid;
print.count = cpu_to_le16(job->copies);
print.jobid = ctx->jobid;
print.copies = cpu_to_le16(job->copies);
print.columns = cpu_to_le16(job->jp.columns);
print.rows = cpu_to_le16(job->jp.rows);
print.media = job->jp.media;
print.mode = job->jp.oc_mode;
print.oc_mode = job->jp.oc_mode;
print.method = job->jp.method;
if ((ret = s2145_do_cmd(ctx,
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&print, sizeof(print),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
@ -1213,7 +1085,7 @@ top:
}
INFO("Sending image data to printer\n");
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@ -1270,7 +1142,7 @@ static int shinkos2145_query_serno(struct libusb_device_handle *dev, uint8_t end
struct s2145_getunique_resp resp;
int ret, num = 0;
struct shinkos2145_ctx ctx = {
struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
@ -1279,10 +1151,10 @@ static int shinkos2145_query_serno(struct libusb_device_handle *dev, uint8_t end
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETUNIQUE);
cmd.len = cpu_to_le16(0);
if ((ret = s2145_do_cmd(&ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&sdev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -1305,7 +1177,7 @@ static int shinkos2145_query_markers(void *vctx, struct marker **markers, int *c
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if (s2145_do_cmd(ctx,
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) {
@ -1335,7 +1207,7 @@ static const char *shinkos2145_prefixes[] = {
struct dyesub_backend shinkos2145_backend = {
.name = "Shinko/Sinfonia CHC-S2145/S2",
.version = "0.60" " (lib " LIBSINFONIA_VER ")",
.version = "0.61" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos2145_prefixes,
.cmdline_usage = shinkos2145_cmdline,
.cmdline_arg = shinkos2145_cmdline_arg,

View File

@ -256,26 +256,6 @@ static char *print_modes(uint8_t v) {
}
#endif
struct s6145_reset_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define RESET_PRINTER 0x03
#define RESET_TONE_CURVE 0x04
#define TONE_CURVE_ID 0x01
struct s6145_readtone_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define READ_TONE_CURVE_USER 0x01
#define READ_TONE_CURVE_CURR 0x02
#define PARAM_OC_PRINT 0x20
#define PARAM_PAPER_PRESV 0x3d
#define PARAM_DRIVER_MODE 0x3e
@ -304,41 +284,7 @@ struct s6145_readtone_cmd {
#define PARAM_SLEEP_120MIN 0x00000004
#define PARAM_SLEEP_240MIN 0x00000005
struct s6145_errorlog_cmd {
struct sinfonia_cmd_hdr hdr;
uint16_t index; /* 0 is latest */
} __attribute__((packed));
#define FWINFO_TARGET_MAIN_BOOT 0x01
#define FWINFO_TARGET_MAIN_APP 0x02
#define FWINFO_TARGET_PRINT_TABLES 0x03
#define FWINFO_TARGET_DSP 0x04
static char *fwinfo_targets (uint8_t v) {
switch (v) {
case FWINFO_TARGET_MAIN_BOOT:
return "Main Boot ";
case FWINFO_TARGET_MAIN_APP:
return "Main App ";
case FWINFO_TARGET_DSP:
return "DSP ";
case FWINFO_TARGET_PRINT_TABLES:
return "Print Tables";
default:
return "Unknown ";
}
}
struct s6145_update_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curve_id;
uint8_t reset; // ??
uint8_t reserved[3];
uint32_t size;
} __attribute__((packed));
static char *error_codes(uint8_t major, uint8_t minor)
static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
case 0x01: /* "Controller Error" */
@ -563,11 +509,6 @@ struct s6145_geteeprom_resp {
uint8_t data[256];
} __attribute__((packed));
struct s6145_readtone_resp {
struct sinfonia_status_hdr hdr;
uint16_t total_size;
} __attribute__((packed));
#define RIBBON_NONE 0x00
#define RIBBON_4x6 0x01
#define RIBBON_3_5x5 0x02
@ -635,10 +576,7 @@ struct s6145_imagecorr_data {
/* Private data structure */
struct shinkos6145_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
struct sinfonia_usbdev dev;
uint8_t jobid;
@ -661,46 +599,6 @@ struct shinkos6145_ctx {
static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx);
static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx);
static int get_param(struct shinkos6145_ctx *ctx, int target, uint32_t *param);
static int s6145_do_cmd(struct shinkos6145_ctx *ctx,
uint8_t *cmd, int cmdlen,
uint8_t *resp, int resplen,
int *num)
{
libusb_device_handle *dev = ctx->dev;
uint8_t endp_up = ctx->endp_up;
uint8_t endp_down = ctx->endp_down;
int ret;
struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
if ((ret = send_data(dev, endp_down,
cmd, cmdlen))) {
goto fail;
}
ret = read_data(dev, endp_up,
(uint8_t *)resp, resplen, num);
if (ret < 0)
goto fail;
if (resphdr->result != RESULT_SUCCESS) {
INFO("Printer Status: %02x (%s)\n", resphdr->status,
sinfonia_status_str(resphdr->status));
INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
resphdr->result, resphdr->error, resphdr->printer_major,
resphdr->printer_minor, error_codes(resphdr->printer_major, resphdr->printer_minor));
goto fail;
}
return 0;
fail:
ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
return ret;
}
static int get_status(struct shinkos6145_ctx *ctx)
{
@ -713,9 +611,9 @@ static int get_status(struct shinkos6145_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp), &num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp), &num)) < 0) {
return ret;
}
@ -760,10 +658,10 @@ static int get_status(struct shinkos6145_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_EXTCOUNTER);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp2, sizeof(resp2),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp2, sizeof(resp2),
&num)) < 0) {
return ret;
}
if (le16_to_cpu(resp2.hdr.payload_len) != (sizeof(struct sinfonia_getextcounter_resp) - sizeof(struct sinfonia_status_hdr)))
@ -774,33 +672,33 @@ static int get_status(struct shinkos6145_ctx *ctx)
INFO("Head Distance: %08u inches\n", le32_to_cpu(resp2.head_distance));
/* Query various params */
if (ctx->type == P_SHINKO_S6145D) {
if ((ret = get_param(ctx, PARAM_REGION_CODE, &val))) {
if (ctx->dev.type == P_SHINKO_S6145D) {
if ((ret = sinfonia_getparam(&ctx->dev, PARAM_REGION_CODE, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Region Code: %#x\n", val);
}
if ((ret = get_param(ctx, PARAM_PAPER_PRESV, &val))) {
if ((ret = sinfonia_getparam(&ctx->dev, PARAM_PAPER_PRESV, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Paper Preserve mode: %s\n", (val ? "On" : "Off"));
if ((ret = get_param(ctx, PARAM_DRIVER_MODE, &val))) {
if ((ret = sinfonia_getparam(&ctx->dev, PARAM_DRIVER_MODE, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Driver mode: %s\n", (val ? "On" : "Off"));
if ((ret = get_param(ctx, PARAM_PAPER_MODE, &val))) {
if ((ret = sinfonia_getparam(&ctx->dev, PARAM_PAPER_MODE, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
INFO("Paper load mode: %s\n", (val ? "Cut" : "No Cut"));
if ((ret = get_param(ctx, PARAM_SLEEP_TIME, &val))) {
if ((ret = sinfonia_getparam(&ctx->dev, PARAM_SLEEP_TIME, &val))) {
ERROR("Failed to execute command\n");
return ret;
}
@ -824,75 +722,6 @@ static int get_status(struct shinkos6145_ctx *ctx)
return 0;
}
static int get_fwinfo(struct shinkos6145_ctx *ctx)
{
struct sinfonia_fwinfo_cmd cmd;
struct sinfonia_fwinfo_resp resp;
int num = 0;
int i;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
cmd.hdr.len = cpu_to_le16(1);
INFO("FW Information:\n");
for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES ; i++) {
int ret;
cmd.target = i;
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
continue;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
continue;
INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
resp.major, resp.minor);
#if 0
INFO(" name: '%s'\n", resp.name);
INFO(" type: '%s'\n", resp.type);
INFO(" date: '%s'\n", resp.date);
INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
le16_to_cpu(resp.checksum));
#endif
}
return 0;
}
static int get_errorlog(struct shinkos6145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_errorlog_resp resp;
int ret, num = 0;
int i;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
return -2;
INFO("Stored Error Events: %u entries:\n", resp.count);
for (i = 0 ; i < resp.count ; i++) {
INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i,
le32_to_cpu(resp.items[i].print_counter),
resp.items[i].major, resp.items[i].minor,
error_codes(resp.items[i].major, resp.items[i].minor));
}
return 0;
}
static void dump_mediainfo(struct s6145_mediainfo_resp *resp)
{
int i;
@ -910,114 +739,6 @@ static void dump_mediainfo(struct s6145_mediainfo_resp *resp)
}
}
static int cancel_job(struct shinkos6145_ctx *ctx, char *str)
{
struct sinfonia_cancel_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
if (!str)
return -1;
cmd.id = atoi(str);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int flash_led(struct shinkos6145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int set_param(struct shinkos6145_ctx *ctx, int target, uint32_t param)
{
struct sinfonia_setparam_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
/* Set up command */
cmd.target = target;
cmd.param = cpu_to_le32(param);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETPARAM);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_setparam_cmd)-sizeof(cmd.hdr));
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
}
return ret;
}
static int get_param(struct shinkos6145_ctx *ctx, int target, uint32_t *param)
{
struct sinfonia_getparam_cmd cmd;
struct sinfonia_getparam_resp resp;
int ret, num = 0;
/* Set up command */
cmd.target = target;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_GETPARAM);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_getparam_cmd)-sizeof(cmd.hdr));
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
}
*param = le32_to_cpu(resp.param);
return ret;
}
static int reset_curve(struct shinkos6145_ctx *ctx, int target)
{
struct s6145_reset_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.target = target;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int shinkos6145_dump_corrdata(struct shinkos6145_ctx *ctx, char *fname)
{
int ret;
@ -1078,137 +799,6 @@ static int shinkos6145_dump_eeprom(struct shinkos6145_ctx *ctx, char *fname)
return ret;
}
static int get_tonecurve(struct shinkos6145_ctx *ctx, int type, char *fname)
{
struct s6145_readtone_cmd cmd;
struct s6145_readtone_resp resp;
int ret, num = 0;
uint8_t *data;
uint16_t curves[TONE_CURVE_SIZE] = { 0 };
int i,j;
cmd.target = type;
cmd.curveid = TONE_CURVE_ID;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
cmd.hdr.len = cpu_to_le16(1);
INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
resp.total_size = le16_to_cpu(resp.total_size);
data = malloc(resp.total_size * 2);
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
i = 0;
while (i < resp.total_size) {
ret = read_data(ctx->dev, ctx->endp_up,
data + i,
resp.total_size * 2 - i,
&num);
if (ret < 0)
goto done;
i += num;
}
i = j = 0;
while (i < resp.total_size) {
memcpy(curves + j, data + i+2, data[i+1]);
j += data[i+1] / 2;
i += data[i+1] + 2;
}
/* Open file and write it out */
{
int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
if (tc_fd < 0) {
ret = -1;
goto done;
}
for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
/* Byteswap appropriately */
curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
}
write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
close(tc_fd);
}
done:
free(data);
return ret;
}
static int set_tonecurve(struct shinkos6145_ctx *ctx, int target, char *fname)
{
struct s6145_update_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
/* Read in file */
if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE * sizeof(uint16_t), NULL))) {
ERROR("Failed to read Tone Curve file\n");
goto done;
}
/* Byteswap data to local CPU.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = be16_to_cpu(data[ret]);
}
/* Set up command */
cmd.target = target;
cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
cmd.reset = 0;
cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
cmd.hdr.len = cpu_to_le16(sizeof(struct s6145_update_cmd)-sizeof(cmd.hdr));
/* Byteswap data to format printer is expecting.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = cpu_to_le16(data[ret]);
}
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
goto done;
}
/* Sent transfer */
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
goto done;
}
done:
free(data);
return ret;
}
static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
@ -1224,10 +814,10 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
ctx->corrdata = NULL;
}
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
goto done;
}
@ -1246,7 +836,7 @@ static int shinkos6145_get_imagecorr(struct shinkos6145_ctx *ctx)
while (total < ctx->corrdatalen) {
struct s6145_imagecorr_data data;
ret = read_data(ctx->dev, ctx->endp_up, (uint8_t *) &data,
ret = read_data(ctx->dev.dev, ctx->dev.endp_up, (uint8_t *) &data,
sizeof(data),
&num);
if (ret < 0)
@ -1279,10 +869,10 @@ static int shinkos6145_get_eeprom(struct shinkos6145_ctx *ctx)
ctx->eeprom = NULL;
}
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
goto done;
}
@ -1326,23 +916,23 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv)
if (!ctx)
return -1;
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:Q:q:R:sX:")) >= 0) {
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:Q:q:rR:sX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'c':
j = get_tonecurve(ctx, TONECURVE_USER, optarg);
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'C':
j = set_tonecurve(ctx, TONECURVE_USER, optarg);
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'e':
j = get_errorlog(ctx);
j = sinfonia_geterrorlog(&ctx->dev);
break;
case 'F':
j = flash_led(ctx);
j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
j = get_fwinfo(ctx);
j = sinfonia_getfwinfo(&ctx->dev);
break;
case 'k': {
i = atoi(optarg);
@ -1361,14 +951,14 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv)
else
i = 5;
j = set_param(ctx, PARAM_SLEEP_TIME, i);
j = sinfonia_setparam(&ctx->dev, PARAM_SLEEP_TIME, i);
break;
}
case 'l':
j = get_tonecurve(ctx, TONECURVE_CURRENT, optarg);
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'L':
j = set_tonecurve(ctx, TONECURVE_CURRENT, optarg);
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
dump_mediainfo(&ctx->media);
@ -1380,16 +970,16 @@ int shinkos6145_cmdline_arg(void *vctx, int argc, char **argv)
j = shinkos6145_dump_corrdata(ctx, optarg);
break;
case 'r':
j = reset_curve(ctx, RESET_TONE_CURVE);
j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
break;
case 'R':
j = reset_curve(ctx, RESET_PRINTER);
j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
break;
case 's':
j = get_status(ctx);
break;
case 'X':
j = cancel_job(ctx, optarg);
j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@ -1420,10 +1010,11 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
{
struct shinkos6145_ctx *ctx = vctx;
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->dev.dev = dev;
ctx->dev.endp_up = endp_up;
ctx->dev.endp_down = endp_down;
ctx->dev.type = type;
ctx->dev.error_codes = &error_codes;
/* Attempt to open the library */
#if defined(WITH_DYNAMIC)
@ -1449,7 +1040,9 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
#endif
/* Ensure jobid is sane */
ctx->jobid = (jobid & 0x7f) + 1;
ctx->jobid = (jobid & 0x7f);
if (!ctx->jobid)
ctx->jobid++;
if (test_mode < TEST_MODE_NOATTACH) {
/* Query Media */
@ -1459,10 +1052,10 @@ static int shinkos6145_attach(void *vctx, struct libusb_device_handle *dev, int
cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
if (s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&ctx->media, sizeof(&ctx->media),
&num)) {
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&ctx->media, sizeof(&ctx->media),
&num)) {
return CUPS_BACKEND_FAILED;
}
@ -1608,8 +1201,8 @@ static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, in
if (!ctx)
return CUPS_BACKEND_FAILED;
if (ctx->type == P_SHINKO_S6145 ||
ctx->type == P_SHINKO_S6145D)
if (ctx->dev.type == P_SHINKO_S6145 ||
ctx->dev.type == P_SHINKO_S6145D)
model = 6145;
else
model = 2245;
@ -1622,7 +1215,7 @@ static int shinkos6145_read_parse(void *vctx, const void **vjob, int data_fd, in
memset(job, 0, sizeof(*job));
/* Common read/parse code */
if (ctx->type == P_KODAK_6900) {
if (ctx->dev.type == P_KODAK_6900) {
ret = sinfonia_raw10_read_parse(data_fd, job);
} else {
ret = sinfonia_read_parse(data_fd, model, job);
@ -1711,7 +1304,7 @@ static int shinkos6145_main_loop(void *vctx, const void *vjob) {
// XXX check copies against remaining media?
/* Query printer mode */
ret = get_param(ctx, PARAM_OC_PRINT, &cur_mode);
ret = sinfonia_getparam(&ctx->dev, PARAM_OC_PRINT, &cur_mode);
if (ret) {
ERROR("Failed to execute command\n");
return ret;
@ -1727,10 +1320,10 @@ top:
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
return CUPS_BACKEND_FAILED;
}
@ -1785,7 +1378,7 @@ top:
sleep(1);
goto top;
}
ret = set_param(ctx, PARAM_OC_PRINT, oc_mode);
ret = sinfonia_setparam(&ctx->dev, PARAM_OC_PRINT, oc_mode);
if (ret) {
ERROR("Failed to execute command\n");
return ret;
@ -1857,15 +1450,15 @@ top:
print.combo_wait = 0;
/* Brava21 header has a few quirks */
if(ctx->type == P_SHINKO_S6145D) {
if(ctx->dev.type == P_SHINKO_S6145D) {
print.media = job->jp.media;
print.unk_1 = 0x01;
}
if ((ret = s6145_do_cmd(ctx,
(uint8_t*)&print, sizeof(print),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&print, sizeof(print),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
return ret;
}
@ -1883,7 +1476,7 @@ top:
INFO("Sending image data to printer\n");
// XXX we shouldn't send the lamination layer over if
// it's not needed. hdr->oc_mode == PRINT_MODE_NO_OC
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@ -1928,7 +1521,7 @@ static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t end
struct sinfonia_getserial_resp resp;
int ret, num = 0;
struct shinkos6145_ctx ctx = {
struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
@ -1937,10 +1530,10 @@ static int shinkos6145_query_serno(struct libusb_device_handle *dev, uint8_t end
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSERIAL);
cmd.len = cpu_to_le16(0);
if ((ret = s6145_do_cmd(&ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&sdev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -1963,10 +1556,10 @@ static int shinkos6145_query_markers(void *vctx, struct marker **markers, int *c
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if (s6145_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) {
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) {
return CUPS_BACKEND_FAILED;
}
@ -1998,7 +1591,7 @@ static const char *shinkos6145_prefixes[] = {
struct dyesub_backend shinkos6145_backend = {
.name = "Shinko/Sinfonia CHC-S6145/CS2/S2245/S3",
.version = "0.35" " (lib " LIBSINFONIA_VER ")",
.version = "0.36" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos6145_prefixes,
.cmdline_usage = shinkos6145_cmdline,
.cmdline_arg = shinkos6145_cmdline_arg,

View File

@ -84,26 +84,6 @@ static char *print_modes(uint8_t v) {
}
#endif
struct s6245_reset_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define RESET_PRINTER 0x03
#define RESET_TONE_CURVE 0x04
#define TONE_CURVE_ID 0x01
struct s6245_readtone_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define READ_TONE_CURVE_USER 0x01
#define READ_TONE_CURVE_CURR 0x02
#define PARAM_DRIVER_MODE 0x3e
#define PARAM_PAPER_MODE 0x3f
#define PARAM_SLEEP_TIME 0x54
@ -137,35 +117,6 @@ struct s6245_errorlog_cmd {
uint16_t index; /* 0 is latest */
} __attribute__((packed));
#define FWINFO_TARGET_MAIN_BOOT 0x01
#define FWINFO_TARGET_MAIN_APP 0x02
#define FWINFO_TARGET_PRINT_TABLES 0x03
#define FWINFO_TARGET_DSP 0x04
static char *fwinfo_targets (uint8_t v) {
switch (v) {
case FWINFO_TARGET_MAIN_BOOT:
return "Main Boot ";
case FWINFO_TARGET_MAIN_APP:
return "Main App ";
case FWINFO_TARGET_DSP:
return "DSP ";
case FWINFO_TARGET_PRINT_TABLES:
return "Print Tables";
default:
return "Unknown ";
}
}
struct s6245_update_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curve_id;
uint8_t reset; // ??
uint8_t reserved[3];
uint32_t size;
} __attribute__((packed));
static const char *error_codes(uint8_t major, uint8_t minor)
{
switch(major) {
@ -413,11 +364,6 @@ struct s6245_geteeprom_resp {
uint8_t data[256];
} __attribute__((packed));
struct s6245_readtone_resp {
struct sinfonia_status_hdr hdr;
uint16_t total_size;
} __attribute__((packed));
struct s6245_mediainfo_resp {
struct sinfonia_status_hdr hdr;
uint8_t ribbon_code;
@ -488,10 +434,7 @@ struct s6245_errorlog_resp {
/* Private data structure */
struct shinkos6245_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
struct sinfonia_usbdev dev;
uint8_t jobid;
@ -500,48 +443,8 @@ struct shinkos6245_ctx {
struct s6245_mediainfo_resp media;
};
#define READBACK_LEN 512 /* Needs to be larger than largest response hdr */
#define CMDBUF_LEN sizeof(struct s6245_print_cmd)
static int s6245_do_cmd(struct shinkos6245_ctx *ctx,
uint8_t *cmd, int cmdlen,
uint8_t *resp, int resplen,
int *num)
{
libusb_device_handle *dev = ctx->dev;
uint8_t endp_up = ctx->endp_up;
uint8_t endp_down = ctx->endp_down;
int ret;
struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
if ((ret = send_data(dev, endp_down,
cmd, cmdlen))) {
goto fail;
}
ret = read_data(dev, endp_up,
(uint8_t *)resp, resplen, num);
if (ret < 0)
goto fail;
if (resphdr->result != RESULT_SUCCESS) {
INFO("Printer Status: %02x (%s)\n", resphdr->status,
sinfonia_status_str(resphdr->status));
INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
resphdr->result, resphdr->error, resphdr->printer_major,
resphdr->printer_minor, error_codes(resphdr->printer_major, resphdr->printer_minor));
goto fail;
}
return 0;
fail:
ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
return ret;
}
static int get_status(struct shinkos6245_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
@ -552,10 +455,10 @@ static int get_status(struct shinkos6245_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*) &resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*) &resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -600,10 +503,10 @@ static int get_status(struct shinkos6245_ctx *ctx)
cmd.cmd = cpu_to_le16(SINFONIA_CMD_EXTCOUNTER);
cmd.len = cpu_to_le16(0);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp2, sizeof(resp2),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp2, sizeof(resp2),
&num)) < 0) {
return ret;
}
// XXX breaks on Kodak 8810!
@ -617,45 +520,6 @@ static int get_status(struct shinkos6245_ctx *ctx)
return 0;
}
static int get_fwinfo(struct shinkos6245_ctx *ctx)
{
struct sinfonia_fwinfo_cmd cmd;
struct sinfonia_fwinfo_resp resp;
int num = 0;
int i;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
cmd.hdr.len = cpu_to_le16(1);
INFO("FW Information:\n");
for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES ; i++) {
int ret;
cmd.target = i;
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
continue;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
continue;
INFO(" %s\t ver %02x.%02x\n", fwinfo_targets(i),
resp.major, resp.minor);
#if 0
INFO(" name: '%s'\n", resp.name);
INFO(" type: '%s'\n", resp.type);
INFO(" date: '%s'\n", resp.date);
INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
le16_to_cpu(resp.checksum));
#endif
}
return 0;
}
static int get_errorlog(struct shinkos6245_ctx *ctx)
{
struct s6245_errorlog_cmd cmd;
@ -670,10 +534,10 @@ static int get_errorlog(struct shinkos6245_ctx *ctx)
int ret;
cmd.index = i;
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -711,224 +575,6 @@ static void dump_mediainfo(struct s6245_mediainfo_resp *resp)
}
}
static int cancel_job(struct shinkos6245_ctx *ctx, char *str)
{
struct sinfonia_cancel_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
if (!str)
return -1;
cmd.id = atoi(str);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int flash_led(struct shinkos6245_ctx *ctx)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
cmd.len = cpu_to_le16(0);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int set_param(struct shinkos6245_ctx *ctx, int target, uint32_t param)
{
struct sinfonia_setparam_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
/* Set up command */
cmd.target = target;
cmd.param = cpu_to_le32(param);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETPARAM);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_setparam_cmd)-sizeof(cmd.hdr));
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return ret;
}
static int reset_curve(struct shinkos6245_ctx *ctx, int target)
{
struct s6245_reset_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.target = target;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
static int get_tonecurve(struct shinkos6245_ctx *ctx, int type, char *fname)
{
struct s6245_readtone_cmd cmd;
struct s6245_readtone_resp resp;
int ret, num = 0;
uint8_t *data;
uint16_t curves[TONE_CURVE_SIZE] = { 0 };
int i,j;
cmd.target = type;
cmd.curveid = TONE_CURVE_ID;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
cmd.hdr.len = cpu_to_le16(1);
INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
resp.total_size = le16_to_cpu(resp.total_size);
data = malloc(resp.total_size * 2);
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
i = 0;
while (i < resp.total_size) {
ret = read_data(ctx->dev, ctx->endp_up,
data + i,
resp.total_size * 2 - i,
&num);
if (ret < 0)
goto done;
i += num;
}
i = j = 0;
while (i < resp.total_size) {
memcpy(curves + j, data + i+2, data[i+1]);
j += data[i+1] / 2;
i += data[i+1] + 2;
}
/* Open file and write it out */
{
int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
if (tc_fd < 0) {
ret = -1;
goto done;
}
for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
/* Byteswap appropriately */
curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
}
write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
close(tc_fd);
}
done:
free(data);
return ret;
}
static int set_tonecurve(struct shinkos6245_ctx *ctx, int target, char *fname)
{
struct s6245_update_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
/* Read in file */
if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE * sizeof(uint16_t), NULL))) {
ERROR("Failed to read Tone Curve file\n");
goto done;
}
/* Byteswap data to local CPU.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = be16_to_cpu(data[ret]);
}
/* Set up command */
cmd.target = target;
cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
cmd.reset = 0;
cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
cmd.hdr.len = cpu_to_le16(sizeof(struct s6245_update_cmd)-sizeof(cmd.hdr));
/* Byteswap data to format printer is expecting.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = cpu_to_le16(data[ret]);
}
if ((ret = s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
/* Sent transfer */
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
goto done;
}
done:
free(data);
return ret;
}
static void shinkos6245_cmdline(void)
{
DEBUG("\t\t[ -c filename ] # Get user/NV tone curve\n");
@ -954,23 +600,23 @@ int shinkos6245_cmdline_arg(void *vctx, int argc, char **argv)
if (!ctx)
return -1;
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mr:R:sX:")) >= 0) {
while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "c:C:eFik:l:L:mrR:sX:")) >= 0) {
switch(i) {
GETOPT_PROCESS_GLOBAL
case 'c':
j = get_tonecurve(ctx, TONECURVE_USER, optarg);
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'C':
j = set_tonecurve(ctx, TONECURVE_USER, optarg);
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_USER, optarg);
break;
case 'e':
j = get_errorlog(ctx);
break;
case 'F':
j = flash_led(ctx);
j = sinfonia_flashled(&ctx->dev);
break;
case 'i':
j = get_fwinfo(ctx);
j = sinfonia_getfwinfo(&ctx->dev);
break;
case 'k': {
i = atoi(optarg);
@ -989,29 +635,29 @@ int shinkos6245_cmdline_arg(void *vctx, int argc, char **argv)
else
i = 5;
j = set_param(ctx, PARAM_SLEEP_TIME, i);
j = sinfonia_setparam(&ctx->dev, PARAM_SLEEP_TIME, i);
break;
}
case 'l':
j = get_tonecurve(ctx, TONECURVE_CURRENT, optarg);
j = sinfonia_gettonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'L':
j = set_tonecurve(ctx, TONECURVE_CURRENT, optarg);
j = sinfonia_settonecurve(&ctx->dev, TONECURVE_CURRENT, optarg);
break;
case 'm':
dump_mediainfo(&ctx->media);
break;
case 'r':
j = reset_curve(ctx, RESET_TONE_CURVE);
j = sinfonia_resetcurve(&ctx->dev, RESET_TONE_CURVE, TONE_CURVE_ID);
break;
case 'R':
j = reset_curve(ctx, RESET_PRINTER);
j = sinfonia_resetcurve(&ctx->dev, RESET_PRINTER, 0);
break;
case 's':
j = get_status(ctx);
break;
case 'X':
j = cancel_job(ctx, optarg);
j = sinfonia_canceljob(&ctx->dev, atoi(optarg));
break;
default:
break; /* Ignore completely */
@ -1042,10 +688,11 @@ static int shinkos6245_attach(void *vctx, struct libusb_device_handle *dev, int
int num;
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->dev.dev = dev;
ctx->dev.endp_up = endp_up;
ctx->dev.endp_down = endp_down;
ctx->dev.type = type;
ctx->dev.error_codes = &error_codes;
/* Ensure jobid is sane */
ctx->jobid = jobid & 0x7f;
@ -1058,10 +705,10 @@ static int shinkos6245_attach(void *vctx, struct libusb_device_handle *dev, int
cmd.cmd = cpu_to_le16(SINFONIA_CMD_MEDIAINFO);
cmd.len = cpu_to_le16(0);
if (s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&ctx->media, sizeof(ctx->media),
&num)) {
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&ctx->media, sizeof(ctx->media),
&num)) {
return CUPS_BACKEND_FAILED;
}
@ -1104,7 +751,7 @@ static int shinkos6245_read_parse(void *vctx, const void **vjob, int data_fd, in
memset(job, 0, sizeof(*job));
/* Common read/parse code */
if (ctx->type == P_KODAK_8810) {
if (ctx->dev.type == P_KODAK_8810) {
ret = sinfonia_raw18_read_parse(data_fd, job);
} else {
ret = sinfonia_read_parse(data_fd, 6245, job);
@ -1193,10 +840,10 @@ static int shinkos6245_main_loop(void *vctx, const void *vjob) {
settime->month = cur->tm_mon;
settime->year = cur->tm_year + 1900 - 2000;
if ((ret = s6245_do_cmd(ctx,
cmdbuf, sizeof(*settime),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
cmdbuf, sizeof(*settime),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return CUPS_BACKEND_FAILED;
}
if (resp.result != RESULT_SUCCESS) {
@ -1218,10 +865,10 @@ top:
cmd->cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd->len = cpu_to_le16(0);
if ((ret = s6245_do_cmd(ctx,
cmdbuf, sizeof(*cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
cmdbuf, sizeof(*cmd),
(uint8_t*)&sts, sizeof(sts),
&num)) < 0) {
return CUPS_BACKEND_FAILED;
}
@ -1284,10 +931,10 @@ top:
print->mode = job->jp.oc_mode;
print->method = mcut;
if ((ret = s6245_do_cmd(ctx,
cmdbuf, sizeof(*print),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&ctx->dev,
cmdbuf, sizeof(*print),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -1303,7 +950,7 @@ top:
}
INFO("Sending image data to printer\n");
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->dev.dev, ctx->dev.endp_down,
job->databuf, job->datalen)))
return CUPS_BACKEND_FAILED;
@ -1348,7 +995,7 @@ static int shinkos6245_query_serno(struct libusb_device_handle *dev, uint8_t end
struct sinfonia_getserial_resp resp;
int ret, num = 0;
struct shinkos6245_ctx ctx = {
struct sinfonia_usbdev sdev = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
@ -1357,10 +1004,10 @@ static int shinkos6245_query_serno(struct libusb_device_handle *dev, uint8_t end
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSERIAL);
cmd.len = cpu_to_le16(0);
if ((ret = s6245_do_cmd(&ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
if ((ret = sinfonia_docmd(&sdev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
@ -1383,10 +1030,10 @@ static int shinkos6245_query_markers(void *vctx, struct marker **markers, int *c
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
if (s6245_do_cmd(ctx,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&status, sizeof(status),
&num)) {
if (sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&status, sizeof(status),
&num)) {
return CUPS_BACKEND_FAILED;
}
@ -1417,7 +1064,7 @@ static const char *shinkos6245_prefixes[] = {
struct dyesub_backend shinkos6245_backend = {
.name = "Shinko/Sinfonia CHC-S6245",
.version = "0.19WIP" " (lib " LIBSINFONIA_VER ")",
.version = "0.20WIP" " (lib " LIBSINFONIA_VER ")",
.uri_prefixes = shinkos6245_prefixes,
.cmdline_usage = shinkos6245_cmdline,
.cmdline_arg = shinkos6245_cmdline_arg,

View File

@ -270,6 +270,351 @@ void sinfonia_cleanup_job(const void *vjob)
free((void*)job);
}
int sinfonia_docmd(struct sinfonia_usbdev *usbh,
uint8_t *cmd, int cmdlen,
uint8_t *resp, int resplen,
int *num)
{
libusb_device_handle *dev = usbh->dev;
uint8_t endp_up = usbh->endp_up;
uint8_t endp_down = usbh->endp_down;
int ret;
struct sinfonia_cmd_hdr *cmdhdr = (struct sinfonia_cmd_hdr *) cmd;
struct sinfonia_status_hdr *resphdr = (struct sinfonia_status_hdr *)resp;
if ((ret = send_data(dev, endp_down,
cmd, cmdlen))) {
goto fail;
}
ret = read_data(dev, endp_up,
(uint8_t *)resp, resplen, num);
if (ret < 0)
goto fail;
if (resphdr->result != RESULT_SUCCESS) {
INFO("Printer Status: %02x (%s)\n", resphdr->status,
sinfonia_status_str(resphdr->status));
INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n",
resphdr->result, resphdr->error, resphdr->printer_major,
resphdr->printer_minor, usbh->error_codes(resphdr->printer_major, resphdr->printer_minor));
goto fail;
}
return 0;
fail:
ERROR("Failed to execute %s command\n", sinfonia_cmd_names(cmdhdr->cmd));
return ret;
}
int sinfonia_flashled(struct sinfonia_usbdev *usbh)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_FLASHLED);
cmd.len = cpu_to_le16(0);
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id)
{
struct sinfonia_cancel_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.id = id;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_CANCELJOB);
cmd.hdr.len = cpu_to_le16(1);
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param)
{
struct sinfonia_getparam_cmd cmd;
struct sinfonia_getparam_resp resp;
int ret, num = 0;
/* Set up command */
cmd.target = target;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_GETPARAM);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_getparam_cmd)-sizeof(cmd.hdr));
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
}
*param = le32_to_cpu(resp.param);
return ret;
}
int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param)
{
struct sinfonia_setparam_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
/* Set up command */
cmd.target = target;
cmd.param = cpu_to_le32(param);
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_SETPARAM);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_setparam_cmd)-sizeof(cmd.hdr));
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
}
return ret;
}
int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh)
{
struct sinfonia_fwinfo_cmd cmd;
struct sinfonia_fwinfo_resp resp;
int num = 0;
int i;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_FWINFO);
cmd.hdr.len = cpu_to_le16(1);
INFO("FW Information:\n");
for (i = FWINFO_TARGET_MAIN_BOOT ; i <= FWINFO_TARGET_PRINT_TABLES ; i++) {
int ret;
cmd.target = i;
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
continue;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_fwinfo_resp) - sizeof(struct sinfonia_status_hdr)))
continue;
INFO(" %s\t ver %02x.%02x\n", sinfonia_fwinfo_targets(i),
resp.major, resp.minor);
#if 0
INFO(" name: '%s'\n", resp.name);
INFO(" type: '%s'\n", resp.type);
INFO(" date: '%s'\n", resp.date);
INFO(" version: %02x.%02x (CRC %04x)\n", resp.major, resp.minor,
le16_to_cpu(resp.checksum));
#endif
}
return 0;
}
int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh)
{
struct sinfonia_cmd_hdr cmd;
struct sinfonia_errorlog_resp resp;
int ret, num = 0;
int i;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_ERRORLOG);
cmd.len = cpu_to_le16(0);
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
if (le16_to_cpu(resp.hdr.payload_len) != (sizeof(struct sinfonia_errorlog_resp) - sizeof(struct sinfonia_status_hdr)))
return -2;
INFO("Stored Error Events: %u entries:\n", resp.count);
for (i = 0 ; i < resp.count ; i++) {
INFO(" %02d: @ %08u prints : 0x%02x/0x%02x (%s)\n", i,
le32_to_cpu(resp.items[i].print_counter),
resp.items[i].major, resp.items[i].minor,
usbh->error_codes(resp.items[i].major, resp.items[i].minor));
}
return 0;
}
int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id)
{
struct sinfonia_reset_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
cmd.target = target;
cmd.curveid = id;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_RESET);
cmd.hdr.len = cpu_to_le16(2);
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
return 0;
}
int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname)
{
struct sinfonia_readtone_cmd cmd;
struct sinfonia_readtone_resp resp;
int ret, num = 0;
uint8_t *data;
uint16_t curves[TONE_CURVE_SIZE] = { 0 };
int i,j;
cmd.target = type;
cmd.curveid = TONE_CURVE_ID;
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_READTONE);
cmd.hdr.len = cpu_to_le16(1);
INFO("Dump %s Tone Curve to '%s'\n", sinfonia_tonecurve_statuses(type), fname);
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
resp.total_size = le16_to_cpu(resp.total_size);
data = malloc(resp.total_size * 2);
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
i = 0;
while (i < resp.total_size) {
ret = read_data(usbh->dev, usbh->endp_up,
data + i,
resp.total_size * 2 - i,
&num);
if (ret < 0)
goto done;
i += num;
}
i = j = 0;
while (i < resp.total_size) {
memcpy(curves + j, data + i+2, data[i+1]);
j += data[i+1] / 2;
i += data[i+1] + 2;
}
/* Open file and write it out */
{
int tc_fd = open(fname, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
if (tc_fd < 0) {
ret = -1;
goto done;
}
for (i = 0 ; i < TONE_CURVE_SIZE; i++) {
/* Byteswap appropriately */
curves[i] = cpu_to_be16(le16_to_cpu(curves[i]));
}
write(tc_fd, curves, TONE_CURVE_SIZE * sizeof(uint16_t));
close(tc_fd);
}
done:
free(data);
return ret;
}
int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname)
{
struct sinfonia_update_cmd cmd;
struct sinfonia_status_hdr resp;
int ret, num = 0;
INFO("Set %s Tone Curve from '%s'\n", sinfonia_update_targets(target), fname);
uint16_t *data = malloc(TONE_CURVE_SIZE * sizeof(uint16_t));
if (!data) {
ERROR("Memory Allocation Failure!\n");
return -1;
}
/* Read in file */
if ((ret = dyesub_read_file(fname, data, TONE_CURVE_SIZE * sizeof(uint16_t), NULL))) {
ERROR("Failed to read Tone Curve file\n");
goto done;
}
/* Byteswap data to local CPU.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = be16_to_cpu(data[ret]);
}
/* Set up command */
cmd.target = target;
cmd.curve_id = TONE_CURVE_ID;
cmd.reserved[0] = cmd.reserved[1] = cmd.reserved[2] = 0;
cmd.reset = 0;
cmd.size = cpu_to_le32(TONE_CURVE_SIZE * sizeof(uint16_t));
cmd.hdr.cmd = cpu_to_le16(SINFONIA_CMD_UPDATE);
cmd.hdr.len = cpu_to_le16(sizeof(struct sinfonia_update_cmd)-sizeof(cmd.hdr));
/* Byteswap data to format printer is expecting.. */
for (ret = 0; ret < TONE_CURVE_SIZE ; ret++) {
data[ret] = cpu_to_le16(data[ret]);
}
if ((ret = sinfonia_docmd(usbh,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)&resp, sizeof(resp),
&num)) < 0) {
return ret;
}
/* Sent transfer */
if ((ret = send_data(usbh->dev, usbh->endp_down,
(uint8_t *) data, TONE_CURVE_SIZE * sizeof(uint16_t)))) {
goto done;
}
done:
free(data);
return ret;
}
const char *sinfonia_update_targets (uint8_t v) {
switch (v) {
case UPDATE_TARGET_USER:
@ -362,6 +707,21 @@ const char *sinfonia_print_methods (uint8_t v) {
}
}
const char *sinfonia_fwinfo_targets (uint8_t v) {
switch (v) {
case FWINFO_TARGET_MAIN_BOOT:
return "Main Boot ";
case FWINFO_TARGET_MAIN_APP:
return "Main App ";
case FWINFO_TARGET_DSP:
return "DSP ";
case FWINFO_TARGET_PRINT_TABLES:
return "Print Tables";
default:
return "Unknown ";
}
}
const char *sinfonia_print_codes (uint8_t v, int eightinch) {
if (eightinch) {
switch (v) {

View File

@ -27,7 +27,7 @@
*
*/
#define LIBSINFONIA_VER "0.02"
#define LIBSINFONIA_VER "0.03"
#define SINFONIA_HDR1_LEN 0x10
#define SINFONIA_HDR2_LEN 0x64
@ -66,6 +66,29 @@ int sinfonia_raw10_read_parse(int data_fd, struct sinfonia_printjob *job);
int sinfonia_raw18_read_parse(int data_fd, struct sinfonia_printjob *job);
void sinfonia_cleanup_job(const void *vjob);
/* Common usb functions */
struct sinfonia_usbdev {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
char const *(*error_codes)(uint8_t major, uint8_t minor);
};
int sinfonia_docmd(struct sinfonia_usbdev *usbh,
uint8_t *cmd, int cmdlen,
uint8_t *resp, int resplen,
int *num);
int sinfonia_flashled(struct sinfonia_usbdev *usbh);
int sinfonia_canceljob(struct sinfonia_usbdev *usbh, int id);
int sinfonia_getparam(struct sinfonia_usbdev *usbh, int target, uint32_t *param);
int sinfonia_setparam(struct sinfonia_usbdev *usbh, int target, uint32_t param);
int sinfonia_getfwinfo(struct sinfonia_usbdev *usbh);
int sinfonia_geterrorlog(struct sinfonia_usbdev *usbh);
int sinfonia_resetcurve(struct sinfonia_usbdev *usbh, int target, int id);
int sinfonia_gettonecurve(struct sinfonia_usbdev *usbh, int type, char *fname);
int sinfonia_settonecurve(struct sinfonia_usbdev *usbh, int target, char *fname);
#define BANK_STATUS_FREE 0x00
#define BANK_STATUS_XFER 0x01
#define BANK_STATUS_FULL 0x02
@ -73,7 +96,6 @@ void sinfonia_cleanup_job(const void *vjob);
const char *sinfonia_bank_statuses(uint8_t v);
#define UPDATE_TARGET_USER 0x03
#define UPDATE_TARGET_CURRENT 0x04
@ -124,6 +146,13 @@ const char *sinfonia_media_types(uint8_t v);
const char *sinfonia_print_methods (uint8_t v);
#define FWINFO_TARGET_MAIN_BOOT 0x01
#define FWINFO_TARGET_MAIN_APP 0x02
#define FWINFO_TARGET_PRINT_TABLES 0x03
#define FWINFO_TARGET_DSP 0x04
const char *sinfonia_fwinfo_targets (uint8_t v);
/* Common command structs */
struct sinfonia_cmd_hdr {
uint16_t cmd;
@ -212,6 +241,40 @@ struct sinfonia_getprintidstatus_resp {
#define IDSTATUS_COMPLETED 0x0200
#define IDSTATUS_ERROR 0xFFFF
struct sinfonia_reset_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define RESET_PRINTER 0x03
#define RESET_TONE_CURVE 0x04
#define TONE_CURVE_ID 0x01
struct sinfonia_readtone_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curveid;
} __attribute__((packed));
#define READ_TONE_CURVE_USER 0x01
#define READ_TONE_CURVE_CURR 0x02
struct sinfonia_readtone_resp {
struct sinfonia_status_hdr hdr;
uint16_t total_size;
} __attribute__((packed));
struct sinfonia_update_cmd {
struct sinfonia_cmd_hdr hdr;
uint8_t target;
uint8_t curve_id;
uint8_t reset; // ??
uint8_t reserved[3];
uint32_t size;
} __attribute__((packed));
struct sinfonia_getserial_resp {
struct sinfonia_status_hdr hdr;
uint8_t data[8];