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.
master
Solomon Peachy 4 years ago
parent 401f43f682
commit d72a4702c6
  1. 13
      README
  2. 294
      backend_kodak605.c
  3. 198
      backend_shinkos2145.c
  4. 553
      backend_shinkos6145.c
  5. 467
      backend_shinkos6245.c
  6. 360
      backend_sinfonia.c
  7. 67
      backend_sinfonia.h

@ -465,10 +465,17 @@
Valid commands:
-C filename Set tone curve [1]
-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
-e Query error log
-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

@ -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))))
return ret;
cmd.cmd = cpu_to_le16(SINFONIA_CMD_GETSTATUS);
cmd.len = cpu_to_le16(0);
/* Read in the printer status */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) sts, sizeof(*sts), &num);
if (ret < 0)
if ((ret = sinfonia_docmd(&ctx->dev,
(uint8_t*)&cmd, sizeof(cmd),
(uint8_t*)sts, sizeof(*sts), &num)) < 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,

@ -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,

@ -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);