/* SANE API ignores return code of this callback */ SANE_Status usb_configure_device (const char *devname, SANE_Status (*attach) (const char *dev)) { sanei_usb_set_timeout (1000); sanei_usb_attach_matching_devices (devname, attach); sanei_usb_set_timeout (30000); return SANE_STATUS_GOOD; }
/** test timeout functions : libusb only * @return 1 on success, else 0 */ static int test_timeout (void) { #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB) int timeout = libusb_timeout; sanei_usb_set_timeout (5000); if (libusb_timeout != 5000) { printf ("ERROR: failed to set timeout\n"); return 1; } sanei_usb_set_timeout (timeout); #endif return 1; }
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize) { SANE_Status ret; SANE_Word vendor_id, product_id; DBG_INIT(); DBG (1, "SANE backed for HP ScanJet 4500C/4570C/5500C/5550C/5590/7650 %u.%u.%u\n", SANE_CURRENT_MAJOR, V_MINOR, BUILD); DBG (1, "(c) Ilia Sotnikov <*****@*****.**>\n"); if (version_code) *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR, BUILD); sanei_usb_init(); sanei_usb_set_timeout (USB_TIMEOUT); scanners_list = NULL; ret = hp5590_vendor_product_id (SCANNER_HP4570, &vendor_id, &product_id); if (ret != SANE_STATUS_GOOD) return ret; ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp4570); if (ret != SANE_STATUS_GOOD) return ret; ret = hp5590_vendor_product_id (SCANNER_HP5550, &vendor_id, &product_id); if (ret != SANE_STATUS_GOOD) return ret; ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp5550); if (ret != SANE_STATUS_GOOD) return ret; ret = hp5590_vendor_product_id (SCANNER_HP5590, &vendor_id, &product_id); if (ret != SANE_STATUS_GOOD) return ret; ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp5590); if (ret != SANE_STATUS_GOOD) return ret; ret = hp5590_vendor_product_id (SCANNER_HP7650, &vendor_id, &product_id); if (ret != SANE_STATUS_GOOD) return ret; ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp7650); if (ret != SANE_STATUS_GOOD) return ret; return SANE_STATUS_GOOD; }
SANE_Status sane_open (SANE_String_Const name, SANE_Handle * h) { struct device_s *dev; int ret; if(!devlist_head) sane_get_devices(NULL,(SANE_Bool)0); dev = devlist_head; if (strlen (name)) for (; dev; dev = dev->next) if (!strcmp (name, dev->devname)) break; if (!dev) { DBG(1,"Unable to find device %s\n",name); return SANE_STATUS_INVAL; } DBG(1,"Found device %s\n",name); /* Now open the usb device */ ret = sanei_usb_open (name, &(dev->dn)); if (ret != SANE_STATUS_GOOD) { DBG(1,"Unable to open device %s\n",name); return ret; } /* Claim the first interface */ ret = sanei_usb_claim_interface (dev->dn, 0); if (ret != SANE_STATUS_GOOD) { sanei_usb_close (dev->dn); /* if we cannot claim the interface, this is because someone else is using it */ DBG(1,"Unable to claim scanner interface on device %s\n",name); return SANE_STATUS_DEVICE_BUSY; } #ifdef HAVE_SANEI_USB_SET_TIMEOUT sanei_usb_set_timeout (30000); /* 30s timeout */ #endif *h = dev; return SANE_STATUS_GOOD; }
SANE_Status kvs40xx_set_timeout (struct scanner * s, int timeout) { u16 t = cpu2be16 ((u16) timeout); struct cmd c = { {0}, 10, NULL, 0, CMD_OUT }; c.data = &t; c.data_size = sizeof (t); c.cmd[0] = SET_TIMEOUT; c.cmd[2] = 0x8d; copy16 (c.cmd + 7, cpu2be16 (sizeof (t))); if (s->bus == USB) sanei_usb_set_timeout (timeout * 1000); return send_command (s, &c); }
/* * 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; }