1141cc406Sopenharmony_ci/* SANE - Scanner Access Now Easy. 2141cc406Sopenharmony_ci * For limitations, see function sanei_usb_get_vendor_product(). 3141cc406Sopenharmony_ci 4141cc406Sopenharmony_ci Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de> 5141cc406Sopenharmony_ci Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de> 6141cc406Sopenharmony_ci 7141cc406Sopenharmony_ci This file is part of the SANE package. 8141cc406Sopenharmony_ci 9141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 10141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 11141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 12141cc406Sopenharmony_ci License, or (at your option) any later version. 13141cc406Sopenharmony_ci 14141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 15141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 16141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17141cc406Sopenharmony_ci General Public License for more details. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 20141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 23141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 24141cc406Sopenharmony_ci 25141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 26141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 27141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 28141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 29141cc406Sopenharmony_ci account of linking the SANE library code into it. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 32141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 33141cc406Sopenharmony_ci License. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 36141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 37141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 38141cc406Sopenharmony_ci 39141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 40141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 41141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 42141cc406Sopenharmony_ci */ 43141cc406Sopenharmony_ci#include "../include/sane/config.h" 44141cc406Sopenharmony_ci 45141cc406Sopenharmony_ci#include <string.h> 46141cc406Sopenharmony_ci#include <stdlib.h> 47141cc406Sopenharmony_ci#include <stdio.h> 48141cc406Sopenharmony_ci#include <limits.h> /* INT_MAX */ 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#include "pixma_rename.h" 51141cc406Sopenharmony_ci#include "pixma_common.h" 52141cc406Sopenharmony_ci#include "pixma_io.h" 53141cc406Sopenharmony_ci#include "pixma_bjnp.h" 54141cc406Sopenharmony_ci 55141cc406Sopenharmony_ci#include "../include/sane/sanei_usb.h" 56141cc406Sopenharmony_ci#include "../include/sane/sane.h" 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci 59141cc406Sopenharmony_ci#ifdef __GNUC__ 60141cc406Sopenharmony_ci# define UNUSED(v) (void) v 61141cc406Sopenharmony_ci#else 62141cc406Sopenharmony_ci# define UNUSED(v) 63141cc406Sopenharmony_ci#endif 64141cc406Sopenharmony_ci 65141cc406Sopenharmony_ci/* MAC OS X does not support timeouts in darwin/libusb interrupt reads 66141cc406Sopenharmony_ci * This is a very basic turnaround for MAC OS X 67141cc406Sopenharmony_ci * Button scan will not work with this wrapper */ 68141cc406Sopenharmony_ci#ifdef __APPLE__ 69141cc406Sopenharmony_ci# define sanei_usb_read_int sanei_usb_read_bulk 70141cc406Sopenharmony_ci#endif 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci 73141cc406Sopenharmony_cistruct pixma_io_t 74141cc406Sopenharmony_ci{ 75141cc406Sopenharmony_ci pixma_io_t *next; 76141cc406Sopenharmony_ci int interface; 77141cc406Sopenharmony_ci SANE_Int dev; 78141cc406Sopenharmony_ci}; 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_citypedef struct scanner_info_t 81141cc406Sopenharmony_ci{ 82141cc406Sopenharmony_ci struct scanner_info_t *next; 83141cc406Sopenharmony_ci char *devname; 84141cc406Sopenharmony_ci int interface; 85141cc406Sopenharmony_ci const pixma_config_t *cfg; 86141cc406Sopenharmony_ci char serial[PIXMA_MAX_ID_LEN + 1]; /* "xxxxyyyy_zzzzzzz..." 87141cc406Sopenharmony_ci x = vid, y = pid, z = serial */ 88141cc406Sopenharmony_ci} scanner_info_t; 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci#define INT_USB 0 91141cc406Sopenharmony_ci#define INT_BJNP 1 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_cistatic scanner_info_t *first_scanner = NULL; 94141cc406Sopenharmony_cistatic pixma_io_t *first_io = NULL; 95141cc406Sopenharmony_cistatic unsigned nscanners; 96141cc406Sopenharmony_ci 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_cistatic scanner_info_t * 99141cc406Sopenharmony_ciget_scanner_info (unsigned devnr) 100141cc406Sopenharmony_ci{ 101141cc406Sopenharmony_ci scanner_info_t *si; 102141cc406Sopenharmony_ci for (si = first_scanner; si && devnr != 0; --devnr, si = si->next) 103141cc406Sopenharmony_ci { 104141cc406Sopenharmony_ci } 105141cc406Sopenharmony_ci return si; 106141cc406Sopenharmony_ci} 107141cc406Sopenharmony_ci 108141cc406Sopenharmony_cistatic SANE_Status 109141cc406Sopenharmony_ciattach (SANE_String_Const devname) 110141cc406Sopenharmony_ci{ 111141cc406Sopenharmony_ci scanner_info_t *si; 112141cc406Sopenharmony_ci 113141cc406Sopenharmony_ci si = (scanner_info_t *) calloc (1, sizeof (*si)); 114141cc406Sopenharmony_ci if (!si) 115141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 116141cc406Sopenharmony_ci si->devname = strdup (devname); 117141cc406Sopenharmony_ci if (!si->devname) 118141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 119141cc406Sopenharmony_ci si -> interface = INT_USB; 120141cc406Sopenharmony_ci si->next = first_scanner; 121141cc406Sopenharmony_ci first_scanner = si; 122141cc406Sopenharmony_ci nscanners++; 123141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 124141cc406Sopenharmony_ci} 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci 127141cc406Sopenharmony_cistatic SANE_Status 128141cc406Sopenharmony_ciattach_bjnp (SANE_String_Const devname, 129141cc406Sopenharmony_ci SANE_String_Const serial, 130141cc406Sopenharmony_ci const struct pixma_config_t *cfg) 131141cc406Sopenharmony_ci{ 132141cc406Sopenharmony_ci scanner_info_t *si; 133141cc406Sopenharmony_ci 134141cc406Sopenharmony_ci si = (scanner_info_t *) calloc (1, sizeof (*si)); 135141cc406Sopenharmony_ci if (!si) 136141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 137141cc406Sopenharmony_ci si->devname = strdup (devname); 138141cc406Sopenharmony_ci if (!si->devname) 139141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_ci si->cfg = cfg; 142141cc406Sopenharmony_ci sprintf(si->serial, "%s_%s", cfg->model, serial); 143141cc406Sopenharmony_ci si -> interface = INT_BJNP; 144141cc406Sopenharmony_ci si->next = first_scanner; 145141cc406Sopenharmony_ci first_scanner = si; 146141cc406Sopenharmony_ci nscanners++; 147141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 148141cc406Sopenharmony_ci} 149141cc406Sopenharmony_ci 150141cc406Sopenharmony_cistatic void 151141cc406Sopenharmony_ciclear_scanner_list (void) 152141cc406Sopenharmony_ci{ 153141cc406Sopenharmony_ci scanner_info_t *si = first_scanner; 154141cc406Sopenharmony_ci while (si) 155141cc406Sopenharmony_ci { 156141cc406Sopenharmony_ci scanner_info_t *temp = si; 157141cc406Sopenharmony_ci free (si->devname); 158141cc406Sopenharmony_ci si = si->next; 159141cc406Sopenharmony_ci free (temp); 160141cc406Sopenharmony_ci } 161141cc406Sopenharmony_ci nscanners = 0; 162141cc406Sopenharmony_ci first_scanner = NULL; 163141cc406Sopenharmony_ci} 164141cc406Sopenharmony_ci 165141cc406Sopenharmony_cistatic SANE_Status 166141cc406Sopenharmony_ciget_descriptor (SANE_Int dn, SANE_Int type, SANE_Int descidx, 167141cc406Sopenharmony_ci SANE_Int index, SANE_Int length, SANE_Byte * data) 168141cc406Sopenharmony_ci{ 169141cc406Sopenharmony_ci return sanei_usb_control_msg (dn, 0x80, USB_REQ_GET_DESCRIPTOR, 170141cc406Sopenharmony_ci ((type & 0xff) << 8) | (descidx & 0xff), 171141cc406Sopenharmony_ci index, length, data); 172141cc406Sopenharmony_ci} 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_cistatic SANE_Status 175141cc406Sopenharmony_ciget_string_descriptor (SANE_Int dn, SANE_Int index, SANE_Int lang, 176141cc406Sopenharmony_ci SANE_Int length, SANE_Byte * data) 177141cc406Sopenharmony_ci{ 178141cc406Sopenharmony_ci return get_descriptor (dn, USB_DT_STRING, index, lang, length, data); 179141cc406Sopenharmony_ci} 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_cistatic void 182141cc406Sopenharmony_ciu16tohex (uint16_t x, char *str) 183141cc406Sopenharmony_ci{ 184141cc406Sopenharmony_ci static const char hdigit[16] = 185141cc406Sopenharmony_ci { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 186141cc406Sopenharmony_ci 'E', 'F' 187141cc406Sopenharmony_ci }; 188141cc406Sopenharmony_ci str[0] = hdigit[(x >> 12) & 0xf]; 189141cc406Sopenharmony_ci str[1] = hdigit[(x >> 8) & 0xf]; 190141cc406Sopenharmony_ci str[2] = hdigit[(x >> 4) & 0xf]; 191141cc406Sopenharmony_ci str[3] = hdigit[x & 0xf]; 192141cc406Sopenharmony_ci str[4] = '\0'; 193141cc406Sopenharmony_ci} 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_cistatic void 196141cc406Sopenharmony_ciread_serial_number (scanner_info_t * si) 197141cc406Sopenharmony_ci{ 198141cc406Sopenharmony_ci uint8_t unicode[2 * (PIXMA_MAX_ID_LEN - 9) + 2]; 199141cc406Sopenharmony_ci uint8_t ddesc[18]; 200141cc406Sopenharmony_ci int iSerialNumber; 201141cc406Sopenharmony_ci SANE_Int usb; 202141cc406Sopenharmony_ci char *serial = si->serial; 203141cc406Sopenharmony_ci 204141cc406Sopenharmony_ci u16tohex (si->cfg->vid, serial); 205141cc406Sopenharmony_ci u16tohex (si->cfg->pid, serial + 4); 206141cc406Sopenharmony_ci 207141cc406Sopenharmony_ci if (SANE_STATUS_GOOD != sanei_usb_open (si->devname, &usb)) 208141cc406Sopenharmony_ci return; 209141cc406Sopenharmony_ci if (get_descriptor (usb, USB_DT_DEVICE, 0, 0, 18, ddesc) 210141cc406Sopenharmony_ci != SANE_STATUS_GOOD) 211141cc406Sopenharmony_ci goto done; 212141cc406Sopenharmony_ci iSerialNumber = ddesc[16]; 213141cc406Sopenharmony_ci if (iSerialNumber != 0) 214141cc406Sopenharmony_ci { 215141cc406Sopenharmony_ci int i, len; 216141cc406Sopenharmony_ci SANE_Status status; 217141cc406Sopenharmony_ci 218141cc406Sopenharmony_ci /*int iSerialNumber = ddesc[16];*/ 219141cc406Sopenharmony_ci /* Read the first language code. Assumed that there is at least one. */ 220141cc406Sopenharmony_ci if (get_string_descriptor (usb, 0, 0, 4, unicode) != SANE_STATUS_GOOD) 221141cc406Sopenharmony_ci goto done; 222141cc406Sopenharmony_ci /* Read the serial number string. */ 223141cc406Sopenharmony_ci status = get_string_descriptor (usb, iSerialNumber, 224141cc406Sopenharmony_ci unicode[3] * 256 + unicode[2], 225141cc406Sopenharmony_ci sizeof (unicode), unicode); 226141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 227141cc406Sopenharmony_ci goto done; 228141cc406Sopenharmony_ci /* Assumed charset: Latin1 */ 229141cc406Sopenharmony_ci len = unicode[0]; 230141cc406Sopenharmony_ci if (len > (int) sizeof (unicode)) 231141cc406Sopenharmony_ci { 232141cc406Sopenharmony_ci len = sizeof (unicode); 233141cc406Sopenharmony_ci PDBG (pixma_dbg (1, "WARNING:Truncated serial number\n")); 234141cc406Sopenharmony_ci } 235141cc406Sopenharmony_ci serial[8] = '_'; 236141cc406Sopenharmony_ci for (i = 2; i < len; i += 2) 237141cc406Sopenharmony_ci { 238141cc406Sopenharmony_ci serial[9 + i / 2 - 1] = unicode[i]; 239141cc406Sopenharmony_ci } 240141cc406Sopenharmony_ci serial[9 + i / 2 - 1] = '\0'; 241141cc406Sopenharmony_ci } 242141cc406Sopenharmony_ci else 243141cc406Sopenharmony_ci { 244141cc406Sopenharmony_ci PDBG (pixma_dbg (1, "WARNING:No serial number\n")); 245141cc406Sopenharmony_ci } 246141cc406Sopenharmony_cidone: 247141cc406Sopenharmony_ci sanei_usb_close (usb); 248141cc406Sopenharmony_ci} 249141cc406Sopenharmony_ci 250141cc406Sopenharmony_cistatic int 251141cc406Sopenharmony_cimap_error (SANE_Status ss) 252141cc406Sopenharmony_ci{ 253141cc406Sopenharmony_ci switch (ss) 254141cc406Sopenharmony_ci { 255141cc406Sopenharmony_ci case SANE_STATUS_GOOD: 256141cc406Sopenharmony_ci return 0; 257141cc406Sopenharmony_ci case SANE_STATUS_UNSUPPORTED: 258141cc406Sopenharmony_ci return PIXMA_ENODEV; 259141cc406Sopenharmony_ci case SANE_STATUS_DEVICE_BUSY: 260141cc406Sopenharmony_ci return PIXMA_EBUSY; 261141cc406Sopenharmony_ci case SANE_STATUS_INVAL: 262141cc406Sopenharmony_ci return PIXMA_EINVAL; 263141cc406Sopenharmony_ci case SANE_STATUS_IO_ERROR: 264141cc406Sopenharmony_ci return PIXMA_EIO; 265141cc406Sopenharmony_ci case SANE_STATUS_NO_MEM: 266141cc406Sopenharmony_ci return PIXMA_ENOMEM; 267141cc406Sopenharmony_ci case SANE_STATUS_ACCESS_DENIED: 268141cc406Sopenharmony_ci return PIXMA_EACCES; 269141cc406Sopenharmony_ci case SANE_STATUS_CANCELLED: 270141cc406Sopenharmony_ci return PIXMA_ECANCELED; 271141cc406Sopenharmony_ci case SANE_STATUS_JAMMED: 272141cc406Sopenharmony_ci return PIXMA_EPAPER_JAMMED; 273141cc406Sopenharmony_ci case SANE_STATUS_COVER_OPEN: 274141cc406Sopenharmony_ci return PIXMA_ECOVER_OPEN; 275141cc406Sopenharmony_ci case SANE_STATUS_NO_DOCS: 276141cc406Sopenharmony_ci return PIXMA_ENO_PAPER; 277141cc406Sopenharmony_ci case SANE_STATUS_EOF: 278141cc406Sopenharmony_ci return PIXMA_EOF; 279141cc406Sopenharmony_ci#ifdef SANE_STATUS_HW_LOCKED 280141cc406Sopenharmony_ci case SANE_STATUS_HW_LOCKED: /* unused by pixma */ 281141cc406Sopenharmony_ci#endif 282141cc406Sopenharmony_ci#ifdef SANE_STATUS_WARMING_UP 283141cc406Sopenharmony_ci case SANE_STATUS_WARMING_UP: /* unused by pixma */ 284141cc406Sopenharmony_ci#endif 285141cc406Sopenharmony_ci break; 286141cc406Sopenharmony_ci } 287141cc406Sopenharmony_ci PDBG (pixma_dbg (1, "BUG:Unmapped SANE Status code %d\n", ss)); 288141cc406Sopenharmony_ci return PIXMA_EIO; /* should not happen */ 289141cc406Sopenharmony_ci} 290141cc406Sopenharmony_ci 291141cc406Sopenharmony_ci 292141cc406Sopenharmony_ciint 293141cc406Sopenharmony_cipixma_io_init (void) 294141cc406Sopenharmony_ci{ 295141cc406Sopenharmony_ci sanei_usb_init (); 296141cc406Sopenharmony_ci sanei_bjnp_init(); 297141cc406Sopenharmony_ci nscanners = 0; 298141cc406Sopenharmony_ci return 0; 299141cc406Sopenharmony_ci} 300141cc406Sopenharmony_ci 301141cc406Sopenharmony_civoid 302141cc406Sopenharmony_cipixma_io_cleanup (void) 303141cc406Sopenharmony_ci{ 304141cc406Sopenharmony_ci while (first_io) 305141cc406Sopenharmony_ci pixma_disconnect (first_io); 306141cc406Sopenharmony_ci clear_scanner_list (); 307141cc406Sopenharmony_ci} 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ciunsigned 310141cc406Sopenharmony_cipixma_collect_devices (const char **conf_devices, 311141cc406Sopenharmony_ci const struct pixma_config_t *const pixma_devices[], SANE_Bool local_only) 312141cc406Sopenharmony_ci{ 313141cc406Sopenharmony_ci unsigned i, j; 314141cc406Sopenharmony_ci struct scanner_info_t *si; 315141cc406Sopenharmony_ci const struct pixma_config_t *cfg; 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci clear_scanner_list (); 318141cc406Sopenharmony_ci j = 0; 319141cc406Sopenharmony_ci for (i = 0; pixma_devices[i]; i++) 320141cc406Sopenharmony_ci { 321141cc406Sopenharmony_ci for (cfg = pixma_devices[i]; cfg->name; cfg++) 322141cc406Sopenharmony_ci { 323141cc406Sopenharmony_ci sanei_usb_find_devices (cfg->vid, cfg->pid, attach); 324141cc406Sopenharmony_ci si = first_scanner; 325141cc406Sopenharmony_ci while (j < nscanners) 326141cc406Sopenharmony_ci { 327141cc406Sopenharmony_ci PDBG (pixma_dbg (3, "pixma_collect_devices() found %s at %s\n", 328141cc406Sopenharmony_ci cfg->name, si->devname)); 329141cc406Sopenharmony_ci si->cfg = cfg; 330141cc406Sopenharmony_ci read_serial_number (si); 331141cc406Sopenharmony_ci si = si->next; 332141cc406Sopenharmony_ci j++; 333141cc406Sopenharmony_ci } 334141cc406Sopenharmony_ci } 335141cc406Sopenharmony_ci } 336141cc406Sopenharmony_ci if (! local_only) 337141cc406Sopenharmony_ci sanei_bjnp_find_devices(conf_devices, attach_bjnp, pixma_devices); 338141cc406Sopenharmony_ci 339141cc406Sopenharmony_ci si = first_scanner; 340141cc406Sopenharmony_ci while (j < nscanners) 341141cc406Sopenharmony_ci { 342141cc406Sopenharmony_ci PDBG (pixma_dbg (3, "pixma_collect_devices() found %s at %s\n", 343141cc406Sopenharmony_ci si->cfg->name, si->devname)); 344141cc406Sopenharmony_ci si = si->next; 345141cc406Sopenharmony_ci j++; 346141cc406Sopenharmony_ci 347141cc406Sopenharmony_ci } 348141cc406Sopenharmony_ci return nscanners; 349141cc406Sopenharmony_ci} 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_ciconst pixma_config_t * 352141cc406Sopenharmony_cipixma_get_device_config (unsigned devnr) 353141cc406Sopenharmony_ci{ 354141cc406Sopenharmony_ci const scanner_info_t *si = get_scanner_info (devnr); 355141cc406Sopenharmony_ci return (si) ? si->cfg : NULL; 356141cc406Sopenharmony_ci} 357141cc406Sopenharmony_ci 358141cc406Sopenharmony_ciconst char * 359141cc406Sopenharmony_cipixma_get_device_id (unsigned devnr) 360141cc406Sopenharmony_ci{ 361141cc406Sopenharmony_ci const scanner_info_t *si = get_scanner_info (devnr); 362141cc406Sopenharmony_ci return (si) ? si->serial : NULL; 363141cc406Sopenharmony_ci} 364141cc406Sopenharmony_ci 365141cc406Sopenharmony_ciint 366141cc406Sopenharmony_cipixma_connect (unsigned devnr, pixma_io_t ** handle) 367141cc406Sopenharmony_ci{ 368141cc406Sopenharmony_ci pixma_io_t *io; 369141cc406Sopenharmony_ci SANE_Int dev; 370141cc406Sopenharmony_ci const scanner_info_t *si; 371141cc406Sopenharmony_ci int error; 372141cc406Sopenharmony_ci 373141cc406Sopenharmony_ci *handle = NULL; 374141cc406Sopenharmony_ci si = get_scanner_info (devnr); 375141cc406Sopenharmony_ci if (!si) 376141cc406Sopenharmony_ci return PIXMA_EINVAL; 377141cc406Sopenharmony_ci if (si-> interface == INT_BJNP) 378141cc406Sopenharmony_ci error = map_error (sanei_bjnp_open (si->devname, &dev)); 379141cc406Sopenharmony_ci else 380141cc406Sopenharmony_ci error = map_error (sanei_usb_open (si->devname, &dev)); 381141cc406Sopenharmony_ci 382141cc406Sopenharmony_ci if (error < 0) 383141cc406Sopenharmony_ci return error; 384141cc406Sopenharmony_ci io = (pixma_io_t *) calloc (1, sizeof (*io)); 385141cc406Sopenharmony_ci if (!io) 386141cc406Sopenharmony_ci { 387141cc406Sopenharmony_ci if (si -> interface == INT_BJNP) 388141cc406Sopenharmony_ci sanei_bjnp_close (dev); 389141cc406Sopenharmony_ci else 390141cc406Sopenharmony_ci sanei_usb_close (dev); 391141cc406Sopenharmony_ci return PIXMA_ENOMEM; 392141cc406Sopenharmony_ci } 393141cc406Sopenharmony_ci io->next = first_io; 394141cc406Sopenharmony_ci first_io = io; 395141cc406Sopenharmony_ci io->dev = dev; 396141cc406Sopenharmony_ci io->interface = si->interface; 397141cc406Sopenharmony_ci *handle = io; 398141cc406Sopenharmony_ci return 0; 399141cc406Sopenharmony_ci} 400141cc406Sopenharmony_ci 401141cc406Sopenharmony_ci 402141cc406Sopenharmony_civoid 403141cc406Sopenharmony_cipixma_disconnect (pixma_io_t * io) 404141cc406Sopenharmony_ci{ 405141cc406Sopenharmony_ci pixma_io_t **p; 406141cc406Sopenharmony_ci 407141cc406Sopenharmony_ci if (!io) 408141cc406Sopenharmony_ci return; 409141cc406Sopenharmony_ci for (p = &first_io; *p && *p != io; p = &((*p)->next)) 410141cc406Sopenharmony_ci { 411141cc406Sopenharmony_ci } 412141cc406Sopenharmony_ci PASSERT (*p); 413141cc406Sopenharmony_ci if (!(*p)) 414141cc406Sopenharmony_ci return; 415141cc406Sopenharmony_ci if (io-> interface == INT_BJNP) 416141cc406Sopenharmony_ci sanei_bjnp_close (io->dev); 417141cc406Sopenharmony_ci else 418141cc406Sopenharmony_ci sanei_usb_close (io->dev); 419141cc406Sopenharmony_ci *p = io->next; 420141cc406Sopenharmony_ci free (io); 421141cc406Sopenharmony_ci} 422141cc406Sopenharmony_ci 423141cc406Sopenharmony_ciint pixma_activate (pixma_io_t * io) 424141cc406Sopenharmony_ci{ 425141cc406Sopenharmony_ci int error; 426141cc406Sopenharmony_ci if (io->interface == INT_BJNP) 427141cc406Sopenharmony_ci { 428141cc406Sopenharmony_ci error = map_error(sanei_bjnp_activate (io->dev)); 429141cc406Sopenharmony_ci } 430141cc406Sopenharmony_ci else 431141cc406Sopenharmony_ci /* noop for USB interface */ 432141cc406Sopenharmony_ci error = 0; 433141cc406Sopenharmony_ci return error; 434141cc406Sopenharmony_ci} 435141cc406Sopenharmony_ci 436141cc406Sopenharmony_ciint pixma_deactivate (pixma_io_t * io) 437141cc406Sopenharmony_ci{ 438141cc406Sopenharmony_ci int error; 439141cc406Sopenharmony_ci if (io->interface == INT_BJNP) 440141cc406Sopenharmony_ci { 441141cc406Sopenharmony_ci error = map_error(sanei_bjnp_deactivate (io->dev)); 442141cc406Sopenharmony_ci } 443141cc406Sopenharmony_ci else 444141cc406Sopenharmony_ci /* noop for USB interface */ 445141cc406Sopenharmony_ci error = 0; 446141cc406Sopenharmony_ci return error; 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci} 449141cc406Sopenharmony_ci 450141cc406Sopenharmony_ciint 451141cc406Sopenharmony_cipixma_reset_device (pixma_io_t * io) 452141cc406Sopenharmony_ci{ 453141cc406Sopenharmony_ci UNUSED (io); 454141cc406Sopenharmony_ci return PIXMA_ENOTSUP; 455141cc406Sopenharmony_ci} 456141cc406Sopenharmony_ci 457141cc406Sopenharmony_ciint 458141cc406Sopenharmony_cipixma_write (pixma_io_t * io, const void *cmd, unsigned len) 459141cc406Sopenharmony_ci{ 460141cc406Sopenharmony_ci size_t count = len; 461141cc406Sopenharmony_ci int error; 462141cc406Sopenharmony_ci 463141cc406Sopenharmony_ci if (io->interface == INT_BJNP) 464141cc406Sopenharmony_ci { 465141cc406Sopenharmony_ci sanei_bjnp_set_timeout (io->dev, PIXMA_BULKOUT_TIMEOUT); 466141cc406Sopenharmony_ci error = map_error (sanei_bjnp_write_bulk (io->dev, cmd, &count)); 467141cc406Sopenharmony_ci } 468141cc406Sopenharmony_ci else 469141cc406Sopenharmony_ci { 470141cc406Sopenharmony_ci#ifdef HAVE_SANEI_USB_SET_TIMEOUT 471141cc406Sopenharmony_ci sanei_usb_set_timeout (PIXMA_BULKOUT_TIMEOUT); 472141cc406Sopenharmony_ci#endif 473141cc406Sopenharmony_ci error = map_error (sanei_usb_write_bulk (io->dev, cmd, &count)); 474141cc406Sopenharmony_ci } 475141cc406Sopenharmony_ci if (error == PIXMA_EIO) 476141cc406Sopenharmony_ci error = PIXMA_ETIMEDOUT; /* FIXME: SANE doesn't have ETIMEDOUT!! */ 477141cc406Sopenharmony_ci if (count != len) 478141cc406Sopenharmony_ci { 479141cc406Sopenharmony_ci PDBG (pixma_dbg (1, "WARNING:pixma_write(): count(%u) != len(%u)\n", 480141cc406Sopenharmony_ci (unsigned) count, len)); 481141cc406Sopenharmony_ci error = PIXMA_EIO; 482141cc406Sopenharmony_ci } 483141cc406Sopenharmony_ci if (error >= 0) 484141cc406Sopenharmony_ci error = count; 485141cc406Sopenharmony_ci PDBG (pixma_dump (10, "OUT ", cmd, error, len, 128)); 486141cc406Sopenharmony_ci return error; 487141cc406Sopenharmony_ci} 488141cc406Sopenharmony_ci 489141cc406Sopenharmony_ciint 490141cc406Sopenharmony_cipixma_read (pixma_io_t * io, void *buf, unsigned size) 491141cc406Sopenharmony_ci{ 492141cc406Sopenharmony_ci size_t count = size; 493141cc406Sopenharmony_ci int error; 494141cc406Sopenharmony_ci 495141cc406Sopenharmony_ci if (io-> interface == INT_BJNP) 496141cc406Sopenharmony_ci { 497141cc406Sopenharmony_ci sanei_bjnp_set_timeout (io->dev, PIXMA_BULKIN_TIMEOUT); 498141cc406Sopenharmony_ci error = map_error (sanei_bjnp_read_bulk (io->dev, buf, &count)); 499141cc406Sopenharmony_ci } 500141cc406Sopenharmony_ci else 501141cc406Sopenharmony_ci { 502141cc406Sopenharmony_ci#ifdef HAVE_SANEI_USB_SET_TIMEOUT 503141cc406Sopenharmony_ci sanei_usb_set_timeout (PIXMA_BULKIN_TIMEOUT); 504141cc406Sopenharmony_ci#endif 505141cc406Sopenharmony_ci error = map_error (sanei_usb_read_bulk (io->dev, buf, &count)); 506141cc406Sopenharmony_ci } 507141cc406Sopenharmony_ci 508141cc406Sopenharmony_ci if (error == PIXMA_EIO) 509141cc406Sopenharmony_ci error = PIXMA_ETIMEDOUT; /* FIXME: SANE doesn't have ETIMEDOUT!! */ 510141cc406Sopenharmony_ci if (error >= 0) 511141cc406Sopenharmony_ci error = count; 512141cc406Sopenharmony_ci PDBG (pixma_dump (10, "IN ", buf, error, -1, 128)); 513141cc406Sopenharmony_ci return error; 514141cc406Sopenharmony_ci} 515141cc406Sopenharmony_ci 516141cc406Sopenharmony_ciint 517141cc406Sopenharmony_cipixma_wait_interrupt (pixma_io_t * io, void *buf, unsigned size, int timeout) 518141cc406Sopenharmony_ci{ 519141cc406Sopenharmony_ci size_t count = size; 520141cc406Sopenharmony_ci int error; 521141cc406Sopenharmony_ci 522141cc406Sopenharmony_ci /* FIXME: What is the meaning of "timeout" in sanei_usb? */ 523141cc406Sopenharmony_ci if (timeout < 0) 524141cc406Sopenharmony_ci timeout = INT_MAX; 525141cc406Sopenharmony_ci else if (timeout < 100) 526141cc406Sopenharmony_ci timeout = 100; 527141cc406Sopenharmony_ci if (io-> interface == INT_BJNP) 528141cc406Sopenharmony_ci { 529141cc406Sopenharmony_ci sanei_bjnp_set_timeout (io->dev, timeout); 530141cc406Sopenharmony_ci error = map_error (sanei_bjnp_read_int (io->dev, buf, &count)); 531141cc406Sopenharmony_ci } 532141cc406Sopenharmony_ci else 533141cc406Sopenharmony_ci { 534141cc406Sopenharmony_ci#ifdef HAVE_SANEI_USB_SET_TIMEOUT 535141cc406Sopenharmony_ci sanei_usb_set_timeout (timeout); 536141cc406Sopenharmony_ci#endif 537141cc406Sopenharmony_ci error = map_error (sanei_usb_read_int (io->dev, buf, &count)); 538141cc406Sopenharmony_ci } 539141cc406Sopenharmony_ci if (error == PIXMA_EIO || 540141cc406Sopenharmony_ci (io->interface == INT_BJNP && error == PIXMA_EOF)) /* EOF is a bjnp timeout error! */ 541141cc406Sopenharmony_ci error = PIXMA_ETIMEDOUT; /* FIXME: SANE doesn't have ETIMEDOUT!! */ 542141cc406Sopenharmony_ci if (error == 0) 543141cc406Sopenharmony_ci error = count; 544141cc406Sopenharmony_ci if (error != PIXMA_ETIMEDOUT) 545141cc406Sopenharmony_ci PDBG (pixma_dump (10, "INTR", buf, error, -1, -1)); 546141cc406Sopenharmony_ci return error; 547141cc406Sopenharmony_ci} 548141cc406Sopenharmony_ci 549141cc406Sopenharmony_ciint 550141cc406Sopenharmony_cipixma_set_interrupt_mode (pixma_io_t * s, int background) 551141cc406Sopenharmony_ci{ 552141cc406Sopenharmony_ci UNUSED (s); 553141cc406Sopenharmony_ci return (background) ? PIXMA_ENOTSUP : 0; 554141cc406Sopenharmony_ci} 555