static void channel_usb_open (channel *self, SANE_Status *status) { SANE_Status s; s = sanei_usb_open (self->name, &self->fd); if (SANE_STATUS_GOOD == s) { SANE_Word product_id = -1; sanei_usb_get_vendor_product (self->fd, NULL, &product_id); if (-1 != product_id) { self->id = product_id; } } if (self->interpreter && SANE_STATUS_GOOD == s) { if (0 > self->interpreter->open (self)) { s = SANE_STATUS_IO_ERROR; } } if (status) *status = s; }
channel * channel_interpreter_ctor (channel *self, const char *dev_name, SANE_Status *status) { char *name = NULL; size_t name_len = 0; require (self && dev_name); require (0 == strncmp_c (dev_name, "interpreter:", strlen ("interpreter:"))); dev_name += strlen ("interpreter:"); name_len = strlen ("usb:") + strlen (dev_name) + 1; name = t_malloc (name_len, char); if (!name) { if (status) *status = SANE_STATUS_NO_MEM; return self->dtor (self); } strcpy (name, "usb:"); strcat (name, dev_name); self = channel_usb_ctor (self, name, status); delete (name); if (self) { SANE_Status s = SANE_STATUS_GOOD; SANE_Word vendor; SANE_Word product; self->open (self, &s); if (SANE_STATUS_GOOD == s) { s = sanei_usb_get_vendor_product (self->fd, &vendor, &product); } self->close (self, NULL); if (SANE_STATUS_GOOD == s) { s = create_interpreter (self, product); } if (!self->interpreter) { if (status) *status = s; return self->dtor (self); } else { self->dtor = channel_interpreter_dtor; } } self->max_size = 32 * 1024; return self; }
/* Open the device. */ static SANE_Status sanei_umaxusb_open (const char *dev, int *fdp, SANEI_SCSI_Sense_Handler handler, void *handler_arg) { SANE_Status status; handler = handler; /* silence gcc */ handler_arg = handler_arg; /* silence gcc */ status = sanei_usb_open (dev, fdp); if (status != SANE_STATUS_GOOD) { DBG (1, "sanei_umaxusb_open: open of `%s' failed: %s\n", dev, sane_strstatus(status)); return status; } else { SANE_Word vendor; SANE_Word product; /* We have openned the device. Check that it is a USB scanner. */ if (sanei_usb_get_vendor_product (*fdp, &vendor, &product) != SANE_STATUS_GOOD) { /* This is not a USB scanner, or SANE or the OS doesn't support it. */ sanei_usb_close(*fdp); *fdp = -1; return SANE_STATUS_UNSUPPORTED; } /* So it's a scanner. Does this backend support it? * Only the UMAX 2200 USB is currently supported. */ if ((vendor != 0x1606) || (product != 0x0230)) { sanei_usb_close(*fdp); *fdp = -1; return SANE_STATUS_UNSUPPORTED; } /* It's a good scanner. Initialize it. * * Note: pv8630_init_umaxusb_scanner() is for the UMAX * 2200. Other UMAX scanner might need a different * initialization routine. */ pv8630_init_umaxusb_scanner(*fdp); } return(SANE_STATUS_GOOD); }
/* callback used by sane_get_devices * build the scanner struct and link to global list * unless struct is already loaded, then pretend */ static SANE_Status attach_one (const char *device_name) { struct scanner *s; int ret, i; SANE_Word vid, pid; DBG (10, "attach_one: start '%s'\n", device_name); for (s = scanner_devList; s; s = s->next) { if (strcmp (s->sane.name, device_name) == 0) { DBG (10, "attach_one: already attached!\n"); return SANE_STATUS_GOOD; } } /* build a scanner struct to hold it */ DBG (15, "attach_one: init struct\n"); if ((s = calloc (sizeof (*s), 1)) == NULL) return SANE_STATUS_NO_MEM; /* copy the device name */ s->device_name = strdup (device_name); if (!s->device_name){ free (s); return SANE_STATUS_NO_MEM; } /* connect the fd */ DBG (15, "attach_one: connect fd\n"); s->fd = -1; ret = connect_fd(s); if(ret != SANE_STATUS_GOOD){ free (s->device_name); free (s); return ret; } /* clean up the scanner struct based on model */ /* this is the only piece of model specific code */ sanei_usb_get_vendor_product(s->fd,&vid,&pid); if(vid == 0x08f0){ s->vendor_name = "CardScan"; if(pid == 0x0005){ s->product_name = "800c"; } else if(pid == 0x0002){ s->product_name = "600c"; } else{ DBG (5, "Unknown product, using default settings\n"); s->product_name = "Unknown"; } } else if(vid == 0x0451){ s->vendor_name = "Sanford"; if(pid == 0x6250){ s->product_name = "800c"; } else{ DBG (5, "Unknown product, using default settings\n"); s->product_name = "Unknown"; } } else{ DBG (5, "Unknown vendor/product, using default settings\n"); s->vendor_name = "Unknown"; s->product_name = "Unknown"; } DBG (15, "attach_one: Found %s scanner %s at %s\n", s->vendor_name, s->product_name, s->device_name); /*copy config file settings*/ s->has_cal_buffer = global_has_cal_buffer; s->lines_per_block = global_lines_per_block; s->color_block_size = s->lines_per_block * PIXELS_PER_LINE * 3; s->gray_block_size = s->lines_per_block * PIXELS_PER_LINE; /* try to get calibration */ if(s->has_cal_buffer){ DBG (15, "attach_one: scanner calibration\n"); ret = load_calibration(s); if (ret != SANE_STATUS_GOOD) { DBG (5, "sane_start: ERROR: cannot calibrate, incompatible?\n"); free (s->device_name); free (s); return ret; } } else{ DBG (15, "attach_one: skipping calibration\n"); } /* set SANE option 'values' to good defaults */ DBG (15, "attach_one: init options\n"); /* go ahead and setup the first opt, because * frontend may call control_option on it * before calling get_option_descriptor */ memset (s->opt, 0, sizeof (s->opt)); for (i = 0; i < NUM_OPTIONS; ++i) { s->opt[i].name = "filler"; s->opt[i].size = sizeof (SANE_Word); s->opt[i].cap = SANE_CAP_INACTIVE; } s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; DBG (15, "attach_one: init settings\n"); /* we close the connection, so that another backend can talk to scanner */ disconnect_fd(s); /* load info into sane_device struct */ s->sane.name = s->device_name; s->sane.vendor = s->vendor_name; s->sane.model = s->product_name; s->sane.type = "scanner"; s->next = scanner_devList; scanner_devList = s; DBG (10, "attach_one: finish\n"); return SANE_STATUS_GOOD; }
static int u12if_open( U12_Device *dev ) { char devStr[50]; int result; SANE_Int handle; SANE_Word vendor, product; SANE_Bool was_empty; DBG( _DBG_INFO, "u12if_open(%s,%s)\n", dev->name, dev->usbId ); USB_devname[0] = '\0'; #ifdef _FAKE_DEVICE dev->name = strdup( "auto" ); dev->sane.name = dev->name; was_empty = SANE_FALSE; result = SANE_STATUS_UNSUPPORTED; #else if( !strcmp( dev->name, "auto" )) { if( dev->usbId[0] == '\0' ) { if( !usbDev_autodetect( &vendor, &product )) { DBG( _DBG_ERROR, "No supported device found!\n" ); return -1; } } else { vendor = strtol( &dev->usbId[0], 0, 0 ); product = strtol( &dev->usbId[7], 0, 0 ); sanei_usb_find_devices( vendor, product, u12if_usbattach ); if( USB_devname[0] == '\0' ) { DBG( _DBG_ERROR, "No matching device found!\n" ); return -1; } } if( SANE_STATUS_GOOD != sanei_usb_open( USB_devname, &handle )) { return -1; } /* replace the old devname, so we are able to have multiple * auto-detected devices */ free( dev->name ); dev->name = strdup( USB_devname ); dev->sane.name = dev->name; } else { if( SANE_STATUS_GOOD != sanei_usb_open( dev->name, &handle )) return -1; } was_empty = SANE_FALSE; result = sanei_usb_get_vendor_product( handle, &vendor, &product ); #endif if( SANE_STATUS_GOOD == result ) { sprintf( devStr, "0x%04X-0x%04X", vendor, product ); DBG(_DBG_INFO,"Vendor ID=0x%04X, Product ID=0x%04X\n",vendor,product); if( dev->usbId[0] != '\0' ) { if( 0 != strcmp( dev->usbId, devStr )) { DBG( _DBG_ERROR, "Specified Vendor and Product ID " "doesn't match with the ones\n" "in the config file\n" ); sanei_usb_close( handle ); return -1; } } else { sprintf( dev->usbId, "0x%04X-0x%04X", vendor, product ); was_empty = SANE_TRUE; } } else { DBG( _DBG_INFO, "Can't get vendor & product ID from driver...\n" ); /* if the ioctl stuff is not supported by the kernel and we have * nothing specified, we have to give up... */ if( dev->usbId[0] == '\0' ) { DBG( _DBG_ERROR, "Cannot autodetect Vendor an Product ID, " "please specify in config file.\n" ); sanei_usb_close( handle ); return -1; } vendor = strtol( &dev->usbId[0], 0, 0 ); product = strtol( &dev->usbId[7], 0, 0 ); DBG( _DBG_INFO, "... using the specified: " "0x%04X-0x%04X\n", vendor, product ); } /* before accessing the scanner, check if supported! */ if( !u12if_IsDeviceSupported( dev )) { DBG( _DBG_ERROR, "Device >%s<, is not supported!\n", dev->usbId ); sanei_usb_close( handle ); return -1; } dev->mode = _PP_MODE_SPP; dev->fd = handle; /* is it accessible ? */ if( SANE_STATUS_GOOD != u12hw_CheckDevice( dev )) { dev->fd = -1; sanei_usb_close( handle ); return -1; } DBG( _DBG_INFO, "Detected vendor & product ID: " "0x%04X-0x%04X\n", vendor, product ); if( was_empty ) dev->usbId[0] = '\0'; /* now initialize the device */ if( SANE_STATUS_GOOD != u12_initDev( dev, handle, vendor )) { dev->fd = -1; sanei_usb_close( handle ); return -1; } if( _PLUSTEK_VENID == vendor ) { if( dev->Tpa ) dev->sane.model = "UT12"; } dev->initialized = SANE_TRUE; return handle; }
/** get vendor for all devices id * loop on all existing devices and get vendor * and product id. * @param expected count * @return 1 on success, else 0 */ static int test_vendor_by_id (void) { int i; SANE_Status status; SANE_Word vendor, product; device_list_type mock; /* loop on detected devices and open them */ for (i = 0; i < device_number; i++) { if (devices[i].missing == 0 && devices[i].devname != NULL) { /* get device id */ status = sanei_usb_get_vendor_product (i, &vendor, &product); if (status != SANE_STATUS_GOOD) { printf ("ERROR: couldn't query device %d!\n", i); return 0; } if (vendor == 0 || product == 0) { printf ("ERROR: incomplete device id for %d!\n", i); return 0; } printf ("%d is %04x:%04x\n", i, vendor, product); } } /* add mock device */ create_mock_device ("mock", &mock); store_device (mock); status = sanei_usb_get_vendor_product (device_number - 1, &vendor, &product); if (status != SANE_STATUS_GOOD) { printf ("ERROR: getting vendor for mock devname!\n"); return 0; } if (vendor != mock.vendor || product != mock.product) { printf ("ERROR: wrong vendor/product for mock devname!\n"); return 0; } /* remove mock device */ device_number--; free (devices[device_number].devname); devices[device_number].devname = NULL; /* try go get id for an invalid id */ status = sanei_usb_get_vendor_product (device_number + 1, &vendor, &product); if (status == SANE_STATUS_GOOD) { printf ("ERROR: unexpected success getting vendor for invalid devname!\n"); return 0; } printf ("\n"); return 1; }