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 [EMAIL PROTECTED]
-- ============================= Tony Chung
