mitsu9550: Rejigger it to handle the 9600 and 98x0 variations.

This is strictly limited to the job parsing and sanity code.
It is unknown if there are runtime differences.
This commit is contained in:
Solomon Peachy 2016-10-13 08:12:20 -04:00
parent 691c406714
commit 6362d358e7
2 changed files with 163 additions and 79 deletions

View File

@ -110,9 +110,9 @@ enum {
P_MITSU_D70X,
P_MITSU_D80,
P_MITSU_K60,
P_MITSU_9550,
P_MITSU_9xxx,
P_MITSU_9550S,
P_MITSU_9600,
P_MITSU_98x0,
P_DNP_DS40,
P_DNP_DS80,
P_DNP_DS80D,

View File

@ -43,30 +43,12 @@
#define USB_PID_MITSU_9550D 0x03A1
#define USB_PID_MITSU_9550DS 0x03A5 // or DZ/DZS/DZU
#define USB_PID_MITSU_9600D 0x03A9
//#define USB_PID_MITSU_9600DS XXXXXX
//#define USB_PID_MITSU_9800D XXXXXX
//#define USB_PID_MITSU_9800DS XXXXXX
//#define USB_PID_MITSU_9810D XXXXXX
//#define USB_PID_MITSU_9810DS XXXXXX
/* Private data stucture */
struct mitsu9550_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
uint8_t *databuf;
int datalen;
int is_s_variant;
uint16_t rows;
uint16_t cols;
uint16_t last_donor;
uint16_t last_remain;
int marker_reported;
};
/* Spool file structures */
/* Print parameters1 */
@ -105,6 +87,7 @@ struct mitsu9550_hdr4 {
uint8_t unk[46]; /* 00 70 00 00 00 00 00 00 01 01 00 [...] */
} __attribute__((packed));
/* Data plane header */
struct mitsu9550_plane {
uint8_t cmd[4]; /* 1b 5a 54 00 */
uint8_t null[2];
@ -117,6 +100,35 @@ struct mitsu9550_cmd {
uint8_t cmd[4];
} __attribute__((packed));
/* Private data stucture */
struct mitsu9550_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
uint8_t *databuf;
uint32_t datalen;
uint16_t rows;
uint16_t cols;
uint32_t plane_len;
uint16_t last_donor;
uint16_t last_remain;
int marker_reported;
/* Parse headers separately */
struct mitsu9550_hdr1 hdr1;
int hdr1_present;
struct mitsu9550_hdr2 hdr2;
int hdr2_present;
struct mitsu9550_hdr3 hdr3;
int hdr3_present;
struct mitsu9550_hdr4 hdr4;
int hdr4_present;
};
/* Printer data structures */
struct mitsu9550_media {
uint8_t hdr[2]; /* 24 2e */
@ -260,7 +272,7 @@ static void mitsu9550_teardown(void *vctx) {
static int mitsu9550_read_parse(void *vctx, int data_fd) {
struct mitsu9550_ctx *ctx = vctx;
struct mitsu9550_hdr1 hdr;
uint8_t buf[sizeof(struct mitsu9550_hdr1)];
int remain, i;
@ -272,10 +284,16 @@ static int mitsu9550_read_parse(void *vctx, int data_fd) {
ctx->databuf = NULL;
}
ctx->hdr1_present = 0;
ctx->hdr2_present = 0;
ctx->hdr3_present = 0;
ctx->hdr4_present = 0;
top:
/* Read in initial header */
remain = sizeof(hdr);
remain = sizeof(buf);
while (remain > 0) {
i = read(data_fd, ((uint8_t*)&hdr) + sizeof(hdr) - remain, remain);
i = read(data_fd, buf + sizeof(buf) - remain, remain);
if (i == 0)
return CUPS_BACKEND_CANCEL;
if (i < 0)
@ -284,31 +302,73 @@ static int mitsu9550_read_parse(void *vctx, int data_fd) {
}
/* Sanity check */
if (hdr.cmd[0] != 0x1b ||
hdr.cmd[1] != 0x57 ||
hdr.cmd[2] != 0x20 ||
hdr.cmd[3] != 0x2e) {
ERROR("Unrecognized data format!\n");
if (buf[0] != 0x1b || buf[1] != 0x57 || buf[3] != 0x2e) {
if (!ctx->hdr1_present || !ctx->hdr2_present) {
ERROR("Unrecognized data format!\n");
return CUPS_BACKEND_CANCEL;
} else if (buf[0] == 0x1b && buf[1] == 0x57 &&
buf[2] == 0x54 && buf[3] == 0x00) {
/* We've hit the data portion */
goto hdr_done;
} else {
ERROR("Unrecognized data format!\n");
return CUPS_BACKEND_CANCEL;
}
}
switch(buf[2]) {
case 0x20: /* header 1 */
memcpy(&ctx->hdr1, buf, sizeof(ctx->hdr1));
ctx->hdr1_present = 1;
break;
case 0x21: /* header 2 */
memcpy(&ctx->hdr2, buf, sizeof(ctx->hdr2));
ctx->hdr2_present = 1;
break;
case 0x22: /* header 3 */
memcpy(&ctx->hdr3, buf, sizeof(ctx->hdr3));
ctx->hdr3_present = 1;
break;
case 0x26: /* header 4 */
memcpy(&ctx->hdr4, buf, sizeof(ctx->hdr4));
ctx->hdr4_present = 1;
break;
default:
ERROR("Unrecognized header format (%02x)!\n", buf[2]);
return CUPS_BACKEND_CANCEL;
}
/* Work out printjob size */
ctx->rows = be16_to_cpu(hdr.rows);
ctx->cols = be16_to_cpu(hdr.cols);
/* Read in the next chunk */
goto top;
remain = ctx->rows * ctx->cols + sizeof(struct mitsu9550_plane);
remain *= 3;
remain += sizeof(struct mitsu9550_hdr2) + sizeof(struct mitsu9550_hdr3)+ sizeof(struct mitsu9550_hdr4) + sizeof(struct mitsu9550_cmd);
hdr_done:
/* Work out printjob size */
ctx->rows = be16_to_cpu(ctx->hdr1.rows);
ctx->cols = be16_to_cpu(ctx->hdr1.cols);
ctx->plane_len = ctx->rows * ctx->cols;
if (ctx->type == P_MITSU_98x0)
ctx->plane_len *= 2;
/* We have three planes and the final command to read */
remain = 3 * (ctx->plane_len + sizeof(struct mitsu9550_plane)) + sizeof(struct mitsu9550_cmd);
/* On the 9810, don't forget the matte plane! */
if (ctx->hdr1.matte) {
remain += ctx->plane_len + sizeof(struct mitsu9550_plane) + sizeof(struct mitsu9550_cmd);
}
/* Allocate buffer */
ctx->databuf = malloc(remain + sizeof(struct mitsu9550_hdr1));
ctx->databuf = malloc(remain);
if (!ctx->databuf) {
ERROR("Memory allocation failure!\n");
return CUPS_BACKEND_FAILED;
}
memcpy(ctx->databuf, &hdr, sizeof(struct mitsu9550_hdr1));
ctx->datalen = sizeof(struct mitsu9550_hdr1);
/* Copy over first chunk into buffer */
memcpy(ctx->databuf, buf, sizeof(buf));
ctx->datalen = sizeof(buf);
/* Read in the spool data */
while(remain) {
@ -321,6 +381,13 @@ static int mitsu9550_read_parse(void *vctx, int data_fd) {
remain -= i;
}
/* Finally, 9550-S doesn't sent over hdr4! */
if (ctx->type == P_MITSU_9550S) {
/* XXX Has to do with error policy, but not sure what. Mitsu9550-S will set this
based on a command, but it's not part of the standard job spool */
ctx->hdr4_present = 0;
}
return CUPS_BACKEND_OK;
}
@ -417,7 +484,6 @@ static int validate_media(int type, int cols, int rows) {
static int mitsu9550_main_loop(void *vctx, int copies) {
struct mitsu9550_ctx *ctx = vctx;
struct mitsu9550_hdr2 *hdr2;
struct mitsu9550_cmd cmd;
uint8_t rdbuf[READBACK_LEN];
uint8_t *ptr;
@ -428,9 +494,9 @@ static int mitsu9550_main_loop(void *vctx, int copies) {
return CUPS_BACKEND_FAILED;
/* Update printjob header to reflect number of requested copies */
hdr2 = (struct mitsu9550_hdr2 *) (ctx->databuf + sizeof(struct mitsu9550_hdr1));
hdr2->copies = cpu_to_be16(copies);
ctx->hdr2.copies = cpu_to_be16(copies);
/* Okay, let's do this thing */
ptr = ctx->databuf;
top:
@ -479,25 +545,22 @@ top:
QUERY_STATUS();
/* Send printjob headers from spool data */
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_hdr1))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_hdr1);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_hdr2))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_hdr2);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_hdr3))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_hdr3);
if (ctx->type != P_MITSU_9550S) {
// XXX need to investigate what hdr4 is about
if (ctx->hdr1_present)
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_hdr4))))
(uint8_t*) &ctx->hdr1, sizeof(ctx->hdr1))))
return CUPS_BACKEND_FAILED;
if (ctx->hdr2_present)
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) &ctx->hdr2, sizeof(ctx->hdr2))))
return CUPS_BACKEND_FAILED;
if (ctx->hdr3_present)
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) &ctx->hdr3, sizeof(ctx->hdr3))))
return CUPS_BACKEND_FAILED;
if (ctx->hdr4_present)
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) &ctx->hdr4, sizeof(struct mitsu9550_hdr4))))
return CUPS_BACKEND_FAILED;
}
ptr += sizeof(struct mitsu9550_hdr4);
if (ctx->type == P_MITSU_9550S) {
/* Send "start data" command */
@ -510,34 +573,34 @@ top:
(uint8_t*) &cmd, sizeof(cmd))))
return CUPS_BACKEND_FAILED;
}
/* Send plane data */
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_plane))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_plane);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, ctx->rows * ctx->cols)))
(uint8_t*) ptr, ctx->plane_len)))
return CUPS_BACKEND_FAILED;
ptr += ctx->rows * ctx->cols;
ptr += ctx->plane_len;
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_plane))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_plane);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, ctx->rows * ctx->cols)))
(uint8_t*) ptr, ctx->plane_len)))
return CUPS_BACKEND_FAILED;
ptr += ctx->rows * ctx->cols;
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_plane))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_plane);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, ctx->rows * ctx->cols)))
return CUPS_BACKEND_FAILED;
ptr += ctx->rows * ctx->cols;
ptr += ctx->plane_len;
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_plane))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_plane);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, ctx->plane_len)))
return CUPS_BACKEND_FAILED;
ptr += ctx->plane_len;
/* Query statuses */
{
@ -603,6 +666,25 @@ top:
ptr += sizeof(cmd);
}
/* Don't forget the 9810's matte plane */
if (ctx->hdr1.matte) {
// XXX include a status loop here too?
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, sizeof(struct mitsu9550_plane))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(struct mitsu9550_plane);
if ((ret = send_data(ctx->dev, ctx->endp_down,
(uint8_t*) ptr, ctx->plane_len)))
return CUPS_BACKEND_FAILED;
ptr += ctx->plane_len;
/* Send "lamination end data" command from spool file */
if ((ret = send_data(ctx->dev, ctx->endp_down,
ptr, sizeof(cmd))))
return CUPS_BACKEND_FAILED;
ptr += sizeof(cmd);
}
/* Status loop, run until printer reports completion */
while(1) {
struct mitsu9550_status *sts = (struct mitsu9550_status*) rdbuf;
@ -794,8 +876,8 @@ static int mitsu9550_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend mitsu9550_backend = {
.name = "Mitsubishi CP-9550DW-S",
.version = "0.17",
.name = "Mitsubishi CP-9550 family",
.version = "0.18",
.uri_prefix = "mitsu9550",
.cmdline_usage = mitsu9550_cmdline,
.cmdline_arg = mitsu9550_cmdline_arg,
@ -806,12 +888,14 @@ struct dyesub_backend mitsu9550_backend = {
.main_loop = mitsu9550_main_loop,
.query_serno = mitsu9550_query_serno,
.devices = {
{ USB_VID_MITSU, USB_PID_MITSU_9550D, P_MITSU_9550, ""},
{ USB_VID_MITSU, USB_PID_MITSU_9550D, P_MITSU_9xxx, ""},
{ USB_VID_MITSU, USB_PID_MITSU_9550DS, P_MITSU_9550S, ""},
{ USB_VID_MITSU, USB_PID_MITSU_9600D, P_MITSU_9600, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9800D, P_MITSU_9800, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9810D, P_MITSU_9810, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9810DS, P_MITSU_9810S, ""},
{ USB_VID_MITSU, USB_PID_MITSU_9600D, P_MITSU_9xxx, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9600D, P_MITSU_9600S, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9800D, P_MITSU_98x0, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9800DS, P_MITSU_98x0S, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9810D, P_MITSU_98x0, ""},
// { USB_VID_MITSU, USB_PID_MITSU_9810DS, P_MITSU_98x0S, ""},
{ 0, 0, 0, ""}
}
};