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.
And one "&" operation versus two operations (&,==) in CAM.Obviously, UDI is better at least here :-).-- ============================= Tony Chung
