kopia lustrzana https://gitlab.com/sane-project/website
227 wiersze
9.1 KiB
HTML
227 wiersze
9.1 KiB
HTML
<!-- received="Tue Jan 26 04:24:50 1999 PST" -->
|
|
<!-- sent="Tue, 26 Jan 1999 00:23:14 -0700 (MST)" -->
|
|
<!-- name="Andreas Dilger" -->
|
|
<!-- email="adilger@enel.ucalgary.ca" -->
|
|
<!-- subject="Strange memcpy in sanei_scsi.c" -->
|
|
<!-- id="199901260723.AAA04578@andreas.dilger.net" -->
|
|
<!-- inreplyto="" -->
|
|
<title>sane-devel: Strange memcpy in sanei_scsi.c</title>
|
|
<h1>Strange memcpy in sanei_scsi.c</h1>
|
|
<b>Andreas Dilger</b> (<a href="mailto:adilger@enel.ucalgary.ca"><i>adilger@enel.ucalgary.ca</i></a>)<br>
|
|
<i>Tue, 26 Jan 1999 00:23:14 -0700 (MST)</i>
|
|
<p>
|
|
<ul>
|
|
<li> <b>Messages sorted by:</b> <a href="date.html#226">[ date ]</a><a href="index.html#226">[ thread ]</a><a href="subject.html#226">[ subject ]</a><a href="author.html#226">[ author ]</a>
|
|
<!-- next="start" -->
|
|
<li> <b>Next message:</b> <a href="0227.html">Andreas Dilger: "Re: Frontend XSane-0.06 available"</a>
|
|
<li> <b>Previous message:</b> <a href="0225.html">Petter Reinholdtsen: "Re: SG_BIG_BUFF woes on Linux"</a>
|
|
<!-- nextthread="start" -->
|
|
<!-- reply="end" -->
|
|
</ul>
|
|
<!-- body="start" -->
|
|
I was looking at whether I could change the code in sanei_scsi.c to use<br>
|
|
a dynamically allocated data buffer (SG_BIG_BUFF related), and I came<br>
|
|
across something strange in sanei_scsi.c:<br>
|
|
<p>
|
|
In the function sanei_scsi_req_enter(), we do a<br>
|
|
memcpy (&req->cdb.data, src, src_size);<br>
|
|
<p>
|
|
but in the function sanei_scsi_req_wait(), there is a call<br>
|
|
memcpy (req->dst, req->cdb.data, nread);<br>
|
|
<p>
|
|
which is not properly getting the address of the statically allocated<br>
|
|
data buffer when it is doing the memcpy. This should fail miserably,<br>
|
|
but is it possible that this part of sanei_scsi_req_wait() function<br>
|
|
isn't used very often?<br>
|
|
<p>
|
|
Hope to hear from someone in the know...<br>
|
|
<p>
|
|
Also below is a preliminary patch to allow for dynamic SG_BIG_BUFF under<br>
|
|
Linux. It compiles, but has not been tested at all, so YMMV.<br>
|
|
The patch quiets one minor compiler warning at the beginning, and also<br>
|
|
closes the file descriptor used to read from /proc/sys/kernel/sg-big-buff.<br>
|
|
Good luck...<br>
|
|
<p>
|
|
Cheers, Andreas<br>
|
|
_______________________________________________<br>
|
|
--- sanei_scsi.c.orig Mon Jan 25 22:27:33 1999<br>
|
|
+++ sanei_scsi.c Tue Jan 26 00:11:59 1999<br>
|
|
@@ -211,11 +211,13 @@<br>
|
|
}<br>
|
|
*fd_info;<br>
|
|
<br>
|
|
+#if USE != LINUX_INTERFACE<br>
|
|
static u_char cdb_sizes[8] =<br>
|
|
{<br>
|
|
6, 10, 10, 12, 12, 12, 10, 10<br>
|
|
};<br>
|
|
#define CDB_SIZE(opcode) cdb_sizes[(((opcode) >> 5) & 7)]<br>
|
|
+#endif<br>
|
|
<br>
|
|
<br>
|
|
#if USE == DOMAINOS_INTERFACE<br>
|
|
@@ -608,6 +610,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>
|
|
@@ -1224,11 +1227,10 @@<br>
|
|
size_t *dst_len;<br>
|
|
void *dst;<br>
|
|
struct<br>
|
|
- {<br>
|
|
- struct sg_header hdr;<br>
|
|
- u_int8_t data[SG_BIG_BUFF];<br>
|
|
- }<br>
|
|
- cdb;<br>
|
|
+ {<br>
|
|
+ struct sg_header *hdr;<br>
|
|
+ u_int8_t *data;<br>
|
|
+ } cdb;<br>
|
|
struct req *next;<br>
|
|
}<br>
|
|
*qhead, *qtail, *free_list;<br>
|
|
@@ -1244,9 +1246,9 @@<br>
|
|
DBG (4, "sanei_scsi.issue: %p\n", req);<br>
|
|
<br>
|
|
ATOMIC (req->running = 1;<br>
|
|
- nwritten = write (req->fd, &req->cdb, req->cdb.hdr.pack_len));<br>
|
|
+ nwritten = write (req->fd, req->cdb.hdr, req->cdb.hdr->pack_len));<br>
|
|
<br>
|
|
- if (nwritten != req->cdb.hdr.pack_len)<br>
|
|
+ if (nwritten != req->cdb.hdr->pack_len)<br>
|
|
{<br>
|
|
DBG (1, "sanei_scsi.issue: bad write (errno=%s)\n",<br>
|
|
strerror (errno));<br>
|
|
@@ -1270,7 +1272,7 @@<br>
|
|
for (req = qhead; req; req = next_req)<br>
|
|
{<br>
|
|
if (req->running && !req->done)<br>
|
|
- read (req->fd, &req->cdb, req->cdb.hdr.reply_len);<br>
|
|
+ read (req->fd, req->cdb.hdr, req->cdb.hdr->reply_len);<br>
|
|
next_req = req->next;<br>
|
|
<br>
|
|
req->next = free_list;<br>
|
|
@@ -1293,13 +1295,34 @@<br>
|
|
}<br>
|
|
else<br>
|
|
{<br>
|
|
- req = malloc (sizeof (*req));<br>
|
|
- if (!req)<br>
|
|
+ req = (struct req *) malloc (sizeof (struct req));<br>
|
|
+ if (req == NULL)<br>
|
|
{<br>
|
|
- DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes\n",<br>
|
|
- (u_long) sizeof (*req));<br>
|
|
+ DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes for req\n",<br>
|
|
+ (u_long) sizeof (struct req));<br>
|
|
return SANE_STATUS_NO_MEM;<br>
|
|
}<br>
|
|
+<br>
|
|
+ /* Allocate enough space for both the header and the buffer (whatever<br>
|
|
+ * the kernel max buffer size is currently configured as), to ensure they<br>
|
|
+ * are contiguous, but then set the .data pointer separately, so we can<br>
|
|
+ * access the data directly. It appears, from the read and write calls<br>
|
|
+ * to the SCSI device that the .hdr and .data segments must be contiguous.<br>
|
|
+ * If that isn't the case, we don't have to be so convoluted.<br>
|
|
+ * Make sure we only free .hdr and not .data (if freeing is ever done)!<br>
|
|
+ */<br>
|
|
+ req->cdb.hdr = (struct sg_header *) malloc (sizeof (struct sg_header) +<br>
|
|
+ sanei_scsi_max_request_size);<br>
|
|
+ if (req->cdb.hdr == NULL)<br>
|
|
+ {<br>
|
|
+ DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes for cdb\n",<br>
|
|
+ (u_long) (sizeof (struct sg_header) +<br>
|
|
+ sanei_scsi_max_request_size));<br>
|
|
+ free (req);<br>
|
|
+ return SANE_STATUS_NO_MEM;<br>
|
|
+ }<br>
|
|
+ else<br>
|
|
+ req->cdb.data = (u_int8_t *) (req->cdb.hdr + sizeof (struct sg_header));<br>
|
|
}<br>
|
|
req->fd = fd;<br>
|
|
req->running = 0;<br>
|
|
@@ -1307,11 +1330,11 @@<br>
|
|
req->status = SANE_STATUS_GOOD;<br>
|
|
req->dst = dst;<br>
|
|
req->dst_len = dst_size;<br>
|
|
- memset (&req->cdb.hdr, 0, sizeof (req->cdb.hdr));<br>
|
|
- req->cdb.hdr.pack_id = pack_id++;<br>
|
|
- req->cdb.hdr.pack_len = src_size + sizeof (req->cdb.hdr);<br>
|
|
- req->cdb.hdr.reply_len = (dst_size ? *dst_size : 0) + sizeof (req->cdb.hdr);<br>
|
|
- memcpy (&req->cdb.data, src, src_size);<br>
|
|
+ memset (req->cdb.hdr, 0, sizeof (struct sg_header));<br>
|
|
+ req->cdb.hdr->pack_id = pack_id++;<br>
|
|
+ req->cdb.hdr->pack_len = src_size + sizeof (struct sg_header);<br>
|
|
+ req->cdb.hdr->reply_len = (dst_size ? *dst_size : 0) + sizeof (struct sg_header);<br>
|
|
+ memcpy (req->cdb.data, src, src_size);<br>
|
|
<br>
|
|
req->next = 0;<br>
|
|
ATOMIC (if (qtail)<br>
|
|
@@ -1355,7 +1378,7 @@<br>
|
|
select (req->fd + 1, &readable, 0, 0, 0);<br>
|
|
<br>
|
|
/* now atomically read result and set DONE: */<br>
|
|
- ATOMIC (nread = read (req->fd, &req->cdb, req->cdb.hdr.reply_len);<br>
|
|
+ ATOMIC (nread = read (req->fd, req->cdb.hdr, req->cdb.hdr->reply_len);<br>
|
|
req->done = 1);<br>
|
|
<br>
|
|
/* Now issue next command asap, if any. We can't do this<br>
|
|
@@ -1373,25 +1396,25 @@<br>
|
|
}<br>
|
|
else<br>
|
|
{<br>
|
|
- nread -= sizeof (req->cdb.hdr);<br>
|
|
+ nread -= sizeof (struct sg_header);<br>
|
|
<br>
|
|
/* check for errors, but let the sense_handler decide.... */<br>
|
|
- if ((req->cdb.hdr.result != 0) ||<br>
|
|
- ((req->cdb.hdr.sense_buffer[0] & 0x7f) != 0))<br>
|
|
+ if ((req->cdb.hdr->result != 0) ||<br>
|
|
+ ((req->cdb.hdr->sense_buffer[0] & 0x7f) != 0))<br>
|
|
{<br>
|
|
SANEI_SCSI_Sense_Handler handler<br>
|
|
= fd_info[req->fd].sense_handler;<br>
|
|
void *arg = fd_info[req->fd].sense_handler_arg;<br>
|
|
<br>
|
|
DBG (1, "sanei_scsi_req_wait: SCSI command complained: %s\n",<br>
|
|
- strerror (req->cdb.hdr.result));<br>
|
|
+ strerror (req->cdb.hdr->result));<br>
|
|
<br>
|
|
- if (req->cdb.hdr.result == EBUSY)<br>
|
|
+ if (req->cdb.hdr->result == EBUSY)<br>
|
|
status = SANE_STATUS_DEVICE_BUSY;<br>
|
|
else if (handler)<br>
|
|
/* sense handler should return SANE_STATUS_GOOD if it<br>
|
|
decided all was ok afterall */<br>
|
|
- status = (*handler) (req->fd, req->cdb.hdr.sense_buffer, arg);<br>
|
|
+ status = (*handler) (req->fd, req->cdb.hdr->sense_buffer, arg);<br>
|
|
else<br>
|
|
status = SANE_STATUS_IO_ERROR;<br>
|
|
}<br>
|
|
________________________<br>
|
|
<pre>
|
|
--
|
|
Andreas Dilger University of Calgary \ "If a man ate a pound of pasta and
|
|
Micronet Research Group \ a pound of antipasto, would they
|
|
Dept of Electrical & Computer Engineering \ cancel out, leaving him still
|
|
<<a href="http://www-mddsp.enel.ucalgary.ca/People/adilger/">http://www-mddsp.enel.ucalgary.ca/People/adilger/</a>> hungry?" -- Dogbert
|
|
<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="0227.html">Andreas Dilger: "Re: Frontend XSane-0.06 available"</a>
|
|
<li> <b>Previous message:</b> <a href="0225.html">Petter Reinholdtsen: "Re: SG_BIG_BUFF woes on Linux"</a>
|
|
<!-- nextthread="start" -->
|
|
<!-- reply="end" -->
|
|
</ul>
|