Switch sanei_scsi to the SG_IO ioctl interface, instead of the

asynchronous SG3 read/write interface.

Makes it possible to use SCSI scanners in 32/64bit mixed environments,
thanks to the ioctl 32bit compatibility layer, which is NOT possible
using the SG3 interface.
merge-requests/1/head
Julien BLACHE 2007-06-21 19:35:53 +00:00
rodzic dd7aa7403b
commit 5dcf165795
2 zmienionych plików z 62 dodań i 34 usunięć

Wyświetl plik

@ -1,3 +1,11 @@
2007-06-21 Julien Blache <jb@jblache.org>
* sanei/sanei_scsi.c: Switch sanei_scsi to the SG_IO ioctl
interface, instead of the asynchronous SG3 read/write interface.
Makes it possible to use SCSI scanners in 32/64bit mixed
environments, thanks to the ioctl 32bit compatibility layer, which
is NOT possible using the SG3 interface.
2007-06-18 Gerhard Jaeger <gerhard@gjaeger.de> 2007-06-18 Gerhard Jaeger <gerhard@gjaeger.de>
* doc/plustek/Plustek-PARPORT.changes: Update. * doc/plustek/Plustek-PARPORT.changes: Update.

Wyświetl plik

@ -207,10 +207,6 @@
# include <ddk/ntddscsi.h> # include <ddk/ntddscsi.h>
#endif #endif
#ifdef DISABLE_LINUX_SG_IO
#undef SG_IO
#endif /* DISABLE_LINUX_SG_IO */
#ifndef USE #ifndef USE
# define USE STUBBED_INTERFACE # define USE STUBBED_INTERFACE
#endif #endif
@ -1852,6 +1848,7 @@ issue (struct req *req)
fdparms *fdp; fdparms *fdp;
struct req *rp; struct req *rp;
int retries; int retries;
int ret;
if (!req) if (!req)
return; return;
@ -1876,6 +1873,7 @@ issue (struct req *req)
ATOMIC (rp->running = 1; ATOMIC (rp->running = 1;
nwritten = write (rp->fd, &rp->sgdata.cdb, nwritten = write (rp->fd, &rp->sgdata.cdb,
rp->sgdata.cdb.hdr.pack_len); rp->sgdata.cdb.hdr.pack_len);
ret = 0;
if (nwritten != rp->sgdata.cdb.hdr.pack_len) if (nwritten != rp->sgdata.cdb.hdr.pack_len)
{ {
/* ENOMEM can easily happen, if both command queueing /* ENOMEM can easily happen, if both command queueing
@ -1898,9 +1896,9 @@ issue (struct req *req)
else else
{ {
ATOMIC (rp->running = 1; ATOMIC (rp->running = 1;
nwritten = ret = ioctl(rp->fd, SG_IO, &rp->sgdata.sg3.hdr);
write (rp->fd, &rp->sgdata.sg3.hdr, sizeof (Sg_io_hdr)); nwritten = 0;
if (nwritten < 0) if (ret < 0)
{ {
/* ENOMEM can easily happen, if both command queuein /* ENOMEM can easily happen, if both command queuein
inside the SG driver and large buffers are used. inside the SG driver and large buffers are used.
@ -1908,13 +1906,20 @@ issue (struct req *req)
command in the queue, we simply try to issue command in the queue, we simply try to issue
it later again. it later again.
*/ */
if (errno == EAGAIN if (errno == EAGAIN
|| (errno == ENOMEM && rp != fdp->sane_qhead)) || (errno == ENOMEM && rp != fdp->sane_qhead))
{ {
/* don't try to send the data again, but /* don't try to send the data again, but
wait for the next call to issue() wait for the next call to issue()
*/ */
rp->running = 0;} rp->running = 0;
}
else /* game over */
{
rp->running = 0;
rp->done = 1;
rp->status = SANE_STATUS_IO_ERROR;
}
} }
); );
IF_DBG (if (DBG_LEVEL >= 255) IF_DBG (if (DBG_LEVEL >= 255)
@ -1934,16 +1939,21 @@ issue (struct req *req)
if (nwritten != rp->sgdata.cdb.hdr.pack_len) if (nwritten != rp->sgdata.cdb.hdr.pack_len)
#else #else
if ((sg_version < 30000 && nwritten != rp->sgdata.cdb.hdr.pack_len) if ((sg_version < 30000 && nwritten != rp->sgdata.cdb.hdr.pack_len)
/* xxx doesn't work yet with kernel 2.3.18: || (sg_version >= 30000 && ret < 0))
|| (sg_version >= 30000 && nwritten < sizeof(Sg_io_hdr)))
*/
|| (sg_version >= 30000 && nwritten < 0))
#endif #endif
{ {
if (rp->running) if (rp->running)
{ {
DBG (1, "sanei_scsi.issue: bad write (errno=%i) %s %li\n", #ifdef SG_IO
errno, strerror (errno), (long)nwritten); if (sg_version < 30000)
#endif
DBG (1, "sanei_scsi.issue: bad write (errno=%i) %s %li\n",
errno, strerror (errno), (long)nwritten);
#ifdef SG_IO
else if (sg_version > 30000)
DBG (1, "sanei_scsi.issue: SG_IO ioctl error (errno=%i, ret=%d) %s\n",
errno, ret, strerror (errno));
#endif
rp->done = 1; rp->done = 1;
if (errno == ENOMEM) if (errno == ENOMEM)
{ {
@ -1966,11 +1976,20 @@ issue (struct req *req)
break; /* in case of an error don't try to queue more commands */ break; /* in case of an error don't try to queue more commands */
} }
else else
req->status = SANE_STATUS_IO_ERROR; {
#ifdef SG_IO
if (sg_version < 30000)
#endif
req->status = SANE_STATUS_IO_ERROR;
#ifdef SG_IO
else if (sg_version > 30000) /* SG_IO is synchronous, we're all set */
req->status = SANE_STATUS_GOOD;
#endif
}
fdp->sg_queue_used++; fdp->sg_queue_used++;
rp = rp->next; rp = rp->next;
}
} }
}
void sanei_scsi_req_flush_all_extended (int fd) void sanei_scsi_req_flush_all_extended (int fd)
{ {
@ -2009,6 +2028,7 @@ issue (struct req *req)
req->next = fdp->sane_free_list; req->next = fdp->sane_free_list;
fdp->sane_free_list = req; fdp->sane_free_list = req;
} }
fdp->sane_qhead = fdp->sane_qtail = 0; fdp->sane_qhead = fdp->sane_qtail = 0;
} }
@ -2197,18 +2217,18 @@ issue (struct req *req)
} }
else else
{ {
fd_set readable;
/* wait for command completion: */
FD_ZERO (&readable);
FD_SET (req->fd, &readable);
select (req->fd + 1, &readable, 0, 0, 0);
/* now atomically read result and set DONE: */
#ifdef SG_IO #ifdef SG_IO
if (sg_version < 30000) if (sg_version < 30000)
{ {
#endif #endif
fd_set readable;
/* wait for command completion: */
FD_ZERO (&readable);
FD_SET (req->fd, &readable);
select (req->fd + 1, &readable, 0, 0, 0);
/* now atomically read result and set DONE: */
ATOMIC (nread = read (req->fd, &req->sgdata.cdb, ATOMIC (nread = read (req->fd, &req->sgdata.cdb,
req->sgdata.cdb.hdr.reply_len); req->sgdata.cdb.hdr.reply_len);
req->done = 1); req->done = 1);
@ -2218,10 +2238,10 @@ issue (struct req *req)
{ {
IF_DBG (if (DBG_LEVEL >= 255) IF_DBG (if (DBG_LEVEL >= 255)
system ("cat /proc/scsi/sg/debug 1>&2");) system ("cat /proc/scsi/sg/debug 1>&2");)
ATOMIC (nread =
read (req->fd, &req->sgdata.sg3.hdr, /* set DONE: */
sizeof (Sg_io_hdr)); nread = 0; /* unused in this code path */
req->done = 1); req->done = 1;
} }
#endif #endif