1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) Marian Eichholz 2001 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 40141cc406Sopenharmony_ci/* ====================================================================== 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ciUserspace scan tool for the Microtek 3600 scanner 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci(C) Marian Eichholz 2001 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci26.4.2001: Added an abstraction layer for TransferControlMsg. 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci====================================================================== */ 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#include "sm3600-scantool.h" 51141cc406Sopenharmony_ci 52141cc406Sopenharmony_ci/* ********************************************************************** 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ciTransferControlMsg() 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci********************************************************************** */ 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_cistatic int TransferControlMsg(TInstance *this, 59141cc406Sopenharmony_ci int nReqType, 60141cc406Sopenharmony_ci int nRequest, 61141cc406Sopenharmony_ci int nValue, 62141cc406Sopenharmony_ci int nIndex, 63141cc406Sopenharmony_ci void *pBuffer, 64141cc406Sopenharmony_ci int cchBuffer, 65141cc406Sopenharmony_ci int cJiffiesTimeout) 66141cc406Sopenharmony_ci{ 67141cc406Sopenharmony_ci SANE_Status err; 68141cc406Sopenharmony_ci 69141cc406Sopenharmony_ci (void) cJiffiesTimeout; 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_ci err = sanei_usb_control_msg (this->hScanner, 72141cc406Sopenharmony_ci nReqType, 73141cc406Sopenharmony_ci nRequest, 74141cc406Sopenharmony_ci nValue, 75141cc406Sopenharmony_ci nIndex, 76141cc406Sopenharmony_ci cchBuffer, 77141cc406Sopenharmony_ci pBuffer); 78141cc406Sopenharmony_ci if (err) 79141cc406Sopenharmony_ci return err; 80141cc406Sopenharmony_ci return cchBuffer; 81141cc406Sopenharmony_ci} 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ci/* ********************************************************************** 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_cicch=BulkRead() 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_ci********************************************************************** */ 88141cc406Sopenharmony_ci 89141cc406Sopenharmony_cistatic int TransferBulkRead(TInstance *this, 90141cc406Sopenharmony_ci int nEndPoint, 91141cc406Sopenharmony_ci void *pBuffer, 92141cc406Sopenharmony_ci int cchMax, 93141cc406Sopenharmony_ci int cJiffiesTimeout) 94141cc406Sopenharmony_ci{ 95141cc406Sopenharmony_ci int err; 96141cc406Sopenharmony_ci size_t sz = cchMax; 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci (void) nEndPoint; 99141cc406Sopenharmony_ci (void) cJiffiesTimeout; 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_ci err = sanei_usb_read_bulk(this->hScanner, 102141cc406Sopenharmony_ci pBuffer, 103141cc406Sopenharmony_ci &sz); 104141cc406Sopenharmony_ci if (err) 105141cc406Sopenharmony_ci return err; 106141cc406Sopenharmony_ci return sz; 107141cc406Sopenharmony_ci} 108141cc406Sopenharmony_ci 109141cc406Sopenharmony_ci/* ********************************************************************** 110141cc406Sopenharmony_ci 111141cc406Sopenharmony_ciRegWrite(iRegister, cb, ulValue) 112141cc406Sopenharmony_ciRegWriteArray(iRegister, cb, unsigned char uchValues) 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci********************************************************************** */ 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_ci__SM3600EXPORT__ 117141cc406Sopenharmony_ciTState RegWrite(TInstance *this, int iRegister, int cb, unsigned long ulValue) 118141cc406Sopenharmony_ci{ 119141cc406Sopenharmony_ci char *pchBuffer; 120141cc406Sopenharmony_ci int i; 121141cc406Sopenharmony_ci TBool bOk=true; 122141cc406Sopenharmony_ci INST_ASSERT(); 123141cc406Sopenharmony_ci /* some rough assertions */ 124141cc406Sopenharmony_ci if (cb<1 || cb>4) 125141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_INVAL,"unsupported control transfer size %d",cb); 126141cc406Sopenharmony_ci pchBuffer=malloc(cb); 127141cc406Sopenharmony_ci CHECK_POINTER(pchBuffer); 128141cc406Sopenharmony_ci for (i=0; i<cb; i++) 129141cc406Sopenharmony_ci { 130141cc406Sopenharmony_ci pchBuffer[i]=(char)(ulValue&0xFF); 131141cc406Sopenharmony_ci ulValue=ulValue>>8; 132141cc406Sopenharmony_ci } 133141cc406Sopenharmony_ci if (!bOk) 134141cc406Sopenharmony_ci { 135141cc406Sopenharmony_ci free(pchBuffer); 136141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_IO_ERROR, 137141cc406Sopenharmony_ci "error in reg out: %d,%d,%08X",iRegister,cb,ulValue); 138141cc406Sopenharmony_ci } 139141cc406Sopenharmony_ci i=TransferControlMsg(this, /* handle */ 140141cc406Sopenharmony_ci 0x40, /* request type */ 141141cc406Sopenharmony_ci 0x08, /* request */ 142141cc406Sopenharmony_ci iRegister, /* value */ 143141cc406Sopenharmony_ci 0, /* index */ 144141cc406Sopenharmony_ci pchBuffer, cb, /* bytes, size */ 145141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); /* TO, jiffies... */ 146141cc406Sopenharmony_ci free(pchBuffer); 147141cc406Sopenharmony_ci if (i<0) 148141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_IO_ERROR,"error during register write"); 149141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 150141cc406Sopenharmony_ci} 151141cc406Sopenharmony_ci 152141cc406Sopenharmony_ci__SM3600EXPORT__ 153141cc406Sopenharmony_ciTState RegWriteArray(TInstance *this, int iRegister, int cb, unsigned char *pchBuffer) 154141cc406Sopenharmony_ci{ 155141cc406Sopenharmony_ci int i; 156141cc406Sopenharmony_ci INST_ASSERT(); 157141cc406Sopenharmony_ci /* some rough assertions */ 158141cc406Sopenharmony_ci i=TransferControlMsg(this, /* handle */ 159141cc406Sopenharmony_ci 0x40, /* request type */ 160141cc406Sopenharmony_ci 0x08, /* request */ 161141cc406Sopenharmony_ci iRegister, /* value */ 162141cc406Sopenharmony_ci 0, /* index */ 163141cc406Sopenharmony_ci pchBuffer, cb, /* bytes, size */ 164141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); /* TO, jiffies... */ 165141cc406Sopenharmony_ci if (i<0) 166141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_IO_ERROR,"error during register write"); 167141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 168141cc406Sopenharmony_ci} 169141cc406Sopenharmony_ci 170141cc406Sopenharmony_ci/* ********************************************************************** 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ciMemWriteArray(iAddress, cb, ulValue) 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_ci********************************************************************** */ 175141cc406Sopenharmony_ci 176141cc406Sopenharmony_ci__SM3600EXPORT__ 177141cc406Sopenharmony_ciTState MemWriteArray(TInstance *this, int iAddress, 178141cc406Sopenharmony_ci int cb, unsigned char *pchBuffer) 179141cc406Sopenharmony_ci{ 180141cc406Sopenharmony_ci int i; 181141cc406Sopenharmony_ci INST_ASSERT(); 182141cc406Sopenharmony_ci /* some rough assertions */ 183141cc406Sopenharmony_ci i=TransferControlMsg(this, 184141cc406Sopenharmony_ci 0x40, /* request type */ 185141cc406Sopenharmony_ci 0x09, /* request */ 186141cc406Sopenharmony_ci iAddress, /* value */ 187141cc406Sopenharmony_ci 0, /* index */ 188141cc406Sopenharmony_ci pchBuffer, cb, /* bytes, size */ 189141cc406Sopenharmony_ci 10000); /* TO, jiffies... */ 190141cc406Sopenharmony_ci if (i<0) 191141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_IO_ERROR,"error during memory write"); 192141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 193141cc406Sopenharmony_ci} 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci/* ********************************************************************** 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ciMemReadArray(iRegister, cb, ulValue) 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci********************************************************************** */ 200141cc406Sopenharmony_ci 201141cc406Sopenharmony_ci#ifdef INSANE_VERSION 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci__SM3600EXPORT__ 204141cc406Sopenharmony_ciTState MemReadArray(TInstance *this, int iAddress, int cb, unsigned char *pchBuffer) 205141cc406Sopenharmony_ci{ 206141cc406Sopenharmony_ci int i; 207141cc406Sopenharmony_ci INST_ASSERT(); 208141cc406Sopenharmony_ci /* some rough assertions */ 209141cc406Sopenharmony_ci i=TransferControlMsg(this, 210141cc406Sopenharmony_ci 0xC0, /* request type */ 211141cc406Sopenharmony_ci 0x01, /* request */ 212141cc406Sopenharmony_ci iAddress, /* value */ 213141cc406Sopenharmony_ci 0, /* index */ 214141cc406Sopenharmony_ci pchBuffer, cb, /* bytes, size */ 215141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); /* TO, jiffies... */ 216141cc406Sopenharmony_ci if (i<0) 217141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_IO_ERROR,"error during memory read"); 218141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 219141cc406Sopenharmony_ci} 220141cc406Sopenharmony_ci 221141cc406Sopenharmony_ci/* ********************************************************************** 222141cc406Sopenharmony_ci 223141cc406Sopenharmony_ciRegCheck(iRegister, cb, ulValue) 224141cc406Sopenharmony_ci 225141cc406Sopenharmony_ci********************************************************************** */ 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci__SM3600EXPORT__ 228141cc406Sopenharmony_ciTState RegCheck(TInstance *this, int iRegister, int cch, unsigned long ulValue) 229141cc406Sopenharmony_ci{ 230141cc406Sopenharmony_ci char *pchBuffer,*pchTransfer; 231141cc406Sopenharmony_ci int i,rcCode; 232141cc406Sopenharmony_ci TBool bOk; 233141cc406Sopenharmony_ci INST_ASSERT(); 234141cc406Sopenharmony_ci if (cch<1 || cch>3) 235141cc406Sopenharmony_ci return SetError(this,SANE_STATUS_INVAL,"unsupported control transfer size %d",cch); 236141cc406Sopenharmony_ci pchBuffer=malloc(cch); 237141cc406Sopenharmony_ci pchTransfer=calloc(1,cch); 238141cc406Sopenharmony_ci rcCode=SANE_STATUS_GOOD; 239141cc406Sopenharmony_ci if (!pchBuffer || !pchTransfer) 240141cc406Sopenharmony_ci { 241141cc406Sopenharmony_ci if (pchBuffer) free(pchBuffer); 242141cc406Sopenharmony_ci if (pchTransfer) free(pchTransfer); 243141cc406Sopenharmony_ci rcCode=SetError(this, SANE_STATUS_NO_MEM, "no memory in RegCheck()"); 244141cc406Sopenharmony_ci } 245141cc406Sopenharmony_ci bOk=true; 246141cc406Sopenharmony_ci for (i=0; !rcCode && i<cch; i++) 247141cc406Sopenharmony_ci { 248141cc406Sopenharmony_ci pchBuffer[i]=(char)(ulValue&0x00FF); 249141cc406Sopenharmony_ci ulValue=(ulValue>>8); 250141cc406Sopenharmony_ci } 251141cc406Sopenharmony_ci if (!rcCode) 252141cc406Sopenharmony_ci { 253141cc406Sopenharmony_ci if (!bOk) 254141cc406Sopenharmony_ci rcCode=SetError(this,SANE_STATUS_IO_ERROR, 255141cc406Sopenharmony_ci "error in reg out: %d,%d,%08X",iRegister,cch,ulValue); 256141cc406Sopenharmony_ci else 257141cc406Sopenharmony_ci { 258141cc406Sopenharmony_ci i=TransferControlMsg(this, /* handle */ 259141cc406Sopenharmony_ci 0xC0, /* request type */ 260141cc406Sopenharmony_ci 0x00, /* request */ 261141cc406Sopenharmony_ci iRegister, /* value */ 262141cc406Sopenharmony_ci 0, /* index */ 263141cc406Sopenharmony_ci pchTransfer, cch, /* bytes, size */ 264141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); /* TO, jiffies... */ 265141cc406Sopenharmony_ci if (i<0) 266141cc406Sopenharmony_ci rcCode=SetError(this,SANE_STATUS_IO_ERROR, 267141cc406Sopenharmony_ci "error during register check"); 268141cc406Sopenharmony_ci } 269141cc406Sopenharmony_ci } 270141cc406Sopenharmony_ci if (!rcCode && memcmp(pchTransfer,pchBuffer,cch)) 271141cc406Sopenharmony_ci { 272141cc406Sopenharmony_ci DumpBuffer(stdout,pchTransfer,cch); 273141cc406Sopenharmony_ci rcCode=SetError(this,SANE_STATUS_IO_ERROR, 274141cc406Sopenharmony_ci "check register failed for %d,%d,%08X", 275141cc406Sopenharmony_ci iRegister,cch,ulValue); 276141cc406Sopenharmony_ci } 277141cc406Sopenharmony_ci free(pchTransfer); free(pchBuffer); 278141cc406Sopenharmony_ci return rcCode; 279141cc406Sopenharmony_ci} 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_ci/* ********************************************************************** 282141cc406Sopenharmony_ci 283141cc406Sopenharmony_cicchRead=BulkRead(fh,cchBulk) 284141cc406Sopenharmony_ci 285141cc406Sopenharmony_ci********************************************************************** */ 286141cc406Sopenharmony_ci 287141cc406Sopenharmony_ci__SM3600EXPORT__ 288141cc406Sopenharmony_ciint BulkRead(TInstance *this, FILE *fhOut, unsigned int cchBulk) 289141cc406Sopenharmony_ci{ 290141cc406Sopenharmony_ci int cchRead,rc; 291141cc406Sopenharmony_ci char *pchBuffer; 292141cc406Sopenharmony_ci INST_ASSERT(); 293141cc406Sopenharmony_ci pchBuffer=(char*)malloc(cchBulk); 294141cc406Sopenharmony_ci CHECK_POINTER(pchBuffer); 295141cc406Sopenharmony_ci cchRead=0; 296141cc406Sopenharmony_ci rc=0; 297141cc406Sopenharmony_ci while (!rc && cchBulk) 298141cc406Sopenharmony_ci { 299141cc406Sopenharmony_ci int cchChunk; 300141cc406Sopenharmony_ci int cchReal; 301141cc406Sopenharmony_ci 302141cc406Sopenharmony_ci cchChunk=cchBulk; 303141cc406Sopenharmony_ci if (cchChunk>0x1000) 304141cc406Sopenharmony_ci cchChunk=0x1000; 305141cc406Sopenharmony_ci cchReal=TransferBulkRead(this, 306141cc406Sopenharmony_ci 0x82, 307141cc406Sopenharmony_ci pchBuffer+cchRead, 308141cc406Sopenharmony_ci cchChunk, 309141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); 310141cc406Sopenharmony_ci dprintf(DEBUG_COMM,"bulk read: %d -> %d\n",cchChunk,cchReal); 311141cc406Sopenharmony_ci if (cchReal>=0) 312141cc406Sopenharmony_ci { 313141cc406Sopenharmony_ci cchBulk-=cchReal; 314141cc406Sopenharmony_ci cchRead+=cchReal; 315141cc406Sopenharmony_ci if (cchReal<cchChunk) /* last Chunk of a series */ 316141cc406Sopenharmony_ci break; 317141cc406Sopenharmony_ci } 318141cc406Sopenharmony_ci else 319141cc406Sopenharmony_ci { 320141cc406Sopenharmony_ci rc=SetError(this,SANE_STATUS_IO_ERROR, 321141cc406Sopenharmony_ci "bulk read of %d bytes failed: %s", 322141cc406Sopenharmony_ci cchChunk, 323141cc406Sopenharmony_ci "I/O error" 324141cc406Sopenharmony_ci ); 325141cc406Sopenharmony_ci continue; 326141cc406Sopenharmony_ci } 327141cc406Sopenharmony_ci } 328141cc406Sopenharmony_ci dprintf(DEBUG_COMM,"writing %d bytes\n",cchRead); 329141cc406Sopenharmony_ci if (fhOut && !rc) 330141cc406Sopenharmony_ci { 331141cc406Sopenharmony_ci fwrite(pchBuffer,1,cchRead,fhOut); 332141cc406Sopenharmony_ci if (ferror(fhOut)) 333141cc406Sopenharmony_ci rc=SetError(this,SANE_STATUS_IO_ERROR, 334141cc406Sopenharmony_ci "scan file write failed: %s", 335141cc406Sopenharmony_ci strerror(errno)); 336141cc406Sopenharmony_ci } 337141cc406Sopenharmony_ci free(pchBuffer); 338141cc406Sopenharmony_ci return rc ? -1 : cchRead; 339141cc406Sopenharmony_ci} 340141cc406Sopenharmony_ci 341141cc406Sopenharmony_ci#endif 342141cc406Sopenharmony_ci 343141cc406Sopenharmony_ci/* ********************************************************************** 344141cc406Sopenharmony_ci 345141cc406Sopenharmony_cicchRead=BulkReadBuffer(puchBuffer, cchBulk) 346141cc406Sopenharmony_ci 347141cc406Sopenharmony_ci********************************************************************** */ 348141cc406Sopenharmony_ci 349141cc406Sopenharmony_ci__SM3600EXPORT__ 350141cc406Sopenharmony_ciint BulkReadBuffer(TInstance *this, 351141cc406Sopenharmony_ci unsigned char *puchBufferOut, 352141cc406Sopenharmony_ci unsigned int cchBulk) 353141cc406Sopenharmony_ci{ 354141cc406Sopenharmony_ci int cchRead,rc; 355141cc406Sopenharmony_ci char *pchBuffer; 356141cc406Sopenharmony_ci INST_ASSERT(); 357141cc406Sopenharmony_ci pchBuffer=(char*)malloc(cchBulk); 358141cc406Sopenharmony_ci CHECK_POINTER(pchBuffer); 359141cc406Sopenharmony_ci cchRead=0; 360141cc406Sopenharmony_ci rc=0; 361141cc406Sopenharmony_ci while (!rc && cchBulk) 362141cc406Sopenharmony_ci { 363141cc406Sopenharmony_ci int cchChunk; 364141cc406Sopenharmony_ci int cchReal; 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci cchChunk=cchBulk; 367141cc406Sopenharmony_ci if (cchChunk>0x1000) 368141cc406Sopenharmony_ci cchChunk=0x1000; 369141cc406Sopenharmony_ci cchReal=TransferBulkRead(this, 370141cc406Sopenharmony_ci 0x82, 371141cc406Sopenharmony_ci pchBuffer+cchRead, 372141cc406Sopenharmony_ci cchChunk, 373141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); 374141cc406Sopenharmony_ci dprintf(DEBUG_COMM,"bulk read: %d -> %d\n",cchChunk,cchReal); 375141cc406Sopenharmony_ci if (cchReal>=0) 376141cc406Sopenharmony_ci { 377141cc406Sopenharmony_ci cchBulk-=cchReal; 378141cc406Sopenharmony_ci cchRead+=cchReal; 379141cc406Sopenharmony_ci if (cchReal<cchChunk) /* last Chunk of a series */ 380141cc406Sopenharmony_ci break; 381141cc406Sopenharmony_ci } 382141cc406Sopenharmony_ci else 383141cc406Sopenharmony_ci rc=SetError(this,SANE_STATUS_IO_ERROR, 384141cc406Sopenharmony_ci "bulk read of %d bytes failed: %s", 385141cc406Sopenharmony_ci cchChunk, 386141cc406Sopenharmony_ci "I/O error" 387141cc406Sopenharmony_ci ); 388141cc406Sopenharmony_ci } 389141cc406Sopenharmony_ci dprintf(DEBUG_COMM,"writing %d bytes\n",cchRead); 390141cc406Sopenharmony_ci 391141cc406Sopenharmony_ci if (!rc && puchBufferOut) 392141cc406Sopenharmony_ci memcpy(puchBufferOut,pchBuffer,cchRead); 393141cc406Sopenharmony_ci free(pchBuffer); 394141cc406Sopenharmony_ci return rc ? -1 : cchRead; 395141cc406Sopenharmony_ci} 396141cc406Sopenharmony_ci 397141cc406Sopenharmony_ci/* ********************************************************************** 398141cc406Sopenharmony_ci 399141cc406Sopenharmony_ciRegRead(iRegister, int cch) 400141cc406Sopenharmony_ci 401141cc406Sopenharmony_ciRead register in big endian (INTEL-) format. 402141cc406Sopenharmony_ci 403141cc406Sopenharmony_ci********************************************************************** */ 404141cc406Sopenharmony_ci 405141cc406Sopenharmony_ci__SM3600EXPORT__ 406141cc406Sopenharmony_ciunsigned int RegRead(TInstance *this, int iRegister, int cch) 407141cc406Sopenharmony_ci{ 408141cc406Sopenharmony_ci char *pchTransfer; 409141cc406Sopenharmony_ci int i; 410141cc406Sopenharmony_ci unsigned int n; 411141cc406Sopenharmony_ci INST_ASSERT(); 412141cc406Sopenharmony_ci if (cch<1 || cch>4) 413141cc406Sopenharmony_ci { 414141cc406Sopenharmony_ci SetError(this,SANE_STATUS_INVAL, 415141cc406Sopenharmony_ci "unsupported control read size %d",cch); 416141cc406Sopenharmony_ci return 0; 417141cc406Sopenharmony_ci } 418141cc406Sopenharmony_ci pchTransfer=calloc(1,cch); 419141cc406Sopenharmony_ci CHECK_POINTER(pchTransfer); 420141cc406Sopenharmony_ci i=TransferControlMsg(this, /* handle */ 421141cc406Sopenharmony_ci 0xC0, /* request type */ 422141cc406Sopenharmony_ci 0x00, /* request */ 423141cc406Sopenharmony_ci iRegister, /* value */ 424141cc406Sopenharmony_ci 0, /* index */ 425141cc406Sopenharmony_ci pchTransfer, cch, /* bytes, size */ 426141cc406Sopenharmony_ci USB_TIMEOUT_JIFFIES); /* TO, jiffies... */ 427141cc406Sopenharmony_ci if (i>=0) 428141cc406Sopenharmony_ci { 429141cc406Sopenharmony_ci n=0; 430141cc406Sopenharmony_ci for (i=cch-1; i>=0; i--) 431141cc406Sopenharmony_ci n=(n<<8)|(unsigned char)pchTransfer[i]; 432141cc406Sopenharmony_ci free(pchTransfer); 433141cc406Sopenharmony_ci return n; 434141cc406Sopenharmony_ci } 435141cc406Sopenharmony_ci free(pchTransfer); 436141cc406Sopenharmony_ci SetError(this,SANE_STATUS_IO_ERROR,"error during register read"); 437141cc406Sopenharmony_ci return 0; 438141cc406Sopenharmony_ci} 439