The original patch sent to me by Bernd. -Dave
Hi David, I found the other problem that kept the software from finding the camera... Sometimes it would try to send commands in the range 0xc0 to 0xcf --- with a CDBLen of 6. The ASPI code would dutifully pass 6 bytes into the kernel, where sg.c would look at the command and say "c0 --- oh well, that's command group 6, 10 bytes. Oops, too few bytes. Let's return EIO". Fortunately, there is a way to override the kernel's assumptions. I have attached a patch at the bottom of this mail. It puts the "maximum scsi targets" to 8 (that should probably be done dynamically, depending on what targets were found --- wouldn't want to discrimate against people with wide-SCSI), does the command length override (is there a cleaner way to get the header info?), and also replaces "strcat" with "strcpy" in SC_HA_INQUIRY (not much point relying on the caller clearing those fields if it isn't necessary). I hope that gets your stuff going a bit further, too. Bernie P.S.: Whenever I start the program, it still claims once that it cannot find the camera --- and no trace from the ASPI stuff at all. Only when I select "try again" will it work. Could this have something to do with the failure to load that you mentioned earlier? ======================== patch =============================== diff -r -U2 /newdisk/wine-20000614/dlls/winaspi/winaspi32.c /tmp/wine-20000614/dlls/winaspi/winaspi32.c --- /newdisk/wine-20000614/dlls/winaspi/winaspi32.c Wed Mar 29 06:23:02 2000 +++ /tmp/wine-20000614/dlls/winaspi/winaspi32.c Sat Jul 8 17:55:24 2000 @@ -35,4 +35,17 @@ #ifdef linux +#include <sys/ioctl.h> + +/* Why oh why isn't this somehow included from <scsi/sg.h> ???? */ +#define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given + number on the next write() on this file descriptor */ + +/* This is what the linux kernel thinks.... */ +static unsigned char scsi_command_size[8] = +{ + 6, 10, 10, 12, + 12, 12, 10, 10 +}; + static ASPI_DEVICE_INFO *ASPI_open_devices = NULL; static CRITICAL_SECTION ASPI_CritSection; @@ -364,4 +377,17 @@ } + { + int cmd=lpPRB->CDBByte[0]; + int ind=(cmd>>5)&7; + + if (lpPRB->SRB_CDBLen!=scsi_command_size[ind]) { + int arg; + + TRACE("CDBLen for command %d claims to be %d, expected %d\n",cmd, + lpPRB->SRB_CDBLen,scsi_command_size[ind]); + arg=lpPRB->SRB_CDBLen; /* How long things *really* are */ + ioctl(fd,SG_NEXT_CMD_LEN,&arg); + } + } if(!SCSI_LinuxDeviceIo( fd, sg_hd, in_len, @@ -469,8 +495,14 @@ lpSRB->inquiry.HA_Count = 1; /* not always */ lpSRB->inquiry.HA_SCSI_ID = 7; /* not always ID 7 */ +#if 0 strcat(lpSRB->inquiry.HA_ManagerId, "ASPI for WIN32"); /* max 15 chars, don't change */ strcat(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host adapter name */ +#else + strcpy(lpSRB->inquiry.HA_ManagerId, "ASPI for WIN32"); /* max 15 chars, don't +change */ + strcpy(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host adapter +name */ +#endif memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */ lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */ + lpSRB->inquiry.HA_Unique[3] = 0x08; /* Maximum number of SCSI targets */ FIXME("ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId); return SS_COMP;