[7208] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

Re: Fixing SCSI Layer

daemon@ATHENA.MIT.EDU (Tony Chung)
Fri Sep 10 19:31:51 1999

Date:   Fri, 10 Sep 1999 16:29:22 -0700
From:   Tony Chung <chungto@ampex.com>
To:     Gerard Roudier <groudier@club-internet.fr>
CC:     "Kenneth D. Merry" <ken@kdm.org>, linux-scsi@vger.rutgers.edu


--------------94C81D8C5394AA4620FEE520
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

Let me clarify this with an example:

if ((flag & UDI_SCSI_DATA_IN )&& (flag &UDI_SCSI_DATA_OUT))
{
    ...   // return error
} else if (flag & UDI_SCSI_DATA_IN)
{
    ... // get data from target
} else if (flag & UDI_SCSI_DATA_OUT)
{
    ...// send data to target
} else {
    ... // no data e.g. format/test unit ready/
}

So you do not need a mask.
You can  even skip the error checking (user mistakenly setting both IN & OUT)
because
1. you will get "unexpected data phase" if user really want UDI_SCSI_DATA_OUT or NONE
2. you will get data from target if you really want UDI_SCSI_DATA_IN (the
UDI_SCSI_DATA_OUT is
    simply ignored).







Gerard Roudier wrote:

> On Fri, 10 Sep 1999, Tony Chung wrote:
>
> > "Kenneth D. Merry" wrote:
> >
> > > Tony Chung wrote...
> > > >
> > > >
> > > > >
> > > > > 1 - Add a 'direction' field to the scsi command structure that can be
> > > > >     filled with the following values:
> > > > >       DIR_INPUT, DIR_OUTPUT, DIR_NONE and DIR_UNKNOWN=0
> > > > >       Set this field to DIR_UNKNOWN=0 by default.
> > > > >
> > > >
> > > > >From Digital Unix  /usr/include/io/cam.h:
> > > >
> > > > /* Defines for the CAM flags field in the CCB header. */
> > > >
> > > > #define CAM_DIR_RESV       0x00000000   /* Data direction (00: reserved) */
> > > > #define CAM_DIR_IN         0x00000040   /* Data direction (01: DATA IN) */
> > > > #define CAM_DIR_OUT        0x00000080   /* Data direction (10: DATA OUT) */
> > > > #define CAM_DIR_NONE       0x000000C0   /* Data direction (11: no data) */
> > > >
> > > > While UDI scsi spec has:
> > > > #define UDI_SCSI_DATA_IN   (1U<<0)
> > > > #define UDI_SCSI_DATA_OUT (1U<<1)
> > > >
> > > > Basically, it can't be UNKNOWN because the Peripheral Driver must specify the
> > > > buffer address and total transfer size. Any  inconsistencies should return error
> > > >
> > > > or let the host adaptor card simply return data overrun or data underrun.
> > > >
> > > >
> > > > I found CAM_DIR_NONE is potential hazard because
> > > > if some one specify CAM_DIR_NONE, another person
> > > > may mistakenly check for:
> > > >         If (flags & CAM_DIR_OUT) ...../* condition true and do something wrong
> > > > */
> > >
> > > In FreeBSD/CAM, we added a mask:
> > >
> > >         CAM_DIR_RESV            = 0x00000000,/* Data direction (00:reserved)  */
> > >         CAM_DIR_IN              = 0x00000040,/* Data direction (01:DATA IN)   */
> > >         CAM_DIR_OUT             = 0x00000080,/* Data direction (10:DATA OUT)  */
> > >         CAM_DIR_NONE            = 0x000000C0,/* Data direction (11:no data)   */
> > >         CAM_DIR_MASK            = 0x000000C0,/* Data direction Mask           */
> > >
> > > So to determine the data direction:
> > >
> > > if ((flags & CAM_DIR_MASK) == CAM_DIR_OUT)
> > >         ...
> >
> > I think CAM_DIR_MASK is a workaround for the original design flaw.
> >
> > Comparing to UDI, only two defines versus five defines in CAM.
>
> You may well suffer of a serious brain problem, my dear. There are 3
> needed values (IN/OUT/NONE). This requires 2 bits of data. If you want to
> define enough values to deal with such a bit field you need a mask and the
> 4 possible values.
>
> > And one "&" operation versus two operations (&,==) in CAM.
>
> Do you mean that UDI is able to transfer data in both directions at the
> same time when user provides both DATA_IN bit and DATA_OUT bit ?
>
> > Obviously, UDI is better at least here :-).
>
> Indeed, CAM is unable to read and write data at the same time on a single
> SCSI BUS. ;-)
>
> Gérard.
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.rutgers.edu

--
=============================
Tony Chung



--------------94C81D8C5394AA4620FEE520
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Let me clarify this with an example:
<p>if ((flag &amp; UDI_SCSI_DATA_IN&nbsp;)&amp;&amp; (flag &amp;UDI_SCSI_DATA_OUT))
<br>{
<br>&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp; // return error
<br>} else if (flag &amp; UDI_SCSI_DATA_IN)
<br>{
<br>&nbsp;&nbsp;&nbsp; ... // get data from target
<br>} else if (flag &amp; UDI_SCSI_DATA_OUT)
<br>{
<br>&nbsp;&nbsp;&nbsp; ...// send data to target
<br>} else {
<br>&nbsp;&nbsp;&nbsp; ... // no data e.g. format/test unit ready/
<br>}
<p>So you do not need a mask.
<br>You can&nbsp; even skip the error checking (user mistakenly setting
both IN &amp; OUT)
<br>because
<br>1. you will get "unexpected data phase" if user really want UDI_SCSI_DATA_OUT
or NONE
<br>2. you will get data from target if you really want UDI_SCSI_DATA_IN&nbsp;(the&nbsp;
UDI_SCSI_DATA_OUT is
<br>&nbsp;&nbsp;&nbsp; simply ignored).
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<p>Gerard Roudier wrote:
<blockquote TYPE=CITE>On Fri, 10 Sep 1999, Tony Chung wrote:
<p>> "Kenneth D. Merry" wrote:
<br>>
<br>> > Tony Chung wrote...
<br>> > >
<br>> > >
<br>> > > >
<br>> > > > 1 - Add a 'direction' field to the scsi command structure that
can be
<br>> > > >&nbsp;&nbsp;&nbsp;&nbsp; filled with the following values:
<br>> > > >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIR_INPUT, DIR_OUTPUT,
DIR_NONE and DIR_UNKNOWN=0
<br>> > > >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set this field to DIR_UNKNOWN=0
by default.
<br>> > > >
<br>> > >
<br>> > > >From Digital Unix&nbsp; /usr/include/io/cam.h:
<br>> > >
<br>> > > /* Defines for the CAM flags field in the CCB header. */
<br>> > >
<br>> > > #define CAM_DIR_RESV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00000000&nbsp;&nbsp;
/* Data direction (00: reserved) */
<br>> > > #define CAM_DIR_IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0x00000040&nbsp;&nbsp; /* Data direction (01: DATA IN) */
<br>> > > #define CAM_DIR_OUT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0x00000080&nbsp;&nbsp; /* Data direction (10: DATA OUT) */
<br>> > > #define CAM_DIR_NONE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x000000C0&nbsp;&nbsp;
/* Data direction (11: no data) */
<br>> > >
<br>> > > While UDI scsi spec has:
<br>> > > #define UDI_SCSI_DATA_IN&nbsp;&nbsp; (1U&lt;&lt;0)
<br>> > > #define UDI_SCSI_DATA_OUT (1U&lt;&lt;1)
<br>> > >
<br>> > > Basically, it can't be UNKNOWN because the Peripheral Driver
must specify the
<br>> > > buffer address and total transfer size. Any&nbsp; inconsistencies
should return error
<br>> > >
<br>> > > or let the host adaptor card simply return data overrun or data
underrun.
<br>> > >
<br>> > >
<br>> > > I found CAM_DIR_NONE is potential hazard because
<br>> > > if some one specify CAM_DIR_NONE, another person
<br>> > > may mistakenly check for:
<br>> > >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If (flags &amp;
CAM_DIR_OUT) ...../* condition true and do something wrong
<br>> > > */
<br>> >
<br>> > In FreeBSD/CAM, we added a mask:
<br>> >
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAM_DIR_RESV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
= 0x00000000,/* Data direction (00:reserved)&nbsp; */
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAM_DIR_IN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
= 0x00000040,/* Data direction (01:DATA IN)&nbsp;&nbsp; */
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAM_DIR_OUT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
= 0x00000080,/* Data direction (10:DATA OUT)&nbsp; */
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAM_DIR_NONE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
= 0x000000C0,/* Data direction (11:no data)&nbsp;&nbsp; */
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAM_DIR_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
= 0x000000C0,/* Data direction Mask&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*/
<br>> >
<br>> > So to determine the data direction:
<br>> >
<br>> > if ((flags &amp; CAM_DIR_MASK) == CAM_DIR_OUT)
<br>> >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
<br>>
<br>> I think CAM_DIR_MASK is a workaround for the original design flaw.
<br>>
<br>> Comparing to UDI, only two defines versus five defines in CAM.
<p>You may well suffer of a serious brain problem, my dear. There are 3
<br>needed values (IN/OUT/NONE). This requires 2 bits of data. If you want
to
<br>define enough values to deal with such a bit field you need a mask
and the
<br>4 possible values.
<p>> And one "&amp;" operation versus two operations (&amp;,==) in CAM.
<p>Do you mean that UDI is able to transfer data in both directions at
the
<br>same time when user provides both DATA_IN bit and DATA_OUT bit ?
<p>> Obviously, UDI is better at least here :-).
<p>Indeed, CAM is unable to read and write data at the same time on a single
<br>SCSI BUS. ;-)
<p>G&eacute;rard.
<p>-
<br>To unsubscribe from this list: send the line "unsubscribe linux-scsi"
in
<br>the body of a message to majordomo@vger.rutgers.edu</blockquote>

<pre>--&nbsp;
=============================
Tony Chung</pre>
&nbsp;</html>

--------------94C81D8C5394AA4620FEE520--


-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu

home help back first fref pref prev next nref lref last post