sane-project-website/old-archive/1999-10/0228.html

694 wiersze
24 KiB
HTML

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

<!-- received="Fri Oct 29 12:00:15 1999 PDT" -->
<!-- sent="Fri, 29 Oct 1999 20:56:45 +0200" -->
<!-- name="abel deuring" -->
<!-- email="a.deuring@satzbau-gmbh.de" -->
<!-- subject="Re: SG_BIG_BUFF, glibc 2.1 weirdness ..." -->
<!-- id="" -->
<!-- inreplyto="SG_BIG_BUFF, glibc 2.1 weirdness ..." -->
<title>sane-devel: Re: SG_BIG_BUFF, glibc 2.1 weirdness ...</title>
<h1>Re: SG_BIG_BUFF, glibc 2.1 weirdness ...</h1>
<b>abel deuring</b> (<a href="mailto:a.deuring@satzbau-gmbh.de"><i>a.deuring@satzbau-gmbh.de</i></a>)<br>
<i>Fri, 29 Oct 1999 20:56:45 +0200</i>
<p>
<ul>
<li> <b>Messages sorted by:</b> <a href="date.html#228">[ date ]</a><a href="index.html#228">[ thread ]</a><a href="subject.html#228">[ subject ]</a><a href="author.html#228">[ author ]</a>
<!-- next="start" -->
<li> <b>Next message:</b> <a href="0229.html">abel deuring: "Re: Mustek ScanExpress 6000SP"</a>
<li> <b>Previous message:</b> <a href="0227.html">Levente NOVAK: "Re: xsane-0.41"</a>
<!-- nextthread="start" -->
<!-- reply="end" -->
</ul>
<!-- body="start" -->
Dies ist eine mehrteilige Nachricht im MIME-Format.<br>
--------------5D2267F9E78A0A1B29D131D6<br>
Content-Type: text/plain; charset=us-ascii<br>
Content-Transfer-Encoding: 7bit<br>
<p>
abel deuring wrote:<br>
<p>
<i>&gt; At the end of the mail are some modifications to sanei_scsi.c to</i><br>
<i>&gt; get a "better cooperation" with the new Linux SG driver.</i><br>
<p>
As Ricardo Ferreira discovered, the patches got a little bit damaged, so<br>
here they are again (hopefully better useable...)<br>
<p>
Abel<br>
--------------5D2267F9E78A0A1B29D131D6<br>
Content-Type: text/plain; charset=us-ascii; name="sanei_scsi-diff-sg2.1.34"<br>
Content-Transfer-Encoding: 7bit<br>
Content-Disposition: inline; filename="sanei_scsi-diff-sg2.1.34"<br>
<p>
--- sane-1.0.1-orig/sanei/sanei_scsi.c Sat Apr 17 22:18:18 1999<br>
+++ sane-1.0.1/sanei/sanei_scsi.c Thu Oct 28 22:10:21 1999<br>
@@ -194,6 +194,76 @@<br>
#endif<br>
<br>
int sanei_scsi_max_request_size = MAX_DATA;<br>
+#if USE == LINUX_INTERFACE<br>
+/* the following #defines follow Douglas Gilbert's sample code<br>
+ to maintain run time compatibility with the old and the<br>
+ new SG driver for Linux<br>
+*/<br>
+#ifndef SG_SET_COMMAND_Q<br>
+#define SG_SET_COMMAND_Q 0x2271<br>
+#endif<br>
+#ifndef SG_SET_RESERVED_SIZE<br>
+#define SG_SET_RESERVED_SIZE 0x2275<br>
+#endif <br>
+#ifndef SG_GET_RESERVED_SIZE<br>
+#define SG_GET_RESERVED_SIZE 0x2272<br>
+#endif <br>
+#ifndef SG_GET_SCSI_ID<br>
+#define SG_GET_SCSI_ID 0x2276<br>
+#endif <br>
+#ifndef SG_GET_VERSION_NUM<br>
+#define SG_GET_VERSION_NUM 0x2282<br>
+#endif<br>
+<br>
+#ifndef SCSIBUFFERSIZE<br>
+#define SCSIBUFFERSIZE (128 * 1024)<br>
+#endif<br>
+<br>
+/* the struct returned by the SG ioctl call SG_GET_SCSI_ID changed<br>
+ from version 2.1.34 to 2.1.35, and we need the informations from<br>
+ the field s_queue_depth, which was introduced in 2.1.35.<br>
+ To get this file compiling also with older versions of sg.h, the <br>
+ struct is re-defined here.<br>
+*/<br>
+typedef struct xsg_scsi_id {<br>
+ int host_no; /* as in "scsi&lt;n&gt;" where 'n' is one of 0, 1, 2 etc */<br>
+ int channel;<br>
+ int scsi_id; /* scsi id of target device */<br>
+ int lun;<br>
+ int scsi_type; /* TYPE_... defined in scsi/scsi.h */<br>
+ short h_cmd_per_lun;/* host (adapter) maximum commands per lun */<br>
+ short d_queue_depth;/* device (or adapter) maximum queue length */<br>
+ int unused1; /* probably find a good use, set 0 for now */<br>
+ int unused2; /* ditto */<br>
+} SG_scsi_id;<br>
+<br>
+typedef struct req<br>
+ {<br>
+ struct req *next;<br>
+ int fd;<br>
+ u_int running:1, done:1;<br>
+ SANE_Status status;<br>
+ size_t *dst_len;<br>
+ void *dst;<br>
+ struct<br>
+ {<br>
+ struct sg_header hdr;<br>
+ /* Make sure this is the last element, the real size is<br>
+ SG_BIG_BUFF and machine dependant */<br>
+ u_int8_t data[1];<br>
+ }<br>
+ cdb;<br>
+ }<br>
+req;<br>
+<br>
+typedef struct Fdparms <br>
+ {<br>
+ int sg_queue_used, sg_queue_max;<br>
+ req *sane_qhead, *sane_qtail, *sane_free_list;<br>
+ }<br>
+fdparms;<br>
+<br>
+#endif<br>
<br>
#if USE == FREEBSD_CAM_INTERFACE<br>
# define CAM_MAXDEVS 128<br>
@@ -590,12 +660,25 @@<br>
<br>
#endif /* USE_OS2_INTERFACE */<br>
<br>
+static int num_alloced = 0;<br>
+<br>
+#if USE == LINUX_INTERFACE<br>
+<br>
+SANE_Status<br>
+sanei_scsi_open_extended (const char *dev, int *fdp,<br>
+ SANEI_SCSI_Sense_Handler handler, <br>
+ void *handler_arg, int *buffersize)<br>
+<br>
+#else<br>
+<br>
SANE_Status<br>
sanei_scsi_open (const char *dev, int *fdp,<br>
SANEI_SCSI_Sense_Handler handler, void *handler_arg)<br>
+<br>
+#endif<br>
+<br>
{<br>
u_int bus = 0, target = 0, lun = 0, fake_fd = 0;<br>
- static int num_alloced = 0;<br>
char *real_dev = 0;<br>
void *pdata = 0;<br>
int fd;<br>
@@ -621,6 +704,7 @@<br>
sanei_scsi_max_request_size = atoi (buf);<br>
DBG (1, "sanei_scsi_open: sanei_scsi_max_request_size=%d bytes\n",<br>
sanei_scsi_max_request_size);<br>
+ close(fd);<br>
}<br>
}<br>
#endif<br>
@@ -913,6 +997,109 @@<br>
}<br>
}<br>
#endif /* SGIOCSTL */<br>
+#if USE == LINUX_INTERFACE<br>
+ {<br>
+ SG_scsi_id sid;<br>
+ int ioctl_val, sg_version;<br>
+ int real_buffersize;<br>
+ fdparms *fdpa = 0;<br>
+ <br>
+ pdata = fdpa = malloc(sizeof(fdparms));<br>
+ if (!pdata)<br>
+ {<br>
+ close(fd);<br>
+ return SANE_STATUS_NO_MEM;<br>
+ }<br>
+ memset(fdpa, 0, sizeof(fdparms));<br>
+ /* default: allow only one command to be sent to the SG driver <br>
+ */<br>
+ fdpa-&gt;sg_queue_max = 1;<br>
+<br>
+ /* Try to read the SG version. If the ioctl call is successful, <br>
+ we have the new SG driver, and we can increase the buffer size<br>
+ using another ioctl call. <br>
+ If we have SG version 2.1.35 or above, we can additionally enable<br>
+ command queueing.<br>
+ */<br>
+ if (0 == ioctl(fd, SG_GET_VERSION_NUM, &amp;sg_version))<br>
+ {<br>
+ DBG(1, "sanei_scsi_open: SG driver version: %i\n", sg_version);<br>
+<br>
+ /* try to reserve a SG buffer of the size specified by *buffersize<br>
+ */<br>
+ ioctl(fd, SG_SET_RESERVED_SIZE, buffersize);<br>
+<br>
+ /* the set call may not be able to allocate as much memory<br>
+ as requested, thus we read the actual buffer size.<br>
+<br>
+ NOTE: sanei_scsi_max_request_size is a global variable<br>
+ used for all devices/file handles, while version 2.0 and <br>
+ above of the SG driver allocate buffer memory for each <br>
+ opened file separately. Therefore, we have a possible <br>
+ inconsistency, if more than one file is opened and<br>
+ if the SG_GET_RESERVED_SIZE return different buffer sizes<br>
+ for different file handles. (See Douglas Gilbert's<br>
+ description of the SG driver for details:<br>
+ <a href="http://www.torque.net/sg/p/scsi-generic_long.txt">http://www.torque.net/sg/p/scsi-generic_long.txt</a>)<br>
+ <br>
+ For this reason, sanei_scsi_open does not allow to open <br>
+ two or more file handles simultaneously.<br>
+ */<br>
+ if (0 == ioctl(fd, SG_GET_RESERVED_SIZE, &amp;real_buffersize))<br>
+ {<br>
+ /* if we got more memory than requested, we stick with<br>
+ with the requested value, in order to allow<br>
+ sanei_scsi_open to check the buffer size exactly.<br>
+ */<br>
+ if (real_buffersize &gt; *buffersize)<br>
+ {<br>
+ sanei_scsi_max_request_size = *buffersize;<br>
+ }<br>
+ else<br>
+ {<br>
+ sanei_scsi_max_request_size = real_buffersize;<br>
+ *buffersize = real_buffersize;<br>
+ }<br>
+ }<br>
+ else <br>
+ {<br>
+ DBG(1, "sanei_scsi_open: cannot read SG buffer size - %s\n", <br>
+ strerror(errno));<br>
+ close(fd);<br>
+ return SANE_STATUS_NO_MEM;<br>
+ }<br>
+ DBG(1, "sanei_scsi_open_extended: using %i bytes as SCSI buffer\n", <br>
+ sanei_scsi_max_request_size);<br>
+<br>
+ if (sg_version &gt;= 20135)<br>
+ {<br>
+ DBG(1, "trying to enable low level command queueing\n");<br>
+ <br>
+ if (0 == ioctl(fd, SG_GET_SCSI_ID, &amp;sid)) <br>
+ { <br>
+ DBG(1, "sanei_scsi_open: Host adapter queue depth: %i\n",<br>
+ sid.d_queue_depth);<br>
+ <br>
+ ioctl_val = 1;<br>
+ if(0 == ioctl(fd, SG_SET_COMMAND_Q, &amp;ioctl_val)) <br>
+ {<br>
+ fdpa-&gt;sg_queue_max = sid.d_queue_depth;<br>
+ if (fdpa-&gt;sg_queue_max &lt;= 0)<br>
+ fdpa-&gt;sg_queue_max = 1;<br>
+ }<br>
+ }<br>
+ }<br>
+ }<br>
+ else<br>
+ {<br>
+ /* we have the old SG driver: */<br>
+ if (sanei_scsi_max_request_size &lt; *buffersize)<br>
+ *buffersize = sanei_scsi_max_request_size;<br>
+ }<br>
+ if (fdpa-&gt;sg_queue_max &gt; 1)<br>
+ DBG(1, "sanei_scsi_open: low level command queueing enabled\n");<br>
+ }<br>
+#endif /* LINUX_INTERFACE */<br>
#endif /* !DECUNIX_INTERFACE */<br>
<br>
if (fd &gt;= num_alloced)<br>
@@ -958,9 +1145,78 @@<br>
return SANE_STATUS_GOOD;<br>
}<br>
<br>
+#if USE == LINUX_INTERFACE<br>
+/* The "wrapper" for the old open call */<br>
+SANE_Status<br>
+sanei_scsi_open (const char *dev, int *fdp,<br>
+ SANEI_SCSI_Sense_Handler handler, void *handler_arg)<br>
+{<br>
+ int i, j = 0;<br>
+ int wanted_buffersize = SCSIBUFFERSIZE, real_buffersize;<br>
+ SANE_Status res;<br>
+ char *cc, *cc1;<br>
+<br>
+ cc = getenv("SANE_SG_BUFFERSIZE");<br>
+ if (cc)<br>
+ {<br>
+ i = strtol(cc, &amp;cc1, 10);<br>
+ if (cc != cc1 &amp;&amp; i &gt;= 32768)<br>
+ wanted_buffersize = i;<br>
+ }<br>
+<br>
+ real_buffersize = wanted_buffersize;<br>
+ res = sanei_scsi_open_extended(dev, fdp, handler, handler_arg, <br>
+ &amp;real_buffersize);<br>
+<br>
+ /* make sure that we got as much memory as we wanted, otherwise<br>
+ the backend might be confused<br>
+ */<br>
+ if (real_buffersize != wanted_buffersize)<br>
+ {<br>
+ DBG(1, "sanei_scsi_open: could not allocate SG buffer memory "<br>
+ "wanted: %i got: %i\n", wanted_buffersize, real_buffersize);<br>
+ sanei_scsi_close(*fdp);<br>
+ return SANE_STATUS_NO_MEM;<br>
+ }<br>
+<br>
+ return res;<br>
+}<br>
+#else<br>
+/* dummy for the proposed new open call */<br>
+sanei_scsi_open_extended (const char *dev, int *fdp,<br>
+ SANEI_SCSI_Sense_Handler handler, <br>
+ void *handler_arg, int *buffersize)<br>
+{<br>
+ SANE_Status res;<br>
+ res = sanei_scsi_open(dev, fdp, handler, handler_arg);<br>
+ if (sanei_scsi_max_request_size &lt; *buffersize)<br>
+ *buffersize = sanei_scsi_max_request_size;<br>
+ return res;<br>
+}<br>
+#endif<br>
+<br>
void<br>
sanei_scsi_close (int fd)<br>
{<br>
+#if USE == LINUX_INTERFACE<br>
+ if (fd_info[fd].pdata) <br>
+ {<br>
+ req *req, *next_req;<br>
+ <br>
+ /* make sure that there are no pending SCSI calls */<br>
+ sanei_scsi_req_flush_all_extended(fd);<br>
+<br>
+ req = ((fdparms*) fd_info[fd].pdata)-&gt;sane_free_list;<br>
+ while (req) <br>
+ {<br>
+ next_req = req-&gt;next;<br>
+ free(req);<br>
+ req = next_req;<br>
+ }<br>
+ free(fd_info[fd].pdata);<br>
+ }<br>
+#endif<br>
+<br>
fd_info[fd].in_use = 0;<br>
fd_info[fd].sense_handler = 0;<br>
fd_info[fd].sense_handler_arg = 0;<br>
@@ -1225,69 +1481,133 @@<br>
} \<br>
while (0)<br>
<br>
-static struct req<br>
- {<br>
- struct req *next;<br>
- int fd;<br>
- u_int running:1, done:1;<br>
- SANE_Status status;<br>
- size_t *dst_len;<br>
- void *dst;<br>
- struct<br>
- {<br>
- struct sg_header hdr;<br>
- /* Make sure this is the last element, the real size is<br>
- SG_BIG_BUFF and machine dependant */<br>
- u_int8_t data[1];<br>
- }<br>
- cdb;<br>
- }<br>
-*qhead, *qtail, *free_list;<br>
-<br>
static void<br>
issue (struct req *req)<br>
{<br>
ssize_t nwritten;<br>
+ fdparms *fdp;<br>
+ struct req *rp;<br>
+ int retries;<br>
<br>
- if (!req || req-&gt;running)<br>
+ if (!req)<br>
return;<br>
-<br>
+ fdp = (fdparms*) fd_info[req-&gt;fd].pdata;<br>
DBG (4, "sanei_scsi.issue: %p\n", req);<br>
<br>
- ATOMIC (req-&gt;running = 1;<br>
- nwritten = write (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.pack_len));<br>
-<br>
- if (nwritten != req-&gt;cdb.hdr.pack_len)<br>
- {<br>
- DBG (1, "sanei_scsi.issue: bad write (errno=%s)\n",<br>
- strerror (errno));<br>
- req-&gt;done = 1;<br>
- if (errno == ENOMEM)<br>
- {<br>
- DBG (1, "sanei_scsi.issue: SG_BIG_BUF inconsistency? "<br>
- "Check file PROBLEMS.\n");<br>
- req-&gt;status = SANE_STATUS_NO_MEM;<br>
- }<br>
+ rp = fdp-&gt;sane_qhead;<br>
+ while (rp &amp;&amp; rp-&gt;running)<br>
+ rp = rp-&gt;next;<br>
+<br>
+ while (rp &amp;&amp; fdp-&gt;sg_queue_used &lt; fdp-&gt;sg_queue_max)<br>
+ {<br>
+ retries = 20;<br>
+ while (retries)<br>
+ {<br>
+ ATOMIC (rp-&gt;running = 1;<br>
+ nwritten = write (rp-&gt;fd, &amp;rp-&gt;cdb, rp-&gt;cdb.hdr.pack_len);<br>
+ if (nwritten != rp-&gt;cdb.hdr.pack_len)<br>
+ {<br>
+ /* ENOMEM can easily happen, if both command queueing<br>
+ inside the SG driver and large buffers are used.<br>
+ Therefore, if ENOMEM does not occur for the first <br>
+ command in the queue, we can simply try to issue<br>
+ it later again.<br>
+ */<br>
+ if ( errno == EAGAIN <br>
+ || (errno == ENOMEM &amp;&amp; rp != fdp-&gt;sane_qhead))<br>
+ {<br>
+ /* don't try to send the data again, but<br>
+ wait for the next call to issue()<br>
+ */<br>
+ rp-&gt;running = 0;<br>
+ }<br>
+ }<br>
+ );<br>
+ if (rp == fdp-&gt;sane_qhead &amp;&amp; errno == EAGAIN)<br>
+ {<br>
+ retries--;<br>
+ usleep(10000);<br>
+ }<br>
+ else<br>
+ retries = 0;<br>
+ }<br>
+<br>
+ if (nwritten != rp-&gt;cdb.hdr.pack_len)<br>
+ {<br>
+ if (rp-&gt;running)<br>
+ {<br>
+ DBG (1, "sanei_scsi.issue: bad write (errno=%s)\n",<br>
+ strerror (errno));<br>
+ rp-&gt;done = 1;<br>
+ if (errno == ENOMEM)<br>
+ {<br>
+ DBG (1, "sanei_scsi.issue: SG_BIG_BUF inconsistency? "<br>
+ "Check file PROBLEMS.\n");<br>
+ rp-&gt;status = SANE_STATUS_NO_MEM;<br>
+ }<br>
+ else<br>
+ rp-&gt;status = SANE_STATUS_IO_ERROR;<br>
+ }<br>
+ else<br>
+ {<br>
+ if (errno == ENOMEM)<br>
+ DBG(1, "issue: ENOMEM - cannot queue SCSI command. "<br>
+ "Trying again later.\n");<br>
+ else<br>
+ DBG(1, "issue: cannot queue SCSI command. "<br>
+ "Trying again later.\n");<br>
+ }<br>
+ break; /* in case of an error don't try to queue more commands */<br>
+ }<br>
else<br>
- req-&gt;status = SANE_STATUS_IO_ERROR;<br>
+ fdp-&gt;sg_queue_used++;<br>
+ rp = rp-&gt;next;<br>
}<br>
}<br>
<br>
void<br>
-sanei_scsi_req_flush_all (void)<br>
+sanei_scsi_req_flush_all_extended (int fd)<br>
{<br>
+ fdparms *fdp;<br>
struct req *req, *next_req;<br>
<br>
- for (req = qhead; req; req = next_req)<br>
+ fdp = (fdparms*) fd_info[fd].pdata;<br>
+ for (req = fdp-&gt;sane_qhead; req; req = next_req)<br>
{<br>
if (req-&gt;running &amp;&amp; !req-&gt;done)<br>
- read (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.reply_len);<br>
+ {<br>
+ read (fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.reply_len);<br>
+ ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sg_queue_used--;<br>
+ }<br>
next_req = req-&gt;next;<br>
<br>
- req-&gt;next = free_list;<br>
- free_list = req;<br>
+ req-&gt;next = fdp-&gt;sane_free_list;<br>
+ fdp-&gt;sane_free_list = req;<br>
}<br>
- qhead = qtail = 0;<br>
+ fdp-&gt;sane_qhead = fdp-&gt;sane_qtail = 0;<br>
+}<br>
+<br>
+void<br>
+sanei_scsi_req_flush_all ()<br>
+{<br>
+ int fd, i, j = 0;<br>
+ <br>
+ /* sanei_scsi_open allows only one open file handle, so we<br>
+ can simply look for the first entry where in_use is set<br>
+ */<br>
+ +<br>
+ fd = num_alloced;<br>
+ for (i = 0; i &lt; num_alloced; i++)<br>
+ if (fd_info[i].in_use)<br>
+ {<br>
+ j++;<br>
+ fd = i;<br>
+ }<br>
+ <br>
+ assert(j &lt; 2);<br>
+ <br>
+ if (fd &lt; num_alloced)<br>
+ sanei_scsi_req_flush_all_extended(fd);<br>
}<br>
<br>
SANE_Status<br>
@@ -1296,11 +1616,14 @@<br>
{<br>
struct req *req;<br>
size_t size;<br>
+ fdparms *fdp;<br>
+<br>
+ fdp = (fdparms*) fd_info[fd].pdata;<br>
<br>
- if (free_list)<br>
+ if (fdp-&gt;sane_free_list)<br>
{<br>
- req = free_list;<br>
- free_list = req-&gt;next;<br>
+ req = fdp-&gt;sane_free_list;<br>
+ fdp-&gt;sane_free_list = req-&gt;next;<br>
req-&gt;next = 0;<br>
}<br>
else<br>
@@ -1328,17 +1651,23 @@<br>
memcpy (&amp;req-&gt;cdb.data, src, src_size);<br>
<br>
req-&gt;next = 0;<br>
- ATOMIC (if (qtail)<br>
+ ATOMIC (if (fdp-&gt;sane_qtail)<br>
{<br>
- qtail-&gt;next = req;<br>
- qtail = req;<br>
+ fdp-&gt;sane_qtail-&gt;next = req;<br>
+ fdp-&gt;sane_qtail = req;<br>
}<br>
else<br>
- qhead = qtail = req);<br>
+ fdp-&gt;sane_qhead = fdp-&gt;sane_qtail = req);<br>
<br>
DBG (4, "scsi_req_enter: entered %p\n", req);<br>
<br>
*idp = req;<br>
+ issue(req);<br>
+<br>
+ DBG(10, "scsi_req_enter: queue_used: %i, queue_max: %i\n",<br>
+ ((fdparms*) fd_info[fd].pdata)-&gt;sg_queue_used,<br>
+ ((fdparms*) fd_info[fd].pdata)-&gt;sg_queue_max);<br>
+<br>
return SANE_STATUS_GOOD;<br>
}<br>
<br>
@@ -1349,7 +1678,8 @@<br>
struct req *req = id;<br>
ssize_t nread = 0;<br>
<br>
- assert (req == qhead); /* we don't support out-of-order completion */<br>
+ /* we don't support out-of-order completion */<br>
+ assert (req == ((fdparms*)fd_info[req-&gt;fd].pdata)-&gt;sane_qhead);<br>
<br>
DBG (4, "sanei_scsi_req_wait: waiting for %p\n", req);<br>
<br>
@@ -1372,6 +1702,9 @@<br>
ATOMIC (nread = read (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.reply_len);<br>
req-&gt;done = 1);<br>
<br>
+ if (fd_info[req-&gt;fd].pdata)<br>
+ ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sg_queue_used--;<br>
+<br>
/* Now issue next command asap, if any. We can't do this<br>
earlier since the Linux kernel has space for just one big<br>
buffer. */<br>
@@ -1423,11 +1756,12 @@<br>
}<br>
<br>
/* dequeue and release processed request: */<br>
- ATOMIC (qhead = qhead-&gt;next;<br>
- if (!qhead)<br>
- qtail = 0;<br>
- req-&gt;next = free_list;<br>
- free_list = req);<br>
+ ATOMIC (((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_qhead <br>
+ = ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_qhead-&gt;next;<br>
+ if (!((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_qhead)<br>
+ ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_qtail = 0;<br>
+ req-&gt;next = ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_free_list;<br>
+ ((fdparms*) fd_info[req-&gt;fd].pdata)-&gt;sane_free_list = req);<br>
return status;<br>
}<br>
<br>
--- sane-1.0.1-orig/include/sane/sanei_scsi.h Thu May 14 08:08:22 1998<br>
+++ sane-1.0.1/include/sane/sanei_scsi.h Sat Sep 25 18:25:24 1999<br>
@@ -48,6 +48,31 @@<br>
SANEI_SCSI_Sense_Handler sense_handler,<br>
void *sense_arg);<br>
<br>
+/* The extended open call allows a backend to ask for a specific<br>
+ buffer size. sanei_scsi_open tries to allocate a buffer of the<br>
+ size given by *buffersize upon entry to this function. If<br>
+ sanei_scsi_open_extended returns successfully, *buffersize<br>
+ contains the available buffer size. This value may be both<br>
+ smaller or larger than the value requested by the backend;<br>
+ it can even be zero. The backend must decide, if it got enough<br>
+ buffer memory to work.<br>
+ <br>
+ Note that the value of *buffersize may differ for different<br>
+ files.<br>
+*/<br>
+extern SANE_Status sanei_scsi_open_extended (<br>
+ const char * device_name, int * fd,<br>
+ SANEI_SCSI_Sense_Handler sense_handler, <br>
+ void *sense_arg, int *buffersize);<br>
+<br>
+/* Let backends decide, which open call to use: <br>
+ if HAVE_SANEI_SCSI_OPEN_EXTENDED is defined, sanei_scsi_open_extended<br>
+ may be used.<br>
+ May also be used to decide, if sanei_scsi_req_flush_all or<br>
+ sanei_scsi_req_flush_all_extended should be used.<br>
+*/<br>
+#define HAVE_SANEI_SCSI_OPEN_EXTENDED<br>
+<br>
/* One or more scsi commands can be enqueued by calling req_enter().<br>
SRC is the pointer to the SCSI command and associated write data<br>
and SRC_SIZE is the length of the command and data. DST is a<br>
@@ -76,8 +101,13 @@<br>
const void * src, size_t src_size,<br>
void * dst, size_t * dst_size);<br>
<br>
-/* Flush all pending SCSI commands. */<br>
+/* Flush all pending SCSI commands. This function work only,<br>
+ if zero or one SCSI file handles are open.<br>
+*/<br>
extern void sanei_scsi_req_flush_all (void);<br>
+<br>
+/* Flush all SCSI commands pending for one handle */<br>
+extern void sanei_scsi_req_flush_all_extended (int fd);<br>
<br>
extern void sanei_scsi_close (int fd);<br>
<br>
--- sane-1.0.1-orig/configure.in Sun Apr 4 00:44:56 1999<br>
+++ sane-1.0.1/configure.in Mon Sep 20 20:41:44 1999<br>
@@ -192,10 +192,19 @@<br>
else<br>
DLL_PRELOAD=""<br>
fi<br>
+<br>
+AC_ARG_ENABLE(scsibuffersize, <br>
+ [ --enable-scsibuffersize=N <br>
+ specify the default size of the buffer for SCSI commands],<br>
+ [set_scsibuffersize="$enableval"], [set_scsibuffersize=131072])<br>
+CFLAGS="$CFLAGS -DSCSIBUFFERSIZE=$set_scsibuffersize"<br>
+echo "scsi buffersize: $set_scsibuffersize"<br>
+<br>
AC_SUBST(V_MAJOR)<br>
AC_SUBST(V_MINOR)<br>
AC_SUBST(V_REV)<br>
AC_SUBST(DLL_PRELOAD)<br>
+<br>
<br>
AC_OUTPUT([Makefile lib/Makefile sanei/Makefile frontend/Makefile<br>
japi/Makefile backend/Makefile include/Makefile doc/Makefile<br>
<p>
<p>
--------------5D2267F9E78A0A1B29D131D6--<br>
<p>
<p>
<pre>
--
Source code, list archive, and docs: <a href="http://www.mostang.com/sane/">http://www.mostang.com/sane/</a>
To unsubscribe: echo unsubscribe sane-devel | mail <a href="mailto:majordomo@mostang.com">majordomo@mostang.com</a>
</pre>
<!-- body="end" -->
<p>
<ul>
<!-- next="start" -->
<li> <b>Next message:</b> <a href="0229.html">abel deuring: "Re: Mustek ScanExpress 6000SP"</a>
<li> <b>Previous message:</b> <a href="0227.html">Levente NOVAK: "Re: xsane-0.41"</a>
<!-- nextthread="start" -->
<!-- reply="end" -->
</ul>