/** release all claimed 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_release_all (SANE_Int * dn, int expected)
{
  int released = 0;
  int i;
  SANE_Status status;
  device_list_type mock;

  released = 0;
  for (i = 0; i < expected; i++)
    {
      status =
	sanei_usb_release_interface (dn[i], devices[dn[i]].interface_nr);
      if (status != SANE_STATUS_GOOD)
	{
	  printf ("ERROR: couldn't release interface 0 on device %d!\n",
		  dn[i]);
	}
      else
	{
	  released++;
	}
    }
  if (released != expected)
    {
      printf ("ERROR: expected %d released interfaces, got %d!\n", expected,
	      released);
      return 0;
    }
  printf ("%d devices released...\n\n", released);

  /* try to release invalid device entry */
  status = sanei_usb_release_interface (device_number, 0);
  if (status == SANE_STATUS_GOOD)
    {
      printf ("ERROR: could release 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_release_interface (device_number - 1, 0);
  if (status == SANE_STATUS_GOOD)
    {
      printf ("ERROR: could release 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;
}
Exemple #2
0
/* Close device */
void
sane_close (SANE_Handle handle)
{
  struct scanner *s = (struct scanner *) handle;
  unsigned i;
  hopper_down (s);
  if (s->bus == USB)
    {
      sanei_usb_release_interface (s->file, 0);
      sanei_usb_close (s->file);
    }
  else
    sanei_scsi_close (s->file);

  for (i = 1; i < NUM_OPTIONS; i++)
    {
      if (s->opt[i].type == SANE_TYPE_STRING && s->val[i].s)
	free (s->val[i].s);
    }

  for (i = 0; i < sizeof (s->buf) / sizeof (s->buf[0]); i++)
    buf_deinit (&s->buf[i]);

  free (s->buffer);
  free (s);

}
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;
}
Exemple #4
0
void
sane_close (SANE_Handle h)
{
  struct device_s *dev = (struct device_s *) h;

  /* Just in case if sane_cancel() is called
   * after starting a scan but not while a sane_read
   */
  if (dev->status == STATUS_CANCELING)
    {
       do_cancel(dev);
    }

  sanei_usb_release_interface (dev->dn, 0);
  sanei_usb_close (dev->dn);

}
Exemple #5
0
/* Close device */
void
sane_close (SANE_Handle handle)
{
  struct scanner *s = (struct scanner *) handle;
  int i;
  if (s->bus == USB)
    {
      sanei_usb_release_interface (s->file, 0);
      sanei_usb_close (s->file);
    }
  else
    sanei_scsi_close (s->file);

  for (i = 1; i < NUM_OPTIONS; i++)
    {
      if (s->opt[i].type == SANE_TYPE_STRING && s->val[i].s)
	free (s->val[i].s);
    }
  if (s->data)
    free (s->data);
  free (s->buffer);
  free (s);

}
Exemple #6
0
/* 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;
}