[sane-devel] Re: Sane on Ultra Sparc

abel deuring a.deuring@satzbau-gmbh.de
Sat, 11 Jan 2003 20:19:24 +0100

Dr. Ing. Dieter Jurzitza wrote:
> Hello Thomas,
> hello all,
> I think you've got me wrong. This define __SPARC_ARCH__ was only an
> *assumption* of mine. In fact, I am sure this define does *not* exist. Maybe I
> wasn't clear enough.

well, that was my fault -- dumb copy & paste ;)

> But according to Thomas's discovery one could say __sparc__ instead.
> The question that ought to be answered by Abel (?) is whether it makes sense to
> globally switch to the old interface for sparc for the sake of simplicity - I
> do not know how big is the performance impact of this.

Well, the impact is not _that_ big. The old interface stuffs three 
different arrays (SG header, SCSI command data block and the date to be 
written to the device) into one array, and passes this array in a write 
call to the kernel. This means an additional memcpy for each command, 
and a few malloc calls. On an old Sun IPX box with only a few MB RAM 
installed this additional memory usage might perhaps be an issue.

Another point is that the old interface underwent a number of changes. 
While these changes made a lot of sense, this contributed to the 
cluttered code in sanei_scsi.c. Some really old versions of the SG 
interface even could not give some additional information about errors 
in the Linux SCSI layer. If we get error reports, I really prefer the 
reports, where the the new interface was used -- in this case I am sure 
that I have useful details about the situation ;)

> Whoever maintains the code should decide about the best way to do this (Abel?),
> I would appreciate to send a patch to SuSE and so on to allow them to make
> things work in their distribution.

Hrrmmm. I am not very familiar with autoconf. Henning, could you do 
that? Thomas already suggested to check, what uname prints ('sparc' vs. 

> Nevertheless, there is my offer: if there is someone willing (having the time
> :-) to do so) to find out what is really going on (going wrong...) I am willing
> to test and to offer time for testing. This is all I can do for now.

Well, if you are a bit adventurous, you could try this:

- define a replacement of sg_io_hdr, which _might_ work:

typedef struct xsg_io_hdr
     int interface_id;           /* [i] 'S' for SCSI generic (required) */
     int dxfer_direction;        /* [i] data transfer direction  */
     unsigned char cmd_len;      /* [i] SCSI command length ( <= 16 
bytes) */
     unsigned char mx_sb_len;    /* [i] max length to write to sbp */
     unsigned short iovec_count; /* [i] 0 implies no scatter gather */
     unsigned int dxfer_len;     /* [i] byte count of data transfer */
     int pad1;
     void * dxferp;              /* [i], [*io] points to data transfer 
                                               or scatter gather list */
     int pad2;
     unsigned char * cmdp;       /* [i], [*i] points to command to 
perform */
     int pad3;
     unsigned char * sbp;        /* [i], [*o] points to sense_buffer 
memory */
     unsigned int timeout;       /* [i] MAX_UINT->no timeout (unit: 
millisec) */
     unsigned int flags;         /* [i] 0 -> default, see SG_FLAG... */
     int pack_id;                /* [i->o] unused internally (normally) */
     int pad4;
     void * usr_ptr;             /* [i->o] unused internally */
     unsigned char status;       /* [o] scsi status */
     unsigned char masked_status;/* [o] shifted, masked scsi status */
     unsigned char msg_status;   /* [o] messaging level data (optional) */
     unsigned char sb_len_wr;    /* [o] byte count actually written to 
sbp */
     unsigned short host_status; /* [o] errors from host adapter */
     unsigned short driver_status;/* [o] errors from software driver */
     int resid;                  /* [o] dxfer_len - actual_transferred */
     unsigned int duration;      /* [o] time taken by cmd (unit: 
millisec) */
     unsigned int info;          /* [o] auxiliary information */
} xsg_io_hdr_t;

(a simple "copy" of struct sg_io_hdr as defined in sg.h, but with 
"padding ints" before each pointer declaration. I even don't know, if 
the SParc processor use big or low endian pointer/integers, so it might 
be necessary to move the "padding ints" after the pointer declarations. 
I conclude from the fact that the old SG interface works, that 
sizeof(int)==4, even for 64 bit programs; if this is wrong, the int 
definition in the struct would need padding too)

- replace all occurrences of Sg_io_hdr and sg_io_hdr in sanei with 

If the kernel function __copy_from_user and __copy_to_user can deal with 
these fake 64 bit pointers, the SG3 interface might work too. But before 
I put this stuff into CVS repository, I'd like to hear a few comments, 
especially from other people, especially from those folks, who know a 
bot more about kernel internals ;)

> I am asking whether there is anywhere a declaration within the gcc-header files
> (or some kernel call, or whatsoever ...) that could be used as above for Ultra
> only. I personally do not know - but maybe someone on the list does.
> Maybe one could check that in the configure script - do not ask me to do
> this, configure is something quite strange for me.
> So to conclude:
> 1.) the short term solution is at hand, looking forward to the new
> AMD processors right in front of the door and the 64bit linux on the horizon
> this issue should be expected to come up once again. If someone wants to try a
> little harder, come back to me - I'll test.

That's what I thought too ;)

> 2.) let me know how to include into the code - I mean I can do right now, but I
> would prefer to be compliant with the solution you are heading for - just for
> readability and maintainability.

I the short term we should use some autoconf "magic" to #undef SG_IO for 
  64 bit Sparcs, and perhaps for other architectures which mix 32 apps 
with a 64 bit kernel. The redefinitions of strcut sg_io_hdr looks a bit 
too hairy to me ;) At least I'd like to have a somewhat longer test phase...