/** claim all open devices * loop on all opened devices and claim interface 0 * @param dn array of opened device number * @param expected number of devices to be claimed * @return 1 on success, else 0 */ static int test_claim_all (SANE_Int * dn, int expected) { int claimed = 0; int i; SANE_Status status; device_list_type mock; claimed = 0; for (i = 0; i < expected; i++) { status = sanei_usb_claim_interface (dn[i], devices[dn[i]].interface_nr); if (status != SANE_STATUS_GOOD) { printf ("ERROR: couldn't claim interface 0 on device %d!\n", dn[i]); } else { claimed++; } } if (claimed != expected) { printf ("ERROR: expected %d claimed interfaces, got %d!\n", expected, claimed); return 0; } printf ("%d devices claimed...\n\n", claimed); /* try to claim invalid device entry */ status = sanei_usb_claim_interface (device_number, 0); if (status == SANE_STATUS_GOOD) { printf ("ERROR: could claim interface 0 on invalid device!\n"); return 0; } /* create a mock device and make it missing by rescanning */ create_mock_device ("mock", &mock); store_device (mock); sanei_usb_scan_devices (); /* try to claim interface on missing device */ status = sanei_usb_claim_interface (device_number - 1, 0); if (status == SANE_STATUS_GOOD) { printf ("ERROR: could claim interface 0 on invalid device!\n"); return 0; } /* remove mock device */ device_number--; free (devices[device_number].devname); devices[device_number].devname = NULL; return 1; }
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; }
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; }
/* Open device, return the device handle */ SANE_Status sane_open (SANE_String_Const devname, SANE_Handle * handle) { unsigned i, j, id = 0; struct scanner *s; SANE_Int h, bus; SANE_Status st = SANE_STATUS_GOOD; if (!devlist) { st = sane_get_devices (NULL, 0); if (st) return st; } for (i = 0; devlist[i]; i++) { if (!strcmp (devlist[i]->name, devname)) break; } if (!devlist[i]) return SANE_STATUS_INVAL; for (j = 0; j < sizeof (known_devices) / sizeof (known_devices[0]); j++) { if (!strcmp (devlist[i]->model, known_devices[j].scanner.model)) { id = known_devices[j].id; break; } } st = sanei_usb_open (devname, &h); if (st == SANE_STATUS_ACCESS_DENIED) return st; if (st) { st = sanei_scsi_open (devname, &h, kvs40xx_sense_handler, NULL); if (st) { return st; } bus = SCSI; } else { bus = USB; st = sanei_usb_claim_interface (h, 0); if (st) { sanei_usb_close (h); return st; } } s = malloc (sizeof (struct scanner)); if (!s) return SANE_STATUS_NO_MEM; memset (s, 0, sizeof (struct scanner)); s->buffer = malloc (MAX_READ_DATA_SIZE + BULK_HEADER_SIZE); if (!s->buffer) return SANE_STATUS_NO_MEM; s->file = h; s->bus = bus; s->id = id; strcpy (s->name, devname); *handle = s; for (i = 0; i < 3; i++) { st = kvs40xx_test_unit_ready (s); if (st) { if (s->bus == SCSI) { sanei_scsi_close (s->file); st = sanei_scsi_open (devname, &h, kvs40xx_sense_handler, NULL); if (st) return st; } else { sanei_usb_release_interface (s->file, 0); sanei_usb_close (s->file); st = sanei_usb_open (devname, &h); if (st) return st; st = sanei_usb_claim_interface (h, 0); if (st) { sanei_usb_close (h); return st; } } s->file = h; } else break; } if (i == 3) return SANE_STATUS_DEVICE_BUSY; if (id == KV_S4085C || id == KV_S4065C) { char str[16]; st = inquiry (s, str); if (st) goto err; if (id == KV_S4085C) s->id = !strcmp (str, "KV-S4085CL") ? KV_S4085CL : KV_S4085CW; else s->id = !strcmp (str, "KV-S4065CL") ? KV_S4065CL : KV_S4065CW; } kvs40xx_init_options (s); st = kvs40xx_set_timeout (s, s->val[FEED_TIMEOUT].w); if (st) goto err; return SANE_STATUS_GOOD; err: sane_close (s); return st; }