static SANE_Status usb_send_command (struct scanner *s, struct cmd *c, struct response *r, void *buf) { SANE_Status st; struct bulk_header *h = (struct bulk_header *) buf; u8 resp[sizeof (*h) + STATUS_SIZE]; size_t sz = sizeof (*h) + MAX_CMD_SIZE; memset (h, 0, sz); h->length = cpu2be32 (sz); h->type = cpu2be16 (COMMAND_BLOCK); h->code = cpu2be16 (COMMAND_CODE); memcpy (h + 1, c->cmd, c->cmd_size); st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz); if (st) return st; if (sz != sizeof (*h) + MAX_CMD_SIZE) return SANE_STATUS_IO_ERROR; if (c->dir == CMD_IN) { sz = sizeof (*h) + c->data_size; st = sanei_usb_read_bulk (s->file, (SANE_Byte *) h, &sz); c->data = h + 1; c->data_size = sz - sizeof (*h); if (st || sz < sizeof (*h)) { st = sanei_usb_release_interface (s->file, 0); if (st) return st; st = sanei_usb_claim_interface (s->file, 0); if (st) return st; r->status = CHECK_CONDITION; return SANE_STATUS_GOOD; } } else if (c->dir == CMD_OUT) { sz = sizeof (*h) + c->data_size; memset (h, 0, sizeof (*h)); h->length = cpu2be32 (sizeof (*h) + c->data_size); h->type = cpu2be16 (DATA_BLOCK); h->code = cpu2be16 (DATA_CODE); memcpy (h + 1, c->data, c->data_size); st = sanei_usb_write_bulk (s->file, (const SANE_Byte *) h, &sz); if (st) return st; } sz = sizeof (resp); st = sanei_usb_read_bulk (s->file, resp, &sz); if (st || sz != sizeof (resp)) return SANE_STATUS_IO_ERROR; r->status = be2cpu32 (*((u32 *) (resp + sizeof (*h)))); return st; }
/** * read available data count from scanner * from tests it appears that advertised data * may not be really available, and that a pause must be made * before reading data so that it is really there. * Such as reading data twice. */ SANE_Status sanei_rts88xx_data_count (SANE_Int devnum, SANE_Word * count) { SANE_Status status; size_t size; static SANE_Byte header[4] = { 0x90, 0x00, 0x00, 3 }; SANE_Byte result[3]; /* set count in case of failure */ *count = 0; size = 4; status = sanei_usb_write_bulk (devnum, header, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_data_count : failed to write header\n"); return status; } size = 3; status = sanei_usb_read_bulk (devnum, result, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_data_count : failed to read data count\n"); return status; } *count = result[0] + (result[1] << 8) + (result[2] << 16); DBG (DBG_io2, "sanei_rts88xx_data_count: %d bytes available (0x%06x)\n", *count, *count); return status; }
int usb_dev_request (struct device *dev, SANE_Byte *cmd, size_t cmdlen, SANE_Byte *resp, size_t *resplen) { SANE_Status status; size_t len = cmdlen; if (cmd && cmdlen) { status = sanei_usb_write_bulk (dev->dn, cmd, &cmdlen); if (status != SANE_STATUS_GOOD) { DBG (1, "%s: sanei_usb_write_bulk: %s\n", __FUNCTION__, sane_strstatus (status)); return SANE_STATUS_IO_ERROR; } if (cmdlen != len) { DBG (1, "%s: sanei_usb_write_bulk: wanted %lu bytes, wrote %lu bytes\n", __FUNCTION__, (size_t)len, (size_t)cmdlen); return SANE_STATUS_IO_ERROR; } } if (resp && resplen) { status = sanei_usb_read_bulk (dev->dn, resp, resplen); if (status != SANE_STATUS_GOOD) { DBG (1, "%s: sanei_usb_read_bulk: %s\n", __FUNCTION__, sane_strstatus (status)); return SANE_STATUS_IO_ERROR; } } return SANE_STATUS_GOOD; }
/* * read one register at given index */ SANE_Status sanei_rts88xx_read_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg) { SANE_Status status = SANE_STATUS_GOOD; unsigned char cmd[] = { 0x80, 0x00, 0x00, 0x01 }; size_t size; cmd[1] = index; size = 4; status = sanei_usb_write_bulk (devnum, cmd, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_reg: bulk write failed\n"); return status; } size = 1; status = sanei_usb_read_bulk (devnum, reg, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_reg: bulk read failed\n"); return status; } DBG (DBG_io2, "sanei_rts88xx_read_reg: reg[0x%02x]=0x%02x\n", index, *reg); return status; }
static void send_conf (struct device_s *dev) { int y1, y2, x1, x2; size_t size = 100; DBG(100,"Sending configuration packet on device %s\n",dev->devname); y1 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H); y2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H); x1 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S)) * MAX_X_H); x2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S)) * MAX_X_H); DBG(100,"\t x1: %d, x2: %d, y1: %d, y2: %d\n",x1, x2, y1, y2); DBG(100,"\t brightness: %d, contrast: %d\n", dev->optionw[BRIGH_OFFSET], dev->optionw[CONTR_OFFSET]); DBG(100,"\t resolution: %d\n",dev->optionw[RES_OFFSET]); dev->conf_data[0] = htonl (0x15); dev->conf_data[1] = htonl (dev->optionw[BRIGH_OFFSET]); dev->conf_data[2] = htonl (dev->optionw[CONTR_OFFSET]); dev->conf_data[3] = htonl (dev->optionw[RES_OFFSET]); dev->conf_data[4] = htonl (0x1); dev->conf_data[5] = htonl (0x1); dev->conf_data[6] = htonl (0x1); dev->conf_data[7] = htonl (0x1); dev->conf_data[8] = 0; dev->conf_data[9] = 0; dev->conf_data[10] = htonl (0x8); dev->conf_data[11] = 0; dev->conf_data[12] = 0; dev->conf_data[13] = 0; dev->conf_data[14] = 0; dev->conf_data[16] = htonl (y1); dev->conf_data[17] = htonl (x1); dev->conf_data[18] = htonl (y2); dev->conf_data[19] = htonl (x2); dev->conf_data[20] = 0; dev->conf_data[21] = 0; dev->conf_data[22] = htonl (0x491); dev->conf_data[23] = htonl (0x352); if (dev->optionw[COLOR_OFFSET] == RGB) { dev->conf_data[15] = htonl (0x2); dev->conf_data[24] = htonl (0x1); DBG(100,"\t Scanning in RGB format\n"); } else { dev->conf_data[15] = htonl (0x6); dev->conf_data[24] = htonl (0x0); DBG(100,"\t Scanning in Grayscale format\n"); } sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); }
static void send_pkt (int command, int data_size, struct device_s *dev) { size_t size = 32; DBG(100,"Sending packet %d, next data size %d, device %s\n", command, data_size, dev->devname); memset (dev->packet_data, 0, size); dev->packet_data[0] = htonl (MAGIC_NUMBER); dev->packet_data[1] = htonl (command); dev->packet_data[5] = htonl (data_size); sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->packet_data, &size); }
/* read several registers starting at the given index */ SANE_Status sanei_rts88xx_read_regs (SANE_Int devnum, SANE_Int start, SANE_Byte * dest, SANE_Int length) { SANE_Status status; static SANE_Byte command_block[] = { 0x80, 0, 0x00, 0xFF }; size_t size, i; char message[256 * 5]; if (start + length > 255) { DBG (DBG_error, "sanei_rts88xx_read_regs: start and length must be within [0..255]\n"); return SANE_STATUS_INVAL; } /* write header */ size = 4; command_block[1] = start; command_block[3] = length; status = sanei_usb_write_bulk (devnum, command_block, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_regs: failed to write header\n"); return status; } /* read data */ size = length; status = sanei_usb_read_bulk (devnum, dest, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_regs: failed to read data\n"); return status; } if (size != (size_t) length) { DBG (DBG_warn, "sanei_rts88xx_read_regs: read got only %lu bytes\n", (u_long) size); } if (DBG_LEVEL >= DBG_io) { for (i = 0; i < size; i++) sprintf (message + 5 * i, "0x%02x ", dest[i]); DBG (DBG_io, "sanei_rts88xx_read_regs: read_regs(0x%02x,%d)=%s\n", start, length, message); } return status; }
/* * read length bytes of memory into area pointed by value */ SANE_Status sanei_rts88xx_read_mem (SANE_Int devnum, SANE_Int length, SANE_Byte * value) { SANE_Status status; size_t size, read, want; SANE_Byte header[4]; /* build and write length header */ header[0] = 0x81; header[1] = 0x00; header[2] = HIBYTE (length); header[3] = LOBYTE (length); size = 4; status = sanei_usb_write_bulk (devnum, header, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_mem: failed to write length header\n"); return status; } DBG (DBG_io, "sanei_rts88xx_read_mem: %02x %02x %02x %02x -> ...\n", header[0], header[1], header[2], header[3]); read = 0; while (length > 0) { if (length > 2048) want = 2048; else want = length; size = want; status = sanei_usb_read_bulk (devnum, value + read, &size); if (size != want) { DBG (DBG_error, "sanei_rts88xx_read_mem: only read %lu bytes out of %lu\n", (u_long) size, (u_long) want); status = SANE_STATUS_IO_ERROR; } length -= size; read += size; } return status; }
static ssize_t channel_usb_send (channel *self, const void *buffer, size_t size, SANE_Status *status) { ssize_t n = size; if (self->interpreter) { n = self->interpreter->send (self, buffer, size, status); } else { SANE_Status s; s = sanei_usb_write_bulk (self->fd, buffer, (size_t *)&n); if (status) *status = s; } return n; }
/* * write the given number of bytes pointed by value into memory * length is payload length * extra is number of bytes to add to the usb write length */ SANE_Status sanei_rts88xx_write_mem (SANE_Int devnum, SANE_Int length, SANE_Int extra, SANE_Byte * value) { SANE_Status status; SANE_Byte *buffer; size_t i, size; char message[(0xFFC0 + 10) * 3] = ""; buffer = (SANE_Byte *) malloc (length + 10); memset (buffer, 0, length + 10); if (buffer == NULL) return SANE_STATUS_NO_MEM; buffer[0] = 0x89; buffer[1] = 0x00; buffer[2] = HIBYTE (length); buffer[3] = LOBYTE (length); for (i = 0; i < (size_t) length; i++) { buffer[i + 4] = value[i]; if (DBG_LEVEL > DBG_io2) { sprintf (message + 3 * i, "%02x ", buffer[i + 4]); } } DBG (DBG_io, "sanei_rts88xx_write_mem: %02x %02x %02x %02x -> %s\n", buffer[0], buffer[1], buffer[2], buffer[3], message); size = length + 4 + extra; status = sanei_usb_write_bulk (devnum, buffer, &size); free (buffer); if ((status == SANE_STATUS_GOOD) && (size != (size_t) length + 4 + extra)) { DBG (DBG_error, "sanei_rts88xx_write_mem: only wrote %lu bytes out of %d\n", (u_long) size, length + 4); status = SANE_STATUS_IO_ERROR; } return status; }
/* * write to the nvram controler */ SANE_Status sanei_rts88xx_nvram_ctrl (SANE_Int devnum, SANE_Int length, SANE_Byte * value) { SANE_Status status = SANE_STATUS_GOOD; SANE_Int size = 0; SANE_Int i; SANE_Byte buffer[60]; char message[60 * 5]; if (DBG_LEVEL > DBG_io) { for (i = 0; i < length; i++) { sprintf (message + 5 * i, "0x%02x ", value[i]); } DBG (DBG_io, "sanei_rts88xx_nvram_ctrl : nvram_ctrl(0x00,%d)=%s\n", length, message); } buffer[0] = 0x8a; buffer[1] = 0x00; buffer[2] = 0x00; buffer[3] = length; for (i = 0; i < size; i++) buffer[i + 4] = value[i]; /* the USB block is size + 4 bytes of header long */ size = length + 4; #ifdef HAZARDOUS_EXPERIMENT status = sanei_usb_write_bulk (devnum, buffer, &size); #else devnum = devnum; status = SANE_STATUS_GOOD; #endif if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_nvram_ctrl : write failed ...\n"); } return status; }
/* * read scanned data from scanner up to the size given. The actual length read is returned. */ SANE_Status sanei_rts88xx_read_data (SANE_Int devnum, SANE_Word * length, unsigned char *dest) { SANE_Status status = SANE_STATUS_GOOD; SANE_Byte header[4]; size_t size, len, remain, read; /* do not read too much data */ if (*length > RTS88XX_MAX_XFER_SIZE) len = RTS88XX_MAX_XFER_SIZE; else len = *length; /* write command header first */ header[0] = 0x91; header[1] = 0x00; header[2] = HIBYTE (len); header[3] = LOBYTE (len); size = 4; status = sanei_usb_write_bulk (devnum, header, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_data: failed to write header\n"); } read = 0; /* first read blocks aligned on 64 bytes boundary */ while (len - read > 64) { size = (len - read) & 0xFFC0; status = sanei_usb_read_bulk (devnum, dest + read, &size); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n"); return status; } DBG (DBG_io2, "sanei_rts88xx_read_data: read %lu bytes\n", (u_long) size); read += size; } /* then read remainder */ remain = len - read; if (remain > 0) { status = sanei_usb_read_bulk (devnum, dest + read, &remain); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n"); return status; } DBG (DBG_io2, "sanei_rts88xx_read_data: read %lu bytes\n", (u_long) remain); read += remain; } /* update actual read length */ DBG (DBG_io, "sanei_rts88xx_read_data: read %lu bytes, %d required\n", (u_long) read, *length); *length = read; return status; }
/* * write length consecutive registers, starting at index * register 0xb3 is never wrote in bulk register write, so we split * write if it belongs to the register set sent */ SANE_Status sanei_rts88xx_write_regs (SANE_Int devnum, SANE_Int start, SANE_Byte * source, SANE_Int length) { size_t size = 0; size_t i; SANE_Byte buffer[260]; char message[256 * 5]; if (DBG_LEVEL > DBG_io) { for (i = 0; i < (size_t) length; i++) { sprintf (message + 5 * i, "0x%02x ", source[i]); } DBG (DBG_io, "sanei_rts88xx_write_regs : write_regs(0x%02x,%d)=%s\n", start, length, message); } /* when writing several registers at a time, we avoid writing the 0xb3 register * which is used to control the status of the scanner */ if ((start + length > 0xb3) && (length > 1)) { size = 0xb3 - start; buffer[0] = 0x88; buffer[1] = start; buffer[2] = 0x00; buffer[3] = size; for (i = 0; i < size; i++) buffer[i + 4] = source[i]; /* the USB block is size + 4 bytes of header long */ size += 4; if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_write_regs : write registers part 1 failed ...\n"); return SANE_STATUS_IO_ERROR; } /* skip 0xb3 register */ size -= 3; start = 0xb4; source = source + size; } size = length - size; buffer[0] = 0x88; buffer[1] = start; buffer[2] = 0x00; buffer[3] = size; for (i = 0; i < size; i++) buffer[i + 4] = source[i]; /* the USB block is size + 4 bytes of header long */ size += 4; if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD) { DBG (DBG_error, "sanei_rts88xx_write_regs : write registers part 2 failed ...\n"); return SANE_STATUS_IO_ERROR; } return SANE_STATUS_GOOD; }
/******************************************************************************* * USB-in-USB: bulk write * * Parameters * dn - sanei_usb device descriptor * cmd - command for bulk write operation * bytes - pointer to data buffer * size - size of data * * Returns * SANE_STATUS_GOOD - all data transferred successfully * all other SANE_Status value - otherwise */ static SANE_Status hp5590_bulk_write (SANE_Int dn, enum proto_flags proto_flags, int cmd, unsigned char *bytes, unsigned int size) { struct usb_in_usb_bulk_setup ctrl; SANE_Status ret; struct bulk_size bulk_size; unsigned int len; unsigned char *ptr; size_t next_portion; DBG (3, "%s: USB-in-USB: command: %04x, size %u\n", __func__, cmd, size); hp5590_low_assert (bytes != NULL); /* Prepare bulk write request */ memset (&bulk_size, 0, sizeof (bulk_size)); /* Counted in page size */ bulk_size.size = size / BULK_WRITE_PAGE_SIZE; /* Send bulk write request */ DBG (3, "%s: USB-in-USB: total %u pages (each of %u bytes)\n", __func__, bulk_size.size, BULK_WRITE_PAGE_SIZE); ret = hp5590_control_msg (dn, proto_flags, USB_DIR_OUT, 0x04, cmd, 0, (unsigned char *) &bulk_size, sizeof (bulk_size), CORE_DATA | CORE_BULK_OUT); if (ret != SANE_STATUS_GOOD) return ret; len = size; ptr = bytes; /* Send all data in pages */ while (len) { next_portion = BULK_WRITE_PAGE_SIZE; if (len < next_portion) next_portion = len; DBG (3, "%s: USB-in-USB: next portion %lu bytes\n", __func__, (u_long) next_portion); /* Prepare bulk write request */ memset (&ctrl, 0, sizeof (ctrl)); ctrl.bRequestType = 0x01; ctrl.bEndpoint = 0x82; ctrl.wLength = htons (next_portion); /* Send bulk write request */ ret = sanei_usb_control_msg (dn, USB_DIR_OUT | USB_TYPE_VENDOR, 0x04, 0x82, 0, sizeof (ctrl), (unsigned char *) &ctrl); if (ret != SANE_STATUS_GOOD) return ret; /* USB-in-USB: checking if command was accepted */ ret = hp5590_get_ack (dn, proto_flags); if (ret != SANE_STATUS_GOOD) return ret; /* Write bulk data */ DBG (3, "%s: USB-in-USB: bulk writing %lu bytes\n", __func__, (u_long) next_portion); ret = sanei_usb_write_bulk (dn, ptr, &next_portion); if (ret != SANE_STATUS_GOOD) { /* Treast EOF as successful result */ if (ret == SANE_STATUS_EOF) break; DBG (DBG_err, "%s: USB-in-USB: error during bulk write: %s\n", __func__, sane_strstatus (ret)); return ret; } /* Move to the next page */ len -= next_portion; ptr += next_portion; } /* Verify bulk command */ return hp5590_verify_last_cmd (dn, proto_flags, cmd); }
/* write all registers, taking care of the special 0xaa value which * must be escaped with a zero */ static SANE_Status rts8891_write_all (SANE_Int devnum, SANE_Byte * regs, SANE_Int count) { SANE_Status status = SANE_STATUS_GOOD; SANE_Byte local_regs[RTS8891_MAX_REGISTERS]; size_t size = 0; SANE_Byte buffer[260]; unsigned int i, j; char message[256 * 5]; if (DBG_LEVEL > DBG_io) { for (i = 0; i < (unsigned int) count; i++) { if (i != 0xb3) sprintf (message + 5 * i, "0x%02x ", regs[i]); else sprintf (message + 5 * i, "---- "); } DBG (DBG_io, "rts8891_write_all : write_all(0x00,%d)=%s\n", count, message); } /* copy register set and escaping 0xaa values */ /* b0, b1 abd b3 values may be scribled, but that isn't important */ /* since they are read-only registers */ j = 0; for (i = 0; i < 0xb3; i++) { local_regs[j] = regs[i]; if (local_regs[j] == 0xaa && i < 0xb3) { j++; local_regs[j] = 0x00; } j++; } buffer[0] = 0x88; buffer[1] = 0; buffer[2] = 0x00; buffer[3] = 0xb3; for (i = 0; i < j; i++) buffer[i + 4] = local_regs[i]; /* the USB block is size + 4 bytes of header long */ size = j + 4; if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD) { DBG (DBG_error, "rts88xx_write_all : write registers part 1 failed ...\n"); return SANE_STATUS_IO_ERROR; } size = count - 0xb4; /* we need to substract one reg since b3 won't be written */ buffer[0] = 0x88; buffer[1] = 0xb4; buffer[2] = 0x00; buffer[3] = size; for (i = 0; i < size; i++) buffer[i + 4] = regs[0xb4 + i]; /* the USB block is size + 4 bytes of header long */ size += 4; if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD) { DBG (DBG_error, "rts88xx_write_all : write registers part 2 failed ...\n"); return SANE_STATUS_IO_ERROR; } return status; }
/* * take a bunch of pointers, send commands to scanner */ static SANE_Status do_cmd(struct scanner *s, int shortTime, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen ) { /* sanei_usb overwrites the transfer size, so make some local copies */ size_t loc_cmdLen = cmdLen; size_t loc_outLen = outLen; size_t loc_inLen = *inLen; int cmdTime = USB_COMMAND_TIME; int outTime = USB_DATA_TIME; int inTime = USB_DATA_TIME; int ret = 0; DBG (10, "do_cmd: start\n"); if(shortTime){ cmdTime /= 20; outTime /= 20; inTime /= 20; } /* change timeout */ sanei_usb_set_timeout(cmdTime); /* write the command out */ DBG(25, "cmd: writing %ld bytes, timeout %d\n", (long)cmdLen, cmdTime); hexdump(30, "cmd: >>", cmdBuff, cmdLen); ret = sanei_usb_write_bulk(s->fd, cmdBuff, &cmdLen); DBG(25, "cmd: wrote %ld bytes, retVal %d\n", (long)cmdLen, ret); if(ret == SANE_STATUS_EOF){ DBG(5,"cmd: got EOF, returning IO_ERROR\n"); return SANE_STATUS_IO_ERROR; } if(ret != SANE_STATUS_GOOD){ DBG(5,"cmd: return error '%s'\n",sane_strstatus(ret)); return ret; } if(loc_cmdLen != cmdLen){ DBG(5,"cmd: wrong size %ld/%ld\n", (long)loc_cmdLen, (long)cmdLen); return SANE_STATUS_IO_ERROR; } /* this command has a write component, and a place to get it */ if(outBuff && outLen && outTime){ /* change timeout */ sanei_usb_set_timeout(outTime); DBG(25, "out: writing %ld bytes, timeout %d\n", (long)outLen, outTime); hexdump(30, "out: >>", outBuff, outLen); ret = sanei_usb_write_bulk(s->fd, outBuff, &outLen); DBG(25, "out: wrote %ld bytes, retVal %d\n", (long)outLen, ret); if(ret == SANE_STATUS_EOF){ DBG(5,"out: got EOF, returning IO_ERROR\n"); return SANE_STATUS_IO_ERROR; } if(ret != SANE_STATUS_GOOD){ DBG(5,"out: return error '%s'\n",sane_strstatus(ret)); return ret; } if(loc_outLen != outLen){ DBG(5,"out: wrong size %ld/%ld\n", (long)loc_outLen, (long)outLen); return SANE_STATUS_IO_ERROR; } } /* this command has a read component, and a place to put it */ if(inBuff && inLen && inTime){ memset(inBuff,0,*inLen); /* change timeout */ sanei_usb_set_timeout(inTime); DBG(25, "in: reading %ld bytes, timeout %d\n", (long)*inLen, inTime); ret = sanei_usb_read_bulk(s->fd, inBuff, inLen); DBG(25, "in: retVal %d\n", ret); if(ret == SANE_STATUS_EOF){ DBG(5,"in: got EOF, continuing\n"); } else if(ret != SANE_STATUS_GOOD){ DBG(5,"in: return error '%s'\n",sane_strstatus(ret)); return ret; } DBG(25, "in: read %ld bytes\n", (long)*inLen); if(*inLen){ hexdump(30, "in: <<", inBuff, *inLen); } if(loc_inLen != *inLen){ ret = SANE_STATUS_EOF; DBG(5,"in: short read %ld/%ld\n", (long)loc_inLen, (long)*inLen); } } DBG (10, "do_cmd: finish\n"); return ret; }
/* Send command via USB, and get response data */ SANE_Status kv_usb_escape (PKV_DEV dev, PKV_CMD_HEADER header, unsigned char *status_byte) { int got_response = 0; size_t len; unsigned char cmd_buff[24]; memset (cmd_buff, 0, 24); cmd_buff[3] = 0x18; /* container length */ cmd_buff[5] = 1; /* container type: command block */ cmd_buff[6] = 0x90; /* code */ if (!kv_usb_already_open(dev)) { DBG (DBG_error, "kv_usb_escape: error, device not open.\n"); return SANE_STATUS_IO_ERROR; } memcpy (cmd_buff + 12, header->cdb, header->cdb_size); /* change timeout */ sanei_usb_set_timeout(KV_CMD_TIMEOUT); /* Send command */ len = 24; if (sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len)) { DBG (DBG_error, "usb_bulk_write: Error writing command.\n"); hexdump (DBG_error, "cmd block", cmd_buff, 24); return SANE_STATUS_IO_ERROR; } /* Send / Read data */ if (header->direction == KV_CMD_IN) { size_t size = header->data_size + 12; size_t size_read = size; unsigned char *data = ((unsigned char *) header->data) - 12; SANE_Status ret; ret = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) data, &size_read); /*empty read is ok?*/ if (ret == SANE_STATUS_EOF){ sanei_usb_clear_halt (dev->usb_fd); ret = SANE_STATUS_GOOD; } if (ret) { sanei_usb_clear_halt (dev->usb_fd); DBG (DBG_error, "usb_bulk_read: Error reading data.\n"); return SANE_STATUS_IO_ERROR; } if (size_read != size) { DBG (DBG_shortread, "usb_bulk_read: Warning - short read\n"); DBG (DBG_shortread, "usb_bulk_read: bytes to read = %lu\n", (unsigned long)size); DBG (DBG_shortread, "usb_bulk_read: bytes actual read = %lu\n", (unsigned long)size_read); /*hexdump (DBG_shortread, "data", data, size_read); */ } } if (header->direction == KV_CMD_OUT) { size_t size = header->data_size + 12; size_t size_written = size; unsigned char *data = ((unsigned char *) header->data) - 12; SANE_Status ret; memset (data, 0, 12); Ito32 (size, data); data[5] = 0x02; /* container type: data block */ data[6] = 0xb0; /* code */ ret = sanei_usb_write_bulk (dev->usb_fd, (SANE_Byte *) data, &size_written); /*empty write is ok?*/ if (ret == SANE_STATUS_EOF){ sanei_usb_clear_halt (dev->usb_fd); ret = SANE_STATUS_GOOD; } if (ret) { sanei_usb_clear_halt (dev->usb_fd); DBG (DBG_error, "usb_bulk_write: Error writing data.\n"); return SANE_STATUS_IO_ERROR; } if (size_written != size) { DBG (DBG_shortread, "usb_bulk_write: Warning - short written\n"); DBG (DBG_shortread, "usb_bulk_write: bytes to write = %lu\n", (unsigned long)size); DBG (DBG_shortread, "usb_bulk_write: bytes actual written = %lu\n", (unsigned long)size_written); hexdump (DBG_shortread, "data", data, size_written); } } /* Get response */ if (!got_response) { SANE_Status ret; size_t len = 16; ret = sanei_usb_read_bulk (dev->usb_fd, (SANE_Byte *) cmd_buff, &len); if (ret || len != 16) { DBG (DBG_error, "usb_bulk_read: Error reading response." " read %lu bytes\n", (unsigned long)len); sanei_usb_clear_halt (dev->usb_fd); return SANE_STATUS_IO_ERROR; } } if (cmd_buff[5] != 3) { DBG (DBG_error, "usb_bulk_read: Invalid response block.\n"); hexdump (DBG_error, "response", cmd_buff, 16); return SANE_STATUS_IO_ERROR; } *status_byte = cmd_buff[15] & 0x3E; return SANE_STATUS_GOOD; }