[sane-devel] RFC: proposal for an improved sanei_scsi library
abel deuring
adeuring at gmx.net
Sun Dec 8 16:51:17 GMT 2002
Henning Meier-Geinitz wrote:
>>Well, there is indeed not urgent need to change the interface for Sane1.
>>But there were a few situations where I wished I had a somewhat cleaner
>>interface at hand for Sane 1 ;) And it would not be difficult to write a
>>compatibility layer for the current interface. But if Sane2 development
>>is taking off soon, work on Sane1 would of course be useless.
>
>
> I hope It won't take too long to finish the core points of SANE2.
Sounds promising.
>
>
>>A SCSI device returns a status byte for every command, giving coarse
>>information about the result of the command (GOOD/CHECK
>>CONDITION/CONDITION MET/BUSY etc). A detailed description can be found
>>in the SCSI2 draft, ftp://ftp.t10.org/t10/drafts/s2/s2-r10l.pdf ,
>>section 7.3. The SCSI reference manuals for the scanners should describe
>>it too.
>
>
> SCSI reference manual for a scanner? Haha. Never seen such a beast.
> Either it's labeled "top secret" or it's written in Chinese. At least
> for "my" backends. :-)
Well, to be fair, some vendors are more helpful. I needed just one phone
call to get the docs from Sharp; Fujitsu has many docs available at
least on their European website; Epson publishes even some of their
source code.
> For the status value, yes, but not for sb, as this is a buffer. All
> the other buffer pointers use void*.
changed. See attachment.
>>>>* @param scsi_status the status returned by the device.
>>>>* xxx what about the situation, that the command has not been
>>>>* issued, or other situations, where no status information
>>>>* is available? Can this situation be detected for all supported
>>>>* OSes? If that is possible, we should add another parameter
>>>>which
>>>>* signals "SCSI status available"
>>>
>>>
>>>Maybe use the return value to flag this. I.e. i/o error: scsi_status
>>>has some meaning, invalid arg: something different went wrong.
>>
>>I don't like to put more semantics into the return status, But we could
>>add another int* parameter which signals, if *scsi_status contains a
>>valid value.
>
>
> Or use an int instead of a byte. -1 is "not applicable".
Sounds reasonable.
Abel
-------------- next part --------------
/** Find SCSI devices.
*
* Find each SCSI device that matches the pattern specified by the
* arguments. String arguments can be "omitted" by passing NULL,
* integer arguments can be "omitted" by passing -1.
*
* Example: vendor="HP" model=NULL, type=NULL, bus=3, id=-1, lun=-1 would
* attach all HP devices on SCSI bus 3.
*
* @param vendor vendor field of the SCSI INQUIRY data
* @param model model field of the SCSI INQUIRY data
* @param type type of the device. Should be "scanner" or "processor"
* @param bus number of the SCSI bus (for certain OSes, this field
* corresponds to the host adapter number)
* @param channel channel of a bus/host adapter
* @param id SCSI ID
* @param lun SCSI LUN
* @param attach callback invoked once for each device
* @param dev real devicename (passed to attach callback)
*
*/
extern void sanei2_scsi_find_devices (const char *vendor, const char *model,
const char *type,
int bus, int channel, int id, int lun,
SANE_Status (*attach) (const char *dev));
/** Open a SCSI device
*
* Opens a SCSI device by its device filename and returns a file descriptor.
* The function tries to allocate a buffer of the size given by *buffersize.
* If sanei2_scsi_open returns successfully, *buffersize contains the
* available buffer size. This value may be both smaller or larger than the
* value requested by the backend; it can even be zero. The backend must not
* try to issue SCSI command with data blocks larger than given by the
* value of *buffersize. The backend must decide, if it got enough buffer
* memory to work.
*
* Note that the value of *buffersize may differ for different files and
* even for consecutive calls for the same file.
*
* @param devicename name of the devicefile, e.g. "/dev/sg0"
* @param fd file descriptor
* @param timeout is the timeout in seconds for SCSI commands. The function
* may set *timeout to another value, if the requested timeout
* could not be set.
* @param buffersize size of the SCSI request buffer (in bytes)
*
* @return
* - SANE_STATUS_GOOD - on success
* - SANE_STATUS_ACCESS_DENIED - if the file couldn't be accessed due to
* permissions
* - SANE_STATUS_NO_MEM - if malloc failed (not enough memory)
* - SANE_STATUS_INVAL - if the filename was invalid or an unknown error occured
*
*/
extern SANE_Status sanei2_scsi_open (
const char * device_name, int * fd,
int *timeout, int *buffersize);
/** Macros for the parameter direction of sanei2_scsi_req_enter and sanei2_scsi_cmd
*
* @param SANEI_SCSI_DXFER_NONE no data transfer
* @param SANEI_SCSI_DXFER_TO_DEVICE data is sent to the device
* @param SANEI_SCSI__DXFER_FROM_DEVICE data is received from the device
*/
#define SANEI_SCSI_DXFER_NONE 0
#define SANEI_SCSI_DXFER_TO_DEVICE 1
#define SANEI_SCSI__DXFER_FROM_DEVICE 2
/** Enqueue SCSI command
*
* One or more scsi commands can be enqueued by calling sanei2_scsi_req_enter().
*
* NOTE: Some systems may not support multiple outstanding commands. On such
* systems, sanei2_scsi_req_enter() may block. In other words, it is not proper
* to assume that enter() is a non-blocking routine.
*
* @param fd file descriptor
* @param cmd pointer to SCSI command
* @param cmd_size size of the command
* @param buffer pointer to the buffer with data to be sent to / received from
* the scanner
* @param buffer_size size of the data buffer
* @param direction direction of the data transfer.
* @param idp pointer to a void* that uniquely identifies the entered request
* @return
* - SANE_STATUS_GOOD - on success
* - SANE_STATUS_IO_ERROR - if an error was received from the SCSI driver
* - SANE_STATUS_NO_MEM - if malloc failed (not enough memory)
* - SANE_STATUS_INVAL - if a locking or an unknown error occured
* - SANE_STATUS_DEVICE_BUSY - the SCSI command could not be issued; try
* again later
*/
extern SANE_Status sanei2_scsi_req_enter (int fd,
const void * cmd, size_t cmd_size,
const void * buffer, size_t buffer_size,
int direction, void **idp);
/** Wait for SCSI command
*
* Wait for the completion of the SCSI command with id ID.
*
* @param id id used in sanei2_scsi_req_enter()
* @param sb pointer to a SANE_Byte array, where the SCSI sense data may be
* stored. The caller must allocate the necessary memory.
* The parameter may be NULL.
* @param sblen the length of the sense buffer allocated by the caller.
* On return, *sblen contains the number of bytes copied to the
* sense buffer
* @param scsi_status the status returned by the device.
* A value of -1 means that no status data from the device is
* available, e.g., because the command could not be sent
* to the device.
*
* @return
* - SANE_STATUS_GOOD - on success
* - SANE_STATUS_DEVICE_BUSY - if the device is busy (try again later)
* - SANE_STATUS_IO_ERROR - if an error was received from the SCSI driver
*/
extern SANE_Status sanei2_scsi_req_wait (void *id, u_int_8 *sb, size_t *sblen,
int *scsi_status);
/** Send SCSI command
*
* This is a convenience function that is equivalent to a pair of
* sanei2_scsi_req_enter()/sanei2_scsi_req_wait() calls.
*
* @param fd file descriptor
* @param cmd pointer to SCSI command
* @param cmd_size size of the command
* @param buffer pointer to the buffer with data to be sent to / received from
the scanner
* @param buffer_size size of the data buffer
* @param direction direction of the data transfer. Allowed value:
* - SANE_SCSI_DXFER_NONE no data transfer
* - SANE_SCSI_DXFER_TO_DEVICE data is sent to the device
* - SANE_SCSI_DXFER_FROM_DEVICE data is received from the device
* @param sb pointer to a SANE_Byte array, where the SCSI sense data may be
* stored. The caller must allocate the necessary memory.
* The parameter may be NULL.
* @param sblen the length of the sense buffer allocated by the caller.
* On return, *sblen contains the number of bytes copied to the
* sense buffer
* @param scsi_status the status returned by the device.
* @param scsi_status_valid If *scsi_status_valid is non-zero, *scsi_status
* contains valid information; if it is zero, *scsi_status is
* invalid.
*
* @return
* - SANE_STATUS_GOOD - on success
* - SANE_STATUS_IO_ERROR - if an error was received from the SCSI driver
* - SANE_STATUS_NO_MEM - if malloc failed (not enough memory)
* - SANE_STATUS_INVAL - if a locking or an unknown error occured
* - SANE_STATUS_DEVICE_BUSY - the SCSI command could not be issued; try
* again later
*/
extern SANE_Status sanei2_scsi_cmd (int fd,
const void * cmd, size_t cmd_size,
const void * buffer, size_t buffer_size,
int direction, SANE_Byte *sb, size_t *sblen,
SANE_Byte *scsi_status);
/** Flush queue for handle
*
* Flush all SCSI commands pending for one handle
*
* @param fd file descriptor
*
*/
extern void sanei2_scsi_req_flush_all (int fd);
/** Close a SCSI device
*
* @param fd file descriptor
*
*/
extern void sanei2_scsi_close (int fd);
More information about the sane-devel
mailing list