1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 2003 James Perry 3141cc406Sopenharmony_ci This file is part of the SANE package. 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 6141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 7141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 8141cc406Sopenharmony_ci License, or (at your option) any later version. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 11141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13141cc406Sopenharmony_ci General Public License for more details. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 16141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 19141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 22141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 23141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 24141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 25141cc406Sopenharmony_ci account of linking the SANE library code into it. 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 28141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 29141cc406Sopenharmony_ci License. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 32141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 33141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 36141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 37141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 38141cc406Sopenharmony_ci 39141cc406Sopenharmony_ci This file implements the Mustek SCSI-over-parallel port protocol 40141cc406Sopenharmony_ci used by, for example, the Paragon 600 II EP 41141cc406Sopenharmony_ci*/ 42141cc406Sopenharmony_ci 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci/**************************************************************************/ 45141cc406Sopenharmony_ci#include "../include/sane/config.h" 46141cc406Sopenharmony_ci 47141cc406Sopenharmony_ci#include <ctype.h> 48141cc406Sopenharmony_ci#include <errno.h> 49141cc406Sopenharmony_ci#include <fcntl.h> 50141cc406Sopenharmony_ci#include <limits.h> 51141cc406Sopenharmony_ci#include <signal.h> 52141cc406Sopenharmony_ci#include <stdio.h> 53141cc406Sopenharmony_ci#include <stdlib.h> 54141cc406Sopenharmony_ci#include <string.h> 55141cc406Sopenharmony_ci#include <unistd.h> 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ci#include <sys/time.h> 58141cc406Sopenharmony_ci#include <sys/types.h> 59141cc406Sopenharmony_ci#include <sys/wait.h> 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_ci#include <time.h> 62141cc406Sopenharmony_ci 63141cc406Sopenharmony_ci#include "../include/sane/sane.h" 64141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 65141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 66141cc406Sopenharmony_ci#include "../include/sane/sanei_debug.h" 67141cc406Sopenharmony_ci#include "../include/sane/sanei_pa4s2.h" 68141cc406Sopenharmony_ci 69141cc406Sopenharmony_ci/* 70141cc406Sopenharmony_ci * Number of times to retry sending a SCSI command before giving up 71141cc406Sopenharmony_ci */ 72141cc406Sopenharmony_ci#define MUSTEK_SCSI_PP_NUM_RETRIES 4 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci/* 75141cc406Sopenharmony_ci * Internal middle-level API functionality 76141cc406Sopenharmony_ci */ 77141cc406Sopenharmony_cistatic int mustek_scsi_pp_timeout = 5000; 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_ci/* FIXME: use same method as mustek.c ? */ 80141cc406Sopenharmony_cistatic int 81141cc406Sopenharmony_cimustek_scsi_pp_get_time () 82141cc406Sopenharmony_ci{ 83141cc406Sopenharmony_ci struct timeval tv; 84141cc406Sopenharmony_ci int retval; 85141cc406Sopenharmony_ci 86141cc406Sopenharmony_ci gettimeofday (&tv, 0); 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci retval = tv.tv_sec * 1000 + tv.tv_usec / 1000; 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci return retval; 91141cc406Sopenharmony_ci} 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_cistatic u_char mustek_scsi_pp_register = 0; 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_cistatic SANE_Status 97141cc406Sopenharmony_cimustek_scsi_pp_select_register (int fd, u_char reg) 98141cc406Sopenharmony_ci{ 99141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_select_register: selecting register %d on fd %d\n", 100141cc406Sopenharmony_ci reg, fd); 101141cc406Sopenharmony_ci 102141cc406Sopenharmony_ci mustek_scsi_pp_register = reg; 103141cc406Sopenharmony_ci 104141cc406Sopenharmony_ci return sanei_pa4s2_scsi_pp_reg_select (fd, reg); 105141cc406Sopenharmony_ci} 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_cistatic SANE_Status 108141cc406Sopenharmony_cimustek_scsi_pp_wait_for_valid_status (int fd) 109141cc406Sopenharmony_ci{ 110141cc406Sopenharmony_ci int start_time; 111141cc406Sopenharmony_ci u_char status; 112141cc406Sopenharmony_ci 113141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_valid_status: entering\n"); 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_ci start_time = mustek_scsi_pp_get_time (); 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_ci do 118141cc406Sopenharmony_ci { 119141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 120141cc406Sopenharmony_ci { 121141cc406Sopenharmony_ci DBG (2, 122141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_valid_status: I/O error while getting status\n"); 123141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 124141cc406Sopenharmony_ci } 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci status &= 0xf0; 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_ci if ((status != 0xf0) && (!(status & 0x40)) && (status & 0x20)) 129141cc406Sopenharmony_ci { 130141cc406Sopenharmony_ci DBG (5, 131141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_valid_status: returning success\n"); 132141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 133141cc406Sopenharmony_ci } 134141cc406Sopenharmony_ci } 135141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - start_time) < mustek_scsi_pp_timeout); 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_valid_status: timed out\n"); 138141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 139141cc406Sopenharmony_ci} 140141cc406Sopenharmony_ci 141141cc406Sopenharmony_cistatic SANE_Status 142141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_5_set (int fd) 143141cc406Sopenharmony_ci{ 144141cc406Sopenharmony_ci int t; 145141cc406Sopenharmony_ci u_char status; 146141cc406Sopenharmony_ci 147141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_5_set: entering\n"); 148141cc406Sopenharmony_ci 149141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 150141cc406Sopenharmony_ci 151141cc406Sopenharmony_ci do 152141cc406Sopenharmony_ci { 153141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 154141cc406Sopenharmony_ci { 155141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_set: I/O error\n"); 156141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 157141cc406Sopenharmony_ci } 158141cc406Sopenharmony_ci if (status & 0x20) 159141cc406Sopenharmony_ci { 160141cc406Sopenharmony_ci DBG (5, 161141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_5_set: returning success\n"); 162141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 163141cc406Sopenharmony_ci } 164141cc406Sopenharmony_ci } 165141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 166141cc406Sopenharmony_ci 167141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_set: timed out\n"); 168141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 169141cc406Sopenharmony_ci} 170141cc406Sopenharmony_ci 171141cc406Sopenharmony_cistatic SANE_Status 172141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_5_clear (int fd) 173141cc406Sopenharmony_ci{ 174141cc406Sopenharmony_ci int t; 175141cc406Sopenharmony_ci u_char status; 176141cc406Sopenharmony_ci 177141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_5_clear: entering\n"); 178141cc406Sopenharmony_ci 179141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci do 182141cc406Sopenharmony_ci { 183141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 184141cc406Sopenharmony_ci { 185141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_clear: I/O error\n"); 186141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 187141cc406Sopenharmony_ci } 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci if (!(status & 0x20)) 190141cc406Sopenharmony_ci { 191141cc406Sopenharmony_ci DBG (5, 192141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_5_clear: returning success\n"); 193141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 194141cc406Sopenharmony_ci } 195141cc406Sopenharmony_ci } 196141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 197141cc406Sopenharmony_ci 198141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_5_clear: timed out\n"); 199141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 200141cc406Sopenharmony_ci} 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_cistatic SANE_Status 203141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_7_set (int fd) 204141cc406Sopenharmony_ci{ 205141cc406Sopenharmony_ci int t; 206141cc406Sopenharmony_ci u_char status; 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_7_set: entering\n"); 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 211141cc406Sopenharmony_ci do 212141cc406Sopenharmony_ci { 213141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 214141cc406Sopenharmony_ci { 215141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_set: I/O error\n"); 216141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 217141cc406Sopenharmony_ci } 218141cc406Sopenharmony_ci if (status & 0x80) 219141cc406Sopenharmony_ci { 220141cc406Sopenharmony_ci DBG (5, 221141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_7_set: returning success\n"); 222141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 223141cc406Sopenharmony_ci } 224141cc406Sopenharmony_ci } 225141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 226141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 227141cc406Sopenharmony_ci 228141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_set: timed out\n"); 229141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 230141cc406Sopenharmony_ci} 231141cc406Sopenharmony_ci 232141cc406Sopenharmony_cistatic SANE_Status 233141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_7_clear (int fd) 234141cc406Sopenharmony_ci{ 235141cc406Sopenharmony_ci int t; 236141cc406Sopenharmony_ci u_char status; 237141cc406Sopenharmony_ci 238141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_7_clear: entering\n"); 239141cc406Sopenharmony_ci 240141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 241141cc406Sopenharmony_ci do 242141cc406Sopenharmony_ci { 243141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 244141cc406Sopenharmony_ci { 245141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_clear: I/O error\n"); 246141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 247141cc406Sopenharmony_ci } 248141cc406Sopenharmony_ci if (!(status & 0x80)) 249141cc406Sopenharmony_ci { 250141cc406Sopenharmony_ci DBG (5, 251141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_7_clear: returning success\n"); 252141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 253141cc406Sopenharmony_ci } 254141cc406Sopenharmony_ci } 255141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 256141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 257141cc406Sopenharmony_ci 258141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_7_clear: timed out\n"); 259141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 260141cc406Sopenharmony_ci} 261141cc406Sopenharmony_ci 262141cc406Sopenharmony_cistatic SANE_Status 263141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_set (int fd) 264141cc406Sopenharmony_ci{ 265141cc406Sopenharmony_ci int t; 266141cc406Sopenharmony_ci u_char status; 267141cc406Sopenharmony_ci 268141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_set: entering\n"); 269141cc406Sopenharmony_ci 270141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 271141cc406Sopenharmony_ci { 272141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: I/O error\n"); 273141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 274141cc406Sopenharmony_ci } 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ci if (status & 0x10) 277141cc406Sopenharmony_ci { 278141cc406Sopenharmony_ci DBG (5, 279141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_set: returning success\n"); 280141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 281141cc406Sopenharmony_ci } 282141cc406Sopenharmony_ci 283141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 284141cc406Sopenharmony_ci do 285141cc406Sopenharmony_ci { 286141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 287141cc406Sopenharmony_ci { 288141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: I/O error\n"); 289141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 290141cc406Sopenharmony_ci } 291141cc406Sopenharmony_ci if (status & 0x40) 292141cc406Sopenharmony_ci { 293141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: bit 6 set\n"); 294141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 295141cc406Sopenharmony_ci } 296141cc406Sopenharmony_ci if (status & 0x10) 297141cc406Sopenharmony_ci { 298141cc406Sopenharmony_ci DBG (5, 299141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_set: returning success\n"); 300141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 301141cc406Sopenharmony_ci } 302141cc406Sopenharmony_ci } 303141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 304141cc406Sopenharmony_ci 305141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_set: timed out\n"); 306141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 307141cc406Sopenharmony_ci} 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_cistatic SANE_Status 310141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_clear (int fd) 311141cc406Sopenharmony_ci{ 312141cc406Sopenharmony_ci int t; 313141cc406Sopenharmony_ci u_char status; 314141cc406Sopenharmony_ci 315141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_clear: entering\n"); 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 318141cc406Sopenharmony_ci { 319141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: I/O error\n"); 320141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 321141cc406Sopenharmony_ci } 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci if (!(status & 0x10)) 324141cc406Sopenharmony_ci { 325141cc406Sopenharmony_ci DBG (5, 326141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_clear: returning success\n"); 327141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 328141cc406Sopenharmony_ci } 329141cc406Sopenharmony_ci 330141cc406Sopenharmony_ci t = mustek_scsi_pp_get_time (); 331141cc406Sopenharmony_ci do 332141cc406Sopenharmony_ci { 333141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 334141cc406Sopenharmony_ci { 335141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: I/O error\n"); 336141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 337141cc406Sopenharmony_ci } 338141cc406Sopenharmony_ci if (status & 0x40) 339141cc406Sopenharmony_ci { 340141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: bit 6 set\n"); 341141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 342141cc406Sopenharmony_ci } 343141cc406Sopenharmony_ci if (!(status & 0x10)) 344141cc406Sopenharmony_ci { 345141cc406Sopenharmony_ci DBG (5, 346141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_clear: returning success\n"); 347141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 348141cc406Sopenharmony_ci } 349141cc406Sopenharmony_ci } 350141cc406Sopenharmony_ci while ((mustek_scsi_pp_get_time () - t) < mustek_scsi_pp_timeout); 351141cc406Sopenharmony_ci 352141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_wait_for_status_bit_4_clear: timed out\n"); 353141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 354141cc406Sopenharmony_ci} 355141cc406Sopenharmony_ci 356141cc406Sopenharmony_cistatic u_char mustek_scsi_pp_bit_4_state = 0; 357141cc406Sopenharmony_ci 358141cc406Sopenharmony_cistatic SANE_Status 359141cc406Sopenharmony_cimustek_scsi_pp_wait_for_status_bit_4_toggle (int fd) 360141cc406Sopenharmony_ci{ 361141cc406Sopenharmony_ci SANE_Status result; 362141cc406Sopenharmony_ci 363141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_wait_for_status_bit_4_toggle: entering\n"); 364141cc406Sopenharmony_ci 365141cc406Sopenharmony_ci mustek_scsi_pp_bit_4_state ^= 0xff; 366141cc406Sopenharmony_ci if (mustek_scsi_pp_bit_4_state) 367141cc406Sopenharmony_ci { 368141cc406Sopenharmony_ci DBG (5, 369141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_toggle: waiting for set\n"); 370141cc406Sopenharmony_ci result = mustek_scsi_pp_wait_for_status_bit_4_set (fd); 371141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 5000; 372141cc406Sopenharmony_ci } 373141cc406Sopenharmony_ci else 374141cc406Sopenharmony_ci { 375141cc406Sopenharmony_ci DBG (5, 376141cc406Sopenharmony_ci "mustek_scsi_pp_wait_for_status_bit_4_toggle: waiting for clear\n"); 377141cc406Sopenharmony_ci result = mustek_scsi_pp_wait_for_status_bit_4_clear (fd); 378141cc406Sopenharmony_ci } 379141cc406Sopenharmony_ci 380141cc406Sopenharmony_ci return result; 381141cc406Sopenharmony_ci} 382141cc406Sopenharmony_ci 383141cc406Sopenharmony_cistatic SANE_Status 384141cc406Sopenharmony_cimustek_scsi_pp_send_command_byte (int fd, u_char cmd) 385141cc406Sopenharmony_ci{ 386141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_send_command byte: sending 0x%02X\n", cmd); 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_7_clear (fd) != SANE_STATUS_GOOD) 391141cc406Sopenharmony_ci { 392141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 393141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 394141cc406Sopenharmony_ci } 395141cc406Sopenharmony_ci 396141cc406Sopenharmony_ci if (sanei_pa4s2_writebyte (fd, mustek_scsi_pp_register, cmd) != 397141cc406Sopenharmony_ci SANE_STATUS_GOOD) 398141cc406Sopenharmony_ci { 399141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 400141cc406Sopenharmony_ci } 401141cc406Sopenharmony_ci 402141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 1); 403141cc406Sopenharmony_ci 404141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_7_set (fd) != SANE_STATUS_GOOD) 405141cc406Sopenharmony_ci { 406141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 407141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 408141cc406Sopenharmony_ci } 409141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 410141cc406Sopenharmony_ci 411141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_send_command_byte: returning success\n"); 412141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 413141cc406Sopenharmony_ci} 414141cc406Sopenharmony_ci 415141cc406Sopenharmony_cistatic u_char 416141cc406Sopenharmony_cimustek_scsi_pp_read_response (int fd) 417141cc406Sopenharmony_ci{ 418141cc406Sopenharmony_ci u_char result; 419141cc406Sopenharmony_ci 420141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_read_response: entering\n"); 421141cc406Sopenharmony_ci 422141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_7_set (fd) != SANE_STATUS_GOOD) 423141cc406Sopenharmony_ci { 424141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 425141cc406Sopenharmony_ci return 0xff; 426141cc406Sopenharmony_ci } 427141cc406Sopenharmony_ci 428141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != SANE_STATUS_GOOD) 429141cc406Sopenharmony_ci { 430141cc406Sopenharmony_ci return 0xff; 431141cc406Sopenharmony_ci } 432141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &result) != SANE_STATUS_GOOD) 433141cc406Sopenharmony_ci { 434141cc406Sopenharmony_ci return 0xff; 435141cc406Sopenharmony_ci } 436141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 437141cc406Sopenharmony_ci { 438141cc406Sopenharmony_ci return 0xff; 439141cc406Sopenharmony_ci } 440141cc406Sopenharmony_ci 441141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 1); 442141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_7_clear (fd) != SANE_STATUS_GOOD) 443141cc406Sopenharmony_ci { 444141cc406Sopenharmony_ci result = 0xff; 445141cc406Sopenharmony_ci } 446141cc406Sopenharmony_ci mustek_scsi_pp_select_register (fd, 0); 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_read_response: returning 0x%02X\n", result); 449141cc406Sopenharmony_ci return result; 450141cc406Sopenharmony_ci} 451141cc406Sopenharmony_ci 452141cc406Sopenharmony_cistatic SANE_Status 453141cc406Sopenharmony_cimustek_scsi_pp_check_response (int fd) 454141cc406Sopenharmony_ci{ 455141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_5_clear (fd) != SANE_STATUS_GOOD) 456141cc406Sopenharmony_ci { 457141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 458141cc406Sopenharmony_ci } 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci if (mustek_scsi_pp_read_response (fd) != 0xA5) 461141cc406Sopenharmony_ci { 462141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_check_response: response!=0xA5\n"); 463141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 464141cc406Sopenharmony_ci } 465141cc406Sopenharmony_ci 466141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_check_response: returning success\n"); 467141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 468141cc406Sopenharmony_ci} 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_cistatic SANE_Status 471141cc406Sopenharmony_cimustek_scsi_pp_send_command (int fd, const u_char * cmd) 472141cc406Sopenharmony_ci{ 473141cc406Sopenharmony_ci int i; 474141cc406Sopenharmony_ci signed char checksum; 475141cc406Sopenharmony_ci 476141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_send_command: sending SCSI command 0x%02X\n", 477141cc406Sopenharmony_ci cmd[0]); 478141cc406Sopenharmony_ci 479141cc406Sopenharmony_ci /* Set timeout depending on command type */ 480141cc406Sopenharmony_ci switch (cmd[0]) 481141cc406Sopenharmony_ci { 482141cc406Sopenharmony_ci case 0xf: 483141cc406Sopenharmony_ci case 0x8: 484141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 1000; 485141cc406Sopenharmony_ci break; 486141cc406Sopenharmony_ci case 0x2: 487141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 80; 488141cc406Sopenharmony_ci break; 489141cc406Sopenharmony_ci case 0x12: 490141cc406Sopenharmony_ci case 0x3: 491141cc406Sopenharmony_ci case 0x11: 492141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 500; 493141cc406Sopenharmony_ci break; 494141cc406Sopenharmony_ci default: 495141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 1000; 496141cc406Sopenharmony_ci break; 497141cc406Sopenharmony_ci } 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD) 500141cc406Sopenharmony_ci { 501141cc406Sopenharmony_ci DBG (2, 502141cc406Sopenharmony_ci "mustek_scsi_pp_send_command: timed out waiting for bit 5 to set\n"); 503141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 504141cc406Sopenharmony_ci } 505141cc406Sopenharmony_ci 506141cc406Sopenharmony_ci checksum = 0; 507141cc406Sopenharmony_ci for (i = 0; i < 6; i++) 508141cc406Sopenharmony_ci { 509141cc406Sopenharmony_ci if (mustek_scsi_pp_send_command_byte (fd, cmd[i]) != SANE_STATUS_GOOD) 510141cc406Sopenharmony_ci { 511141cc406Sopenharmony_ci DBG (2, 512141cc406Sopenharmony_ci "mustek_scsi_pp_send_command: error sending byte %d (0x%02X)\n", 513141cc406Sopenharmony_ci i, cmd[i]); 514141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 515141cc406Sopenharmony_ci } 516141cc406Sopenharmony_ci checksum += cmd[i]; 517141cc406Sopenharmony_ci } 518141cc406Sopenharmony_ci if (mustek_scsi_pp_send_command_byte (fd, -checksum) != SANE_STATUS_GOOD) 519141cc406Sopenharmony_ci { 520141cc406Sopenharmony_ci DBG (2, 521141cc406Sopenharmony_ci "mustek_scsi_pp_send_command: error sending checksum (0x%02X)\n", 522141cc406Sopenharmony_ci -checksum); 523141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 524141cc406Sopenharmony_ci } 525141cc406Sopenharmony_ci return mustek_scsi_pp_check_response (fd); 526141cc406Sopenharmony_ci} 527141cc406Sopenharmony_ci 528141cc406Sopenharmony_cistatic SANE_Status 529141cc406Sopenharmony_cimustek_scsi_pp_send_data_block (int fd, const u_char * data, int len) 530141cc406Sopenharmony_ci{ 531141cc406Sopenharmony_ci int i; 532141cc406Sopenharmony_ci signed char checksum; 533141cc406Sopenharmony_ci 534141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_send_data_block: sending block of length %d\n", 535141cc406Sopenharmony_ci len); 536141cc406Sopenharmony_ci 537141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD) 538141cc406Sopenharmony_ci { 539141cc406Sopenharmony_ci DBG (2, 540141cc406Sopenharmony_ci "mustek_scsi_pp_send_data_block: timed out waiting for bit 5 to set\n"); 541141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 542141cc406Sopenharmony_ci } 543141cc406Sopenharmony_ci 544141cc406Sopenharmony_ci checksum = 0; 545141cc406Sopenharmony_ci for (i = 0; i < len; i++) 546141cc406Sopenharmony_ci { 547141cc406Sopenharmony_ci if (mustek_scsi_pp_send_command_byte (fd, data[i]) != SANE_STATUS_GOOD) 548141cc406Sopenharmony_ci { 549141cc406Sopenharmony_ci DBG (2, 550141cc406Sopenharmony_ci "mustek_scsi_pp_send_data_block: error sending byte %d (0x%02X)\n", 551141cc406Sopenharmony_ci i, data[i]); 552141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 553141cc406Sopenharmony_ci } 554141cc406Sopenharmony_ci checksum += data[i]; 555141cc406Sopenharmony_ci } 556141cc406Sopenharmony_ci if (mustek_scsi_pp_send_command_byte (fd, -checksum) != SANE_STATUS_GOOD) 557141cc406Sopenharmony_ci { 558141cc406Sopenharmony_ci DBG (2, 559141cc406Sopenharmony_ci "mustek_scsi_pp_send_data_block: error sending checksum (0x%02X)\n", 560141cc406Sopenharmony_ci -checksum); 561141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 562141cc406Sopenharmony_ci } 563141cc406Sopenharmony_ci return mustek_scsi_pp_check_response (fd); 564141cc406Sopenharmony_ci} 565141cc406Sopenharmony_ci 566141cc406Sopenharmony_cistatic SANE_Status 567141cc406Sopenharmony_cimustek_scsi_pp_read_data_block (int fd, u_char * buffer, int len) 568141cc406Sopenharmony_ci{ 569141cc406Sopenharmony_ci int i; 570141cc406Sopenharmony_ci signed char checksum; 571141cc406Sopenharmony_ci 572141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_read_data_block: reading block of length %d\n", 573141cc406Sopenharmony_ci len); 574141cc406Sopenharmony_ci 575141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_5_clear (fd) != SANE_STATUS_GOOD) 576141cc406Sopenharmony_ci { 577141cc406Sopenharmony_ci DBG (2, 578141cc406Sopenharmony_ci "mustek_scsi_pp_read_data_block: timed out waiting for bit 5 to clear\n"); 579141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 580141cc406Sopenharmony_ci } 581141cc406Sopenharmony_ci 582141cc406Sopenharmony_ci checksum = 0; 583141cc406Sopenharmony_ci for (i = 0; i < len; i++) 584141cc406Sopenharmony_ci { 585141cc406Sopenharmony_ci buffer[i] = mustek_scsi_pp_read_response (fd); 586141cc406Sopenharmony_ci checksum += buffer[i]; 587141cc406Sopenharmony_ci } 588141cc406Sopenharmony_ci if ((signed char) mustek_scsi_pp_read_response (fd) != (-checksum)) 589141cc406Sopenharmony_ci { 590141cc406Sopenharmony_ci mustek_scsi_pp_send_command_byte (fd, 0xff); 591141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_read_data_block: checksums do not match\n"); 592141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 593141cc406Sopenharmony_ci } 594141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_5_set (fd) != SANE_STATUS_GOOD) 595141cc406Sopenharmony_ci { 596141cc406Sopenharmony_ci DBG (2, 597141cc406Sopenharmony_ci "mustek_scsi_pp_read_data_block: error waiting for bit 5 to set\n"); 598141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 599141cc406Sopenharmony_ci } 600141cc406Sopenharmony_ci if (mustek_scsi_pp_send_command_byte (fd, 0) != SANE_STATUS_GOOD) 601141cc406Sopenharmony_ci { 602141cc406Sopenharmony_ci mustek_scsi_pp_send_command_byte (fd, 0xff); 603141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_read_data_block: error sending final 0 byte\n"); 604141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 605141cc406Sopenharmony_ci } 606141cc406Sopenharmony_ci 607141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_read_data_block: returning success\n"); 608141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 609141cc406Sopenharmony_ci} 610141cc406Sopenharmony_ci 611141cc406Sopenharmony_ci 612141cc406Sopenharmony_ci 613141cc406Sopenharmony_ci/* 614141cc406Sopenharmony_ci * Externally visible functions 615141cc406Sopenharmony_ci */ 616141cc406Sopenharmony_ciSANE_Status 617141cc406Sopenharmony_cimustek_scsi_pp_open (const char *dev, int *fd) 618141cc406Sopenharmony_ci{ 619141cc406Sopenharmony_ci SANE_Status status; 620141cc406Sopenharmony_ci 621141cc406Sopenharmony_ci status = sanei_pa4s2_scsi_pp_open (dev, fd); 622141cc406Sopenharmony_ci if (status == SANE_STATUS_GOOD) 623141cc406Sopenharmony_ci { 624141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_open: device %s opened as fd %d\n", dev, *fd); 625141cc406Sopenharmony_ci } 626141cc406Sopenharmony_ci else 627141cc406Sopenharmony_ci { 628141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_open: error opening device %s\n", dev); 629141cc406Sopenharmony_ci } 630141cc406Sopenharmony_ci return status; 631141cc406Sopenharmony_ci} 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_cistatic void 634141cc406Sopenharmony_cimustek_scsi_pp_close (int fd) 635141cc406Sopenharmony_ci{ 636141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_close: closing fd %d\n", fd); 637141cc406Sopenharmony_ci sanei_pa4s2_close (fd); 638141cc406Sopenharmony_ci} 639141cc406Sopenharmony_ci 640141cc406Sopenharmony_cistatic void 641141cc406Sopenharmony_cimustek_scsi_pp_exit (void) 642141cc406Sopenharmony_ci{ 643141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_exit: entering\n"); 644141cc406Sopenharmony_ci} 645141cc406Sopenharmony_ci 646141cc406Sopenharmony_cistatic SANE_Status 647141cc406Sopenharmony_cimustek_scsi_pp_test_ready (int fd) 648141cc406Sopenharmony_ci{ 649141cc406Sopenharmony_ci u_char status; 650141cc406Sopenharmony_ci SANE_Status retval; 651141cc406Sopenharmony_ci 652141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_test_ready: entering with fd=%d\n", fd); 653141cc406Sopenharmony_ci 654141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD) 655141cc406Sopenharmony_ci { 656141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_test_ready: error enabling scanner\n"); 657141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 658141cc406Sopenharmony_ci } 659141cc406Sopenharmony_ci 660141cc406Sopenharmony_ci if (sanei_pa4s2_scsi_pp_get_status (fd, &status) != SANE_STATUS_GOOD) 661141cc406Sopenharmony_ci { 662141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_test_ready: error getting status\n"); 663141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 664141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 665141cc406Sopenharmony_ci } 666141cc406Sopenharmony_ci 667141cc406Sopenharmony_ci retval = SANE_STATUS_GOOD; 668141cc406Sopenharmony_ci 669141cc406Sopenharmony_ci status &= 0xf0; 670141cc406Sopenharmony_ci 671141cc406Sopenharmony_ci if (status == 0xf0) 672141cc406Sopenharmony_ci { 673141cc406Sopenharmony_ci retval = SANE_STATUS_DEVICE_BUSY; 674141cc406Sopenharmony_ci } 675141cc406Sopenharmony_ci if (status & 0x40) 676141cc406Sopenharmony_ci { 677141cc406Sopenharmony_ci retval = SANE_STATUS_DEVICE_BUSY; 678141cc406Sopenharmony_ci } 679141cc406Sopenharmony_ci if (!(status & 0x20)) 680141cc406Sopenharmony_ci { 681141cc406Sopenharmony_ci retval = SANE_STATUS_DEVICE_BUSY; 682141cc406Sopenharmony_ci } 683141cc406Sopenharmony_ci 684141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD) 685141cc406Sopenharmony_ci { 686141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_test_ready: error disabling scanner\n"); 687141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 688141cc406Sopenharmony_ci } 689141cc406Sopenharmony_ci 690141cc406Sopenharmony_ci if (retval == SANE_STATUS_GOOD) 691141cc406Sopenharmony_ci { 692141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_test_ready: returning SANE_STATUS_GOOD\n"); 693141cc406Sopenharmony_ci } 694141cc406Sopenharmony_ci else 695141cc406Sopenharmony_ci { 696141cc406Sopenharmony_ci DBG (5, 697141cc406Sopenharmony_ci "mustek_scsi_pp_test_ready: returning SANE_STATUS_DEVICE_BUSY\n"); 698141cc406Sopenharmony_ci } 699141cc406Sopenharmony_ci 700141cc406Sopenharmony_ci return retval; 701141cc406Sopenharmony_ci} 702141cc406Sopenharmony_ci 703141cc406Sopenharmony_cistatic SANE_Status 704141cc406Sopenharmony_cimustek_scsi_pp_cmd (int fd, const void *src, size_t src_size, 705141cc406Sopenharmony_ci void *dst, size_t * dst_size) 706141cc406Sopenharmony_ci{ 707141cc406Sopenharmony_ci SANE_Status stat; 708141cc406Sopenharmony_ci int num_tries = 0; 709141cc406Sopenharmony_ci static u_char scan_options = 0; 710141cc406Sopenharmony_ci const u_char *cmd; 711141cc406Sopenharmony_ci u_char stop_cmd[6] = { 0x1b, 0, 0, 0, 0, 0 }; 712141cc406Sopenharmony_ci int max_tries; 713141cc406Sopenharmony_ci 714141cc406Sopenharmony_ci max_tries = MUSTEK_SCSI_PP_NUM_RETRIES; 715141cc406Sopenharmony_ci 716141cc406Sopenharmony_ci cmd = (const u_char *) src; 717141cc406Sopenharmony_ci 718141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: sending command 0x%02X to device %d\n", 719141cc406Sopenharmony_ci cmd[0], fd); 720141cc406Sopenharmony_ci 721141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD) 722141cc406Sopenharmony_ci { 723141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: error enabling scanner\n"); 724141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 725141cc406Sopenharmony_ci } 726141cc406Sopenharmony_ci 727141cc406Sopenharmony_ci if (cmd[0] == 0x1b) 728141cc406Sopenharmony_ci { 729141cc406Sopenharmony_ci if (!(cmd[4] & 0x1)) 730141cc406Sopenharmony_ci { 731141cc406Sopenharmony_ci unsigned char c; 732141cc406Sopenharmony_ci int i; 733141cc406Sopenharmony_ci 734141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: doing stop-specific stuff\n"); 735141cc406Sopenharmony_ci 736141cc406Sopenharmony_ci /* 737141cc406Sopenharmony_ci * Remembers what flags were sent with a 'start' command, and 738141cc406Sopenharmony_ci * replicate them with a stop command. 739141cc406Sopenharmony_ci */ 740141cc406Sopenharmony_ci stop_cmd[4] = scan_options & 0xfe; 741141cc406Sopenharmony_ci cmd = &stop_cmd[0]; 742141cc406Sopenharmony_ci 743141cc406Sopenharmony_ci /* 744141cc406Sopenharmony_ci * In color mode at least, the scanner doesn't seem to like stopping at 745141cc406Sopenharmony_ci * the end. It's a bit of a horrible hack, but reading loads of bytes and 746141cc406Sopenharmony_ci * allowing 20 tries for the stop command is the only way I've found that 747141cc406Sopenharmony_ci * solves the problem. 748141cc406Sopenharmony_ci */ 749141cc406Sopenharmony_ci max_tries = 20; 750141cc406Sopenharmony_ci 751141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != 752141cc406Sopenharmony_ci SANE_STATUS_GOOD) 753141cc406Sopenharmony_ci { 754141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: error in readbegin for stop\n"); 755141cc406Sopenharmony_ci } 756141cc406Sopenharmony_ci 757141cc406Sopenharmony_ci for (i = 0; i < 10000; i++) 758141cc406Sopenharmony_ci { 759141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &c) != SANE_STATUS_GOOD) 760141cc406Sopenharmony_ci { 761141cc406Sopenharmony_ci DBG (2, 762141cc406Sopenharmony_ci "mustek_scsi_pp_cmd: error reading byte for stop\n"); 763141cc406Sopenharmony_ci break; 764141cc406Sopenharmony_ci } 765141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: successfully read byte %d\n", i); 766141cc406Sopenharmony_ci } 767141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 768141cc406Sopenharmony_ci { 769141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: error in readend for stop\n"); 770141cc406Sopenharmony_ci } 771141cc406Sopenharmony_ci } 772141cc406Sopenharmony_ci } 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci if (cmd[0] == 0x08) 775141cc406Sopenharmony_ci { 776141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: doing read-specific stuff\n"); 777141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 30000; 778141cc406Sopenharmony_ci mustek_scsi_pp_bit_4_state = 0xff; 779141cc406Sopenharmony_ci } 780141cc406Sopenharmony_ci 781141cc406Sopenharmony_ci /* 782141cc406Sopenharmony_ci * Send the command itself in one block, then any extra input data in a second 783141cc406Sopenharmony_ci * block. Not sure if that's necessary. 784141cc406Sopenharmony_ci */ 785141cc406Sopenharmony_ci if (src_size < 6) 786141cc406Sopenharmony_ci { 787141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 788141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: source size is only %lu (<6)\n", (u_long) src_size); 789141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 790141cc406Sopenharmony_ci } 791141cc406Sopenharmony_ci 792141cc406Sopenharmony_ci /* 793141cc406Sopenharmony_ci * Retry the command several times, as occasionally it doesn't 794141cc406Sopenharmony_ci * work first time. 795141cc406Sopenharmony_ci */ 796141cc406Sopenharmony_ci do 797141cc406Sopenharmony_ci { 798141cc406Sopenharmony_ci stat = mustek_scsi_pp_send_command (fd, cmd); 799141cc406Sopenharmony_ci num_tries++; 800141cc406Sopenharmony_ci } 801141cc406Sopenharmony_ci while ((stat != SANE_STATUS_GOOD) && (num_tries < max_tries)); 802141cc406Sopenharmony_ci 803141cc406Sopenharmony_ci if (stat != SANE_STATUS_GOOD) 804141cc406Sopenharmony_ci { 805141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 806141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: sending command failed\n"); 807141cc406Sopenharmony_ci return stat; 808141cc406Sopenharmony_ci } 809141cc406Sopenharmony_ci 810141cc406Sopenharmony_ci if (src_size > 6) 811141cc406Sopenharmony_ci { 812141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: sending data block of length %lu\n", 813141cc406Sopenharmony_ci (u_long) (src_size - 6)); 814141cc406Sopenharmony_ci 815141cc406Sopenharmony_ci stat = 816141cc406Sopenharmony_ci mustek_scsi_pp_send_data_block (fd, ((const u_char *) src) + 6, 817141cc406Sopenharmony_ci src_size - 6); 818141cc406Sopenharmony_ci if (stat != SANE_STATUS_GOOD) 819141cc406Sopenharmony_ci { 820141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 821141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: sending data block failed\n"); 822141cc406Sopenharmony_ci return stat; 823141cc406Sopenharmony_ci } 824141cc406Sopenharmony_ci } 825141cc406Sopenharmony_ci 826141cc406Sopenharmony_ci 827141cc406Sopenharmony_ci if (dst) 828141cc406Sopenharmony_ci { 829141cc406Sopenharmony_ci unsigned int length; 830141cc406Sopenharmony_ci 831141cc406Sopenharmony_ci /* check buffer is big enough to receive data */ 832141cc406Sopenharmony_ci length = (cmd[3] << 8) | cmd[4]; 833141cc406Sopenharmony_ci 834141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: reading %d bytes\n", length); 835141cc406Sopenharmony_ci 836141cc406Sopenharmony_ci if (length > *dst_size) 837141cc406Sopenharmony_ci { 838141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 839141cc406Sopenharmony_ci DBG (2, 840141cc406Sopenharmony_ci "mustek_scsi_pp_cmd: buffer (size %lu) not big enough for data (size %d)\n", 841141cc406Sopenharmony_ci (u_long) *dst_size, length); 842141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 843141cc406Sopenharmony_ci } 844141cc406Sopenharmony_ci 845141cc406Sopenharmony_ci stat = mustek_scsi_pp_read_data_block (fd, dst, length); 846141cc406Sopenharmony_ci if (stat != SANE_STATUS_GOOD) 847141cc406Sopenharmony_ci { 848141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: error reading data block\n"); 849141cc406Sopenharmony_ci } 850141cc406Sopenharmony_ci } 851141cc406Sopenharmony_ci 852141cc406Sopenharmony_ci if (cmd[0] == 0x1b) 853141cc406Sopenharmony_ci { 854141cc406Sopenharmony_ci if (cmd[4] & 0x1) 855141cc406Sopenharmony_ci { 856141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: doing start-specific stuff\n"); 857141cc406Sopenharmony_ci 858141cc406Sopenharmony_ci scan_options = cmd[4]; 859141cc406Sopenharmony_ci 860141cc406Sopenharmony_ci /* 'Start' command - wait for valid status */ 861141cc406Sopenharmony_ci mustek_scsi_pp_timeout = 70000; 862141cc406Sopenharmony_ci stat = mustek_scsi_pp_wait_for_valid_status (fd); 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_ci if (stat != SANE_STATUS_GOOD) 865141cc406Sopenharmony_ci { 866141cc406Sopenharmony_ci DBG (2, 867141cc406Sopenharmony_ci "mustek_scsi_pp_cmd: error waiting for valid status after start\n"); 868141cc406Sopenharmony_ci } 869141cc406Sopenharmony_ci } 870141cc406Sopenharmony_ci } 871141cc406Sopenharmony_ci 872141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD) 873141cc406Sopenharmony_ci { 874141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_cmd: error disabling scanner\n"); 875141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 876141cc406Sopenharmony_ci } 877141cc406Sopenharmony_ci 878141cc406Sopenharmony_ci if (stat == SANE_STATUS_GOOD) 879141cc406Sopenharmony_ci { 880141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_cmd: returning success\n"); 881141cc406Sopenharmony_ci } 882141cc406Sopenharmony_ci 883141cc406Sopenharmony_ci return stat; 884141cc406Sopenharmony_ci} 885141cc406Sopenharmony_ci 886141cc406Sopenharmony_cistatic SANE_Status 887141cc406Sopenharmony_cimustek_scsi_pp_rdata (int fd, int planes, SANE_Byte * buf, int lines, int bpl) 888141cc406Sopenharmony_ci{ 889141cc406Sopenharmony_ci int i, j; 890141cc406Sopenharmony_ci 891141cc406Sopenharmony_ci DBG (5, 892141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: reading %d lines at %d bpl, %d planes from %d\n", 893141cc406Sopenharmony_ci lines, bpl, planes, fd); 894141cc406Sopenharmony_ci 895141cc406Sopenharmony_ci if ((planes != 1) && (planes != 3)) 896141cc406Sopenharmony_ci { 897141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_rdata: invalid number of planes (%d)\n", 898141cc406Sopenharmony_ci planes); 899141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 900141cc406Sopenharmony_ci } 901141cc406Sopenharmony_ci 902141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_TRUE) != SANE_STATUS_GOOD) 903141cc406Sopenharmony_ci { 904141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_rdata: error enabling scanner\n"); 905141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 906141cc406Sopenharmony_ci } 907141cc406Sopenharmony_ci 908141cc406Sopenharmony_ci for (i = 0; i < lines; i++) 909141cc406Sopenharmony_ci { 910141cc406Sopenharmony_ci if (planes == 3) 911141cc406Sopenharmony_ci { 912141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) != 913141cc406Sopenharmony_ci SANE_STATUS_GOOD) 914141cc406Sopenharmony_ci { 915141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 916141cc406Sopenharmony_ci DBG (2, 917141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for red, line %d\n", 918141cc406Sopenharmony_ci i); 919141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 920141cc406Sopenharmony_ci } 921141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != 922141cc406Sopenharmony_ci SANE_STATUS_GOOD) 923141cc406Sopenharmony_ci { 924141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 925141cc406Sopenharmony_ci DBG (2, 926141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readbegin for red, line %d\n", 927141cc406Sopenharmony_ci i); 928141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 929141cc406Sopenharmony_ci } 930141cc406Sopenharmony_ci for (j = 0; j < (bpl / 3); j++) 931141cc406Sopenharmony_ci { 932141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &buf[j]) != SANE_STATUS_GOOD) 933141cc406Sopenharmony_ci { 934141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 935141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 936141cc406Sopenharmony_ci DBG (2, 937141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error reading red byte, line %d, byte %d\n", 938141cc406Sopenharmony_ci i, j); 939141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 940141cc406Sopenharmony_ci } 941141cc406Sopenharmony_ci } 942141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 943141cc406Sopenharmony_ci { 944141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 945141cc406Sopenharmony_ci DBG (2, 946141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readend for red, line %d\n", 947141cc406Sopenharmony_ci i); 948141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 949141cc406Sopenharmony_ci } 950141cc406Sopenharmony_ci 951141cc406Sopenharmony_ci 952141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) != 953141cc406Sopenharmony_ci SANE_STATUS_GOOD) 954141cc406Sopenharmony_ci { 955141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 956141cc406Sopenharmony_ci DBG (2, 957141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for green, line %d\n", 958141cc406Sopenharmony_ci i); 959141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 960141cc406Sopenharmony_ci } 961141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != 962141cc406Sopenharmony_ci SANE_STATUS_GOOD) 963141cc406Sopenharmony_ci { 964141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 965141cc406Sopenharmony_ci DBG (2, 966141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readbegin for green, line %d\n", 967141cc406Sopenharmony_ci i); 968141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 969141cc406Sopenharmony_ci } 970141cc406Sopenharmony_ci for (j = 0; j < (bpl / 3); j++) 971141cc406Sopenharmony_ci { 972141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &buf[j + (bpl / 3)]) != 973141cc406Sopenharmony_ci SANE_STATUS_GOOD) 974141cc406Sopenharmony_ci { 975141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 976141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 977141cc406Sopenharmony_ci DBG (2, 978141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error reading green byte, line %d, byte %d\n", 979141cc406Sopenharmony_ci i, j); 980141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 981141cc406Sopenharmony_ci } 982141cc406Sopenharmony_ci } 983141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 984141cc406Sopenharmony_ci { 985141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 986141cc406Sopenharmony_ci DBG (2, 987141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readend for green, line %d\n", 988141cc406Sopenharmony_ci i); 989141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 990141cc406Sopenharmony_ci } 991141cc406Sopenharmony_ci 992141cc406Sopenharmony_ci 993141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) != 994141cc406Sopenharmony_ci SANE_STATUS_GOOD) 995141cc406Sopenharmony_ci { 996141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 997141cc406Sopenharmony_ci DBG (2, 998141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error waiting for bit 4 toggle for blue, line %d\n", 999141cc406Sopenharmony_ci i); 1000141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1001141cc406Sopenharmony_ci } 1002141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != 1003141cc406Sopenharmony_ci SANE_STATUS_GOOD) 1004141cc406Sopenharmony_ci { 1005141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1006141cc406Sopenharmony_ci DBG (2, 1007141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readbegin for blue, line %d\n", 1008141cc406Sopenharmony_ci i); 1009141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1010141cc406Sopenharmony_ci } 1011141cc406Sopenharmony_ci for (j = 0; j < (bpl / 3); j++) 1012141cc406Sopenharmony_ci { 1013141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &buf[j + (2 * (bpl / 3))]) != 1014141cc406Sopenharmony_ci SANE_STATUS_GOOD) 1015141cc406Sopenharmony_ci { 1016141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 1017141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1018141cc406Sopenharmony_ci DBG (2, 1019141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error reading blue byte, line %d, byte %d\n", 1020141cc406Sopenharmony_ci i, j); 1021141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1022141cc406Sopenharmony_ci } 1023141cc406Sopenharmony_ci } 1024141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 1025141cc406Sopenharmony_ci { 1026141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1027141cc406Sopenharmony_ci DBG (2, 1028141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error in readend for blue, line %d\n", 1029141cc406Sopenharmony_ci i); 1030141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1031141cc406Sopenharmony_ci } 1032141cc406Sopenharmony_ci } 1033141cc406Sopenharmony_ci else 1034141cc406Sopenharmony_ci { 1035141cc406Sopenharmony_ci if (mustek_scsi_pp_wait_for_status_bit_4_toggle (fd) != 1036141cc406Sopenharmony_ci SANE_STATUS_GOOD) 1037141cc406Sopenharmony_ci { 1038141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1039141cc406Sopenharmony_ci DBG (2, 1040141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error waiting for bit 4 toggle, line %d\n", 1041141cc406Sopenharmony_ci i); 1042141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1043141cc406Sopenharmony_ci } 1044141cc406Sopenharmony_ci if (sanei_pa4s2_readbegin (fd, mustek_scsi_pp_register) != 1045141cc406Sopenharmony_ci SANE_STATUS_GOOD) 1046141cc406Sopenharmony_ci { 1047141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1048141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_rdata: error in readbegin, line %d\n", 1049141cc406Sopenharmony_ci i); 1050141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1051141cc406Sopenharmony_ci } 1052141cc406Sopenharmony_ci 1053141cc406Sopenharmony_ci for (j = 0; j < bpl; j++) 1054141cc406Sopenharmony_ci { 1055141cc406Sopenharmony_ci if (sanei_pa4s2_readbyte (fd, &buf[j]) != SANE_STATUS_GOOD) 1056141cc406Sopenharmony_ci { 1057141cc406Sopenharmony_ci sanei_pa4s2_readend (fd); 1058141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1059141cc406Sopenharmony_ci DBG (2, 1060141cc406Sopenharmony_ci "mustek_scsi_pp_rdata: error reading byte, line %d, byte %d\n", 1061141cc406Sopenharmony_ci i, j); 1062141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1063141cc406Sopenharmony_ci } 1064141cc406Sopenharmony_ci } 1065141cc406Sopenharmony_ci 1066141cc406Sopenharmony_ci if (sanei_pa4s2_readend (fd) != SANE_STATUS_GOOD) 1067141cc406Sopenharmony_ci { 1068141cc406Sopenharmony_ci sanei_pa4s2_enable (fd, SANE_FALSE); 1069141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_rdata: error in readend, line %d\n", i); 1070141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1071141cc406Sopenharmony_ci } 1072141cc406Sopenharmony_ci } 1073141cc406Sopenharmony_ci buf += bpl; 1074141cc406Sopenharmony_ci } 1075141cc406Sopenharmony_ci 1076141cc406Sopenharmony_ci if (sanei_pa4s2_enable (fd, SANE_FALSE) != SANE_STATUS_GOOD) 1077141cc406Sopenharmony_ci { 1078141cc406Sopenharmony_ci DBG (2, "mustek_scsi_pp_rdata: error enabling scanner\n"); 1079141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1080141cc406Sopenharmony_ci } 1081141cc406Sopenharmony_ci 1082141cc406Sopenharmony_ci DBG (5, "mustek_scsi_pp_rdata: returning success\n"); 1083141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1084141cc406Sopenharmony_ci} 1085