1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 1998 F.W. Dillema (dillema@acm.org) 3141cc406Sopenharmony_ci 4141cc406Sopenharmony_ci This file is part of the SANE package. 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 7141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 8141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 9141cc406Sopenharmony_ci License, or (at your option) any later version. 10141cc406Sopenharmony_ci 11141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 12141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 13141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14141cc406Sopenharmony_ci General Public License for more details. 15141cc406Sopenharmony_ci 16141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 17141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 20141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 23141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 24141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 25141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 26141cc406Sopenharmony_ci account of linking the SANE library code into it. 27141cc406Sopenharmony_ci 28141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 29141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 30141cc406Sopenharmony_ci License. 31141cc406Sopenharmony_ci 32141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 33141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 34141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 37141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 38141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 39141cc406Sopenharmony_ci*/ 40141cc406Sopenharmony_ci 41141cc406Sopenharmony_ci/* 42141cc406Sopenharmony_ci This file implements the low-level scsi-commands. 43141cc406Sopenharmony_ci*/ 44141cc406Sopenharmony_ci 45141cc406Sopenharmony_ci/* SCSI commands that the Ricoh scanners understand: */ 46141cc406Sopenharmony_ci#define RICOH_SCSI_TEST_UNIT_READY 0x00 47141cc406Sopenharmony_ci#define RICOH_SCSI_SET_WINDOW 0x24 48141cc406Sopenharmony_ci#define RICOH_SCSI_GET_WINDOW 0x25 49141cc406Sopenharmony_ci#define RICOH_SCSI_READ_SCANNED_DATA 0x28 50141cc406Sopenharmony_ci#define RICOH_SCSI_INQUIRY 0x12 51141cc406Sopenharmony_ci#define RICOH_SCSI_MODE_SELECT 0x15 52141cc406Sopenharmony_ci#define RICOH_SCSI_START_SCAN 0x1b 53141cc406Sopenharmony_ci#define RICOH_SCSI_MODE_SENSE 0x1a 54141cc406Sopenharmony_ci#define RICOH_SCSI_GET_BUFFER_STATUS 0x34 55141cc406Sopenharmony_ci#define RICOH_SCSI_OBJECT_POSITION 0x31 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ci/* How long do we wait for scanner to have data for us */ 58141cc406Sopenharmony_ci#define MAX_WAITING_TIME 15 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_cistruct scsi_window_cmd { 61141cc406Sopenharmony_ci SANE_Byte opcode; 62141cc406Sopenharmony_ci SANE_Byte byte2; 63141cc406Sopenharmony_ci SANE_Byte reserved[4]; 64141cc406Sopenharmony_ci SANE_Byte len[3]; 65141cc406Sopenharmony_ci SANE_Byte control; 66141cc406Sopenharmony_ci}; 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_cistruct scsi_mode_select_cmd { 69141cc406Sopenharmony_ci SANE_Byte opcode; 70141cc406Sopenharmony_ci SANE_Byte byte2; 71141cc406Sopenharmony_ci#define SMS_SP 0x01 72141cc406Sopenharmony_ci#define SMS_PF 0x10 73141cc406Sopenharmony_ci SANE_Byte page_code; /* for mode_sense, reserved for mode_select */ 74141cc406Sopenharmony_ci SANE_Byte unused[1]; 75141cc406Sopenharmony_ci SANE_Byte len; 76141cc406Sopenharmony_ci SANE_Byte control; 77141cc406Sopenharmony_ci}; 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_cistruct scsi_mode_header { 80141cc406Sopenharmony_ci SANE_Byte data_length; /* Sense data length */ 81141cc406Sopenharmony_ci SANE_Byte medium_type; 82141cc406Sopenharmony_ci SANE_Byte dev_spec; 83141cc406Sopenharmony_ci SANE_Byte blk_desc_len; 84141cc406Sopenharmony_ci}; 85141cc406Sopenharmony_ci 86141cc406Sopenharmony_cistruct scsi_get_buffer_status_cmd { 87141cc406Sopenharmony_ci SANE_Byte opcode; 88141cc406Sopenharmony_ci SANE_Byte byte2; 89141cc406Sopenharmony_ci SANE_Byte res[5]; 90141cc406Sopenharmony_ci SANE_Byte len[2]; 91141cc406Sopenharmony_ci SANE_Byte control; 92141cc406Sopenharmony_ci}; 93141cc406Sopenharmony_ci 94141cc406Sopenharmony_cistruct scsi_status_desc { 95141cc406Sopenharmony_ci SANE_Byte window_id; 96141cc406Sopenharmony_ci SANE_Byte byte2; 97141cc406Sopenharmony_ci SANE_Byte available[3]; 98141cc406Sopenharmony_ci SANE_Byte filled[3]; 99141cc406Sopenharmony_ci}; 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_cistruct scsi_status_data { 102141cc406Sopenharmony_ci SANE_Byte len[3]; 103141cc406Sopenharmony_ci SANE_Byte byte4; 104141cc406Sopenharmony_ci struct scsi_status_desc desc; 105141cc406Sopenharmony_ci}; 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_cistruct scsi_start_scan_cmd { 108141cc406Sopenharmony_ci SANE_Byte opcode; 109141cc406Sopenharmony_ci SANE_Byte byte2; 110141cc406Sopenharmony_ci SANE_Byte unused[2]; 111141cc406Sopenharmony_ci SANE_Byte len; 112141cc406Sopenharmony_ci SANE_Byte control; 113141cc406Sopenharmony_ci}; 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_cistruct scsi_read_scanner_cmd { 116141cc406Sopenharmony_ci SANE_Byte opcode; 117141cc406Sopenharmony_ci SANE_Byte byte2; 118141cc406Sopenharmony_ci SANE_Byte data_type; 119141cc406Sopenharmony_ci SANE_Byte byte3; 120141cc406Sopenharmony_ci SANE_Byte data_type_qualifier[2]; 121141cc406Sopenharmony_ci SANE_Byte len[3]; 122141cc406Sopenharmony_ci SANE_Byte control; 123141cc406Sopenharmony_ci}; 124141cc406Sopenharmony_ci 125141cc406Sopenharmony_cistatic SANE_Status 126141cc406Sopenharmony_citest_unit_ready (int fd) 127141cc406Sopenharmony_ci{ 128141cc406Sopenharmony_ci static SANE_Byte cmd[6]; 129141cc406Sopenharmony_ci SANE_Status status; 130141cc406Sopenharmony_ci DBG (11, ">> test_unit_ready\n"); 131141cc406Sopenharmony_ci 132141cc406Sopenharmony_ci cmd[0] = RICOH_SCSI_TEST_UNIT_READY; 133141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 134141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci DBG (11, "<< test_unit_ready\n"); 137141cc406Sopenharmony_ci return (status); 138141cc406Sopenharmony_ci} 139141cc406Sopenharmony_ci 140141cc406Sopenharmony_cistatic SANE_Status 141141cc406Sopenharmony_ciinquiry (int fd, void *buf, size_t * buf_size) 142141cc406Sopenharmony_ci{ 143141cc406Sopenharmony_ci static SANE_Byte cmd[6]; 144141cc406Sopenharmony_ci SANE_Status status; 145141cc406Sopenharmony_ci DBG (11, ">> inquiry\n"); 146141cc406Sopenharmony_ci 147141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 148141cc406Sopenharmony_ci cmd[0] = RICOH_SCSI_INQUIRY; 149141cc406Sopenharmony_ci cmd[4] = *buf_size; 150141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size); 151141cc406Sopenharmony_ci 152141cc406Sopenharmony_ci DBG (11, "<< inquiry\n"); 153141cc406Sopenharmony_ci return (status); 154141cc406Sopenharmony_ci} 155141cc406Sopenharmony_ci 156141cc406Sopenharmony_cistatic SANE_Status 157141cc406Sopenharmony_cimode_select (int fd, struct mode_pages *mp) 158141cc406Sopenharmony_ci{ 159141cc406Sopenharmony_ci static struct { 160141cc406Sopenharmony_ci struct scsi_mode_select_cmd cmd; 161141cc406Sopenharmony_ci struct scsi_mode_header smh; 162141cc406Sopenharmony_ci struct mode_pages mp; 163141cc406Sopenharmony_ci } select_cmd; 164141cc406Sopenharmony_ci SANE_Status status; 165141cc406Sopenharmony_ci DBG (11, ">> mode_select\n"); 166141cc406Sopenharmony_ci 167141cc406Sopenharmony_ci memset (&select_cmd, 0, sizeof (select_cmd)); 168141cc406Sopenharmony_ci select_cmd.cmd.opcode = RICOH_SCSI_MODE_SELECT; 169141cc406Sopenharmony_ci select_cmd.cmd.byte2 |= SMS_PF; 170141cc406Sopenharmony_ci select_cmd.cmd.len = sizeof(select_cmd.smh) + sizeof(select_cmd.mp); 171141cc406Sopenharmony_ci memcpy (&select_cmd.mp, mp, sizeof(*mp)); 172141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &select_cmd, sizeof (select_cmd), 0, 0); 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_ci DBG (11, "<< mode_select\n"); 175141cc406Sopenharmony_ci return (status); 176141cc406Sopenharmony_ci} 177141cc406Sopenharmony_ci 178141cc406Sopenharmony_ci#if 0 179141cc406Sopenharmony_cistatic SANE_Status 180141cc406Sopenharmony_cimode_sense (int fd, struct mode_pages *mp, SANE_Byte page_code) 181141cc406Sopenharmony_ci{ 182141cc406Sopenharmony_ci static struct scsi_mode_select_cmd cmd; /* no type, we can reuse it for sensing */ 183141cc406Sopenharmony_ci static struct { 184141cc406Sopenharmony_ci struct scsi_mode_header smh; 185141cc406Sopenharmony_ci struct mode_pages mp; 186141cc406Sopenharmony_ci } select_data; 187141cc406Sopenharmony_ci static size_t select_size = sizeof(select_data); 188141cc406Sopenharmony_ci SANE_Status status; 189141cc406Sopenharmony_ci DBG (11, ">> mode_sense\n"); 190141cc406Sopenharmony_ci 191141cc406Sopenharmony_ci memset (&cmd, 0, sizeof (cmd)); 192141cc406Sopenharmony_ci cmd.opcode = RICOH_SCSI_MODE_SENSE; 193141cc406Sopenharmony_ci cmd.page_code = page_code; 194141cc406Sopenharmony_ci cmd.len = sizeof(select_data); 195141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &select_data, &select_size); 196141cc406Sopenharmony_ci memcpy (mp, &select_data.mp, sizeof(*mp)); 197141cc406Sopenharmony_ci 198141cc406Sopenharmony_ci DBG (11, "<< mode_sense\n"); 199141cc406Sopenharmony_ci return (status); 200141cc406Sopenharmony_ci} 201141cc406Sopenharmony_ci#endif 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_cistatic SANE_Status 204141cc406Sopenharmony_citrigger_scan (int fd) 205141cc406Sopenharmony_ci{ 206141cc406Sopenharmony_ci static struct scsi_start_scan_cmd cmd; 207141cc406Sopenharmony_ci static char window_id_list[1] = { '\0' }; /* scan start data out */ 208141cc406Sopenharmony_ci static size_t wl_size = 1; 209141cc406Sopenharmony_ci SANE_Status status; 210141cc406Sopenharmony_ci DBG (11, ">> trigger scan\n"); 211141cc406Sopenharmony_ci 212141cc406Sopenharmony_ci memset (&cmd, 0, sizeof (cmd)); 213141cc406Sopenharmony_ci cmd.opcode = RICOH_SCSI_START_SCAN; 214141cc406Sopenharmony_ci cmd.len = wl_size; 215141cc406Sopenharmony_ci if (wl_size) 216141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &window_id_list, &wl_size); 217141cc406Sopenharmony_ci else 218141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), 0, 0); 219141cc406Sopenharmony_ci 220141cc406Sopenharmony_ci DBG (11, "<< trigger scan\n"); 221141cc406Sopenharmony_ci return (status); 222141cc406Sopenharmony_ci} 223141cc406Sopenharmony_ci 224141cc406Sopenharmony_cistatic SANE_Status 225141cc406Sopenharmony_ciset_window (int fd, struct ricoh_window_data *rwd) 226141cc406Sopenharmony_ci{ 227141cc406Sopenharmony_ci 228141cc406Sopenharmony_ci static struct { 229141cc406Sopenharmony_ci struct scsi_window_cmd cmd; 230141cc406Sopenharmony_ci struct ricoh_window_data rwd; 231141cc406Sopenharmony_ci } win; 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci SANE_Status status; 234141cc406Sopenharmony_ci DBG (11, ">> set_window\n"); 235141cc406Sopenharmony_ci 236141cc406Sopenharmony_ci memset (&win, 0, sizeof (win)); 237141cc406Sopenharmony_ci win.cmd.opcode = RICOH_SCSI_SET_WINDOW; 238141cc406Sopenharmony_ci _lto3b(sizeof(*rwd), win.cmd.len); 239141cc406Sopenharmony_ci memcpy (&win.rwd, rwd, sizeof(*rwd)); 240141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &win, sizeof (win), 0, 0); 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci DBG (11, "<< set_window\n"); 243141cc406Sopenharmony_ci return (status); 244141cc406Sopenharmony_ci} 245141cc406Sopenharmony_ci 246141cc406Sopenharmony_cistatic SANE_Status 247141cc406Sopenharmony_ciget_window (int fd, struct ricoh_window_data *rwd) 248141cc406Sopenharmony_ci{ 249141cc406Sopenharmony_ci 250141cc406Sopenharmony_ci static struct scsi_window_cmd cmd; 251141cc406Sopenharmony_ci static size_t rwd_size; 252141cc406Sopenharmony_ci SANE_Status status; 253141cc406Sopenharmony_ci 254141cc406Sopenharmony_ci rwd_size = sizeof(*rwd); 255141cc406Sopenharmony_ci DBG (11, ">> get_window datalen = %lu\n", (unsigned long) rwd_size); 256141cc406Sopenharmony_ci 257141cc406Sopenharmony_ci memset (&cmd, 0, sizeof (cmd)); 258141cc406Sopenharmony_ci cmd.opcode = RICOH_SCSI_GET_WINDOW; 259141cc406Sopenharmony_ci#if 0 260141cc406Sopenharmony_ci cmd.byte2 |= (SANE_Byte)0x01; /* set Single bit to get one window desc. */ 261141cc406Sopenharmony_ci#endif 262141cc406Sopenharmony_ci _lto3b(rwd_size, cmd.len); 263141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), rwd, &rwd_size); 264141cc406Sopenharmony_ci 265141cc406Sopenharmony_ci DBG (11, "<< get_window, datalen = %lu\n", (unsigned long) rwd_size); 266141cc406Sopenharmony_ci return (status); 267141cc406Sopenharmony_ci} 268141cc406Sopenharmony_ci 269141cc406Sopenharmony_cistatic SANE_Status 270141cc406Sopenharmony_ciread_data (int fd, void *buf, size_t * buf_size) 271141cc406Sopenharmony_ci{ 272141cc406Sopenharmony_ci static struct scsi_read_scanner_cmd cmd; 273141cc406Sopenharmony_ci SANE_Status status; 274141cc406Sopenharmony_ci DBG (11, ">> read_data %lu\n", (unsigned long) *buf_size); 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ci memset (&cmd, 0, sizeof (cmd)); 277141cc406Sopenharmony_ci cmd.opcode = RICOH_SCSI_READ_SCANNED_DATA; 278141cc406Sopenharmony_ci _lto3b(*buf_size, cmd.len); 279141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), buf, buf_size); 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_ci DBG (11, "<< read_data %lu\n", (unsigned long) *buf_size); 282141cc406Sopenharmony_ci return (status); 283141cc406Sopenharmony_ci} 284141cc406Sopenharmony_ci 285141cc406Sopenharmony_cistatic SANE_Status 286141cc406Sopenharmony_ciobject_position (int fd) 287141cc406Sopenharmony_ci{ 288141cc406Sopenharmony_ci static SANE_Byte cmd[10]; 289141cc406Sopenharmony_ci SANE_Status status; 290141cc406Sopenharmony_ci DBG (11, ">> object_position\n"); 291141cc406Sopenharmony_ci 292141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 293141cc406Sopenharmony_ci cmd[0] = RICOH_SCSI_OBJECT_POSITION; 294141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 295141cc406Sopenharmony_ci 296141cc406Sopenharmony_ci DBG (11, "<< object_position\n"); 297141cc406Sopenharmony_ci return (status); 298141cc406Sopenharmony_ci} 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_cistatic SANE_Status 301141cc406Sopenharmony_ciget_data_status (int fd, struct scsi_status_desc *dbs) 302141cc406Sopenharmony_ci{ 303141cc406Sopenharmony_ci static struct scsi_get_buffer_status_cmd cmd; 304141cc406Sopenharmony_ci static struct scsi_status_data ssd; 305141cc406Sopenharmony_ci size_t ssd_size = sizeof(ssd); 306141cc406Sopenharmony_ci SANE_Status status; 307141cc406Sopenharmony_ci DBG (11, ">> get_data_status %lu\n", (unsigned long) ssd_size); 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci memset (&cmd, 0, sizeof (cmd)); 310141cc406Sopenharmony_ci cmd.opcode = RICOH_SCSI_GET_BUFFER_STATUS; 311141cc406Sopenharmony_ci _lto2b(ssd_size, cmd.len); 312141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd), &ssd, &ssd_size); 313141cc406Sopenharmony_ci 314141cc406Sopenharmony_ci memcpy (dbs, &ssd.desc, sizeof(*dbs)); 315141cc406Sopenharmony_ci if (status == SANE_STATUS_GOOD && 316141cc406Sopenharmony_ci (((unsigned int) _3btol(ssd.len)) <= sizeof(*dbs) || _3btol(ssd.desc.filled) == 0)) { 317141cc406Sopenharmony_ci DBG (11, "get_data_status: busy\n"); 318141cc406Sopenharmony_ci status = SANE_STATUS_DEVICE_BUSY; 319141cc406Sopenharmony_ci } 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_ci DBG (11, "<< get_data_status %lu\n", (unsigned long) ssd_size); 322141cc406Sopenharmony_ci return (status); 323141cc406Sopenharmony_ci} 324141cc406Sopenharmony_ci 325141cc406Sopenharmony_ci#if 0 326141cc406Sopenharmony_cistatic SANE_Status 327141cc406Sopenharmony_ciricoh_wait_ready_tur (int fd) 328141cc406Sopenharmony_ci{ 329141cc406Sopenharmony_ci struct timeval now, start; 330141cc406Sopenharmony_ci SANE_Status status; 331141cc406Sopenharmony_ci 332141cc406Sopenharmony_ci gettimeofday (&start, 0); 333141cc406Sopenharmony_ci 334141cc406Sopenharmony_ci while (1) 335141cc406Sopenharmony_ci { 336141cc406Sopenharmony_ci DBG(3, "scsi_wait_ready: sending TEST_UNIT_READY\n"); 337141cc406Sopenharmony_ci 338141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, test_unit_ready, sizeof (test_unit_ready), 339141cc406Sopenharmony_ci 0, 0); 340141cc406Sopenharmony_ci switch (status) 341141cc406Sopenharmony_ci { 342141cc406Sopenharmony_ci default: 343141cc406Sopenharmony_ci /* Ignore errors while waiting for scanner to become ready. 344141cc406Sopenharmony_ci Some SCSI drivers return EIO while the scanner is 345141cc406Sopenharmony_ci returning to the home position. */ 346141cc406Sopenharmony_ci DBG(1, "scsi_wait_ready: test unit ready failed (%s)\n", 347141cc406Sopenharmony_ci sane_strstatus (status)); 348141cc406Sopenharmony_ci /* fall through */ 349141cc406Sopenharmony_ci case SANE_STATUS_DEVICE_BUSY: 350141cc406Sopenharmony_ci gettimeofday (&now, 0); 351141cc406Sopenharmony_ci if (now.tv_sec - start.tv_sec >= MAX_WAITING_TIME) 352141cc406Sopenharmony_ci { 353141cc406Sopenharmony_ci DBG(1, "ricoh_wait_ready: timed out after %lu seconds\n", 354141cc406Sopenharmony_ci (u_long) (now.tv_sec - start.tv_sec)); 355141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 356141cc406Sopenharmony_ci } 357141cc406Sopenharmony_ci usleep (100000); /* retry after 100ms */ 358141cc406Sopenharmony_ci break; 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci case SANE_STATUS_GOOD: 361141cc406Sopenharmony_ci return status; 362141cc406Sopenharmony_ci } 363141cc406Sopenharmony_ci } 364141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 365141cc406Sopenharmony_ci} 366141cc406Sopenharmony_ci#endif 367141cc406Sopenharmony_ci 368141cc406Sopenharmony_cistatic SANE_Status 369141cc406Sopenharmony_ciricoh_wait_ready (Ricoh_Scanner * s) 370141cc406Sopenharmony_ci{ 371141cc406Sopenharmony_ci struct scsi_status_desc dbs; 372141cc406Sopenharmony_ci time_t now, start; 373141cc406Sopenharmony_ci SANE_Status status; 374141cc406Sopenharmony_ci 375141cc406Sopenharmony_ci start = time(NULL); 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci while (1) 378141cc406Sopenharmony_ci { 379141cc406Sopenharmony_ci status = get_data_status (s->fd, &dbs); 380141cc406Sopenharmony_ci 381141cc406Sopenharmony_ci switch (status) 382141cc406Sopenharmony_ci { 383141cc406Sopenharmony_ci default: 384141cc406Sopenharmony_ci /* Ignore errors while waiting for scanner to become ready. 385141cc406Sopenharmony_ci Some SCSI drivers return EIO while the scanner is 386141cc406Sopenharmony_ci returning to the home position. */ 387141cc406Sopenharmony_ci DBG(1, "scsi_wait_ready: get datat status failed (%s)\n", 388141cc406Sopenharmony_ci sane_strstatus (status)); 389141cc406Sopenharmony_ci /* fall through */ 390141cc406Sopenharmony_ci case SANE_STATUS_DEVICE_BUSY: 391141cc406Sopenharmony_ci now = time(NULL); 392141cc406Sopenharmony_ci if (now - start >= MAX_WAITING_TIME) 393141cc406Sopenharmony_ci { 394141cc406Sopenharmony_ci DBG(1, "ricoh_wait_ready: timed out after %lu seconds\n", 395141cc406Sopenharmony_ci (u_long) (now - start)); 396141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 397141cc406Sopenharmony_ci } 398141cc406Sopenharmony_ci break; 399141cc406Sopenharmony_ci 400141cc406Sopenharmony_ci case SANE_STATUS_GOOD: 401141cc406Sopenharmony_ci DBG(11, "ricoh_wait_ready: %d bytes ready\n", _3btol(dbs.filled)); 402141cc406Sopenharmony_ci return status; 403141cc406Sopenharmony_ci break; 404141cc406Sopenharmony_ci } 405141cc406Sopenharmony_ci usleep (1000000); /* retry after 100ms */ 406141cc406Sopenharmony_ci } 407141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 408141cc406Sopenharmony_ci} 409