Here is a patch that has been sitting in my tree for quite a long time. I can't exactly remember where I left off with it, but I *THINK* I had it working properly in theory (IIRC). If someone with a SCSI card with multiple channels could please test this it would be greatly appreciated. -Dave
Index: dlls/winaspi/aspi.c =================================================================== RCS file: /home/wine/wine/dlls/winaspi/aspi.c,v retrieving revision 1.3 diff -u -r1.3 aspi.c --- dlls/winaspi/aspi.c 2000/03/19 12:42:31 1.3 +++ dlls/winaspi/aspi.c 2000/06/05 07:21:02 @@ -43,18 +43,24 @@ static void SCSI_GetProcinfo(); +static void +SCSI_MapHCtoController(); + /* Exported functions */ void SCSI_Init() { /* For now we just call SCSI_GetProcinfo */ SCSI_GetProcinfo(); + SCSI_MapHCtoController(); } int ASPI_GetNumControllers() { HKEY hkeyScsi; + HKEY hkeyControllerMap; + DWORD error; DWORD type = REG_DWORD; DWORD num_ha = 0; DWORD cbData = sizeof(num_ha); @@ -65,13 +71,20 @@ return 0; } - if( RegQueryValueExA(hkeyScsi, NULL, NULL, &type, (LPBYTE)&num_ha, &cbData ) != ERROR_SUCCESS ) + if( (error=RegOpenKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, +KEY_ALL_ACCESS, &hkeyControllerMap )) != ERROR_SUCCESS ) { + ERR("Could not open HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP); + RegCloseKey(hkeyScsi); + SetLastError(error); + return 0; + } + if( RegQueryValueExA(hkeyControllerMap, NULL, NULL, &type, (LPBYTE)&num_ha, +&cbData ) != ERROR_SUCCESS ) + { ERR("Could not query value HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); num_ha=0; } + RegCloseKey(hkeyControllerMap); RegCloseKey(hkeyScsi); - FIXME("Please fix to return number of controllers\n"); TRACE("Returning %ld host adapters\n", num_ha ); return num_ha; } @@ -113,10 +126,51 @@ DWORD ASPI_GetHCforController( int controller ) { - DWORD retval; + DWORD hc = 0xFFFFFFFF; + char cstr[20]; + DWORD error; + HKEY hkeyScsi; + HKEY hkeyControllerMap; + DWORD type = REG_DWORD; + DWORD cbData = sizeof(DWORD); + DWORD disposition; +#if 0 FIXME("Please fix to map each channel of each host adapter to the proper ASPI controller number!\n"); - retval = (controller << 16); - return retval; + hc = (controller << 16); + return hc; +#endif + if( (error=RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, +REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition )) != +ERROR_SUCCESS ) + { + ERR("Could not open HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + SetLastError(error); + return hc; + } + if( disposition != REG_OPENED_EXISTING_KEY ) + { + WARN("Created HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI); + } + if( (error=RegCreateKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, NULL, +REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyControllerMap, &disposition )) != +ERROR_SUCCESS ) + { + ERR("Could not open HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP); + RegCloseKey(hkeyScsi); + SetLastError(error); + return hc; + } + if( disposition != REG_OPENED_EXISTING_KEY ) + { + WARN("Created HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP); + } + + sprintf(cstr, "c%02d", controller); + if( (error=RegQueryValueExA( hkeyControllerMap, cstr, 0, &type, (LPBYTE)&hc, +&cbData)) != ERROR_SUCCESS ) + { + ERR("Could not open HKEY_DYN_DATA\\%s\\%s\\%s, error=%lx\n", +KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP, cstr, error ); + SetLastError( error ); + } + RegCloseKey(hkeyControllerMap); + RegCloseKey(hkeyScsi); + return hc; + }; int @@ -268,6 +322,94 @@ TRACE( " Type: %s ANSI SCSI revision: %02d\n", dev->type, dev->ansirev ); +} + +static BOOL +SCSI_PutRegControllerMap( HKEY hkeyControllerMap, int num_controller, int ha, int +chan) +{ + DWORD error; + char cstr[20]; + DWORD hc; + hc = (ha << 16) + chan; + sprintf(cstr, "c%02d", num_controller); + if( (error=RegSetValueExA( hkeyControllerMap, cstr, 0, REG_DWORD, (LPBYTE)&hc, +sizeof(DWORD))) != ERROR_SUCCESS ) + { + ERR("Could not create HKEY_DYN_DATA\\%s\\%s\\%s\n", KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP, cstr ); + } + return error; +} + +static void +SCSI_MapHCtoController() +{ + HKEY hkeyScsi; + HKEY hkeyControllerMap; + DWORD disposition; + + char idstr[20]; + DWORD cbIdStr = 20; + int i = 0; + DWORD type = 0; + DWORD error; + + DWORD num_controller = 0; + int last_ha = -1; + int last_chan = -1; + + int ha = 0; + int chan = 0; + + if( RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, REG_OPTION_VOLATILE, +KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition ) != ERROR_SUCCESS ) + { + ERR("Could not open HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + return; + } + if( disposition != REG_OPENED_EXISTING_KEY ) + { + WARN("Created HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI); + } + if( RegCreateKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, NULL, +REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyControllerMap, &disposition ) != +ERROR_SUCCESS ) + { + ERR("Could not create HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP); + RegCloseKey(hkeyScsi); + return; + } + + for( i=0; (error=RegEnumValueA( hkeyScsi, i, idstr, &cbIdStr, NULL, &type, +NULL, NULL )) == ERROR_SUCCESS; i++ ) + { + sscanf(idstr, "h%02dc%02dt%*02dd%*02d", &ha, &chan); + if( last_ha < ha ) + { /* Next HA */ + last_ha = ha; + last_chan = chan; + SCSI_PutRegControllerMap( hkeyControllerMap, num_controller, +ha, chan); + num_controller++; + } + else if( last_ha > ha ) + { + FIXME("Expected registry to be sorted\n"); + } + /* last_ha == ha */ + else if( last_chan < chan ) + { + last_chan = chan; + SCSI_PutRegControllerMap( hkeyControllerMap, num_controller, +ha, chan); + num_controller++; + } + else if( last_chan > chan ) + { + FIXME("Expected registry to be sorted\n"); + } + /* else last_ha == ha && last_chan == chan so do nothing */ + } + /* Set (default) value to number of controllers */ + if( RegSetValueExA(hkeyControllerMap, NULL, 0, REG_DWORD, +(LPBYTE)&num_controller, sizeof(DWORD) ) != ERROR_SUCCESS ) + { + ERR("Could not set value HEKY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, +KEYNAME_SCSI_CONTROLLERMAP); + } + RegCloseKey(hkeyControllerMap); + RegCloseKey(hkeyScsi); + return; } #endif Index: dlls/winaspi/winescsi.h =================================================================== RCS file: /home/wine/wine/dlls/winaspi/winescsi.h,v retrieving revision 1.2 diff -u -r1.2 winescsi.h --- dlls/winaspi/winescsi.h 2000/03/12 20:19:23 1.2 +++ dlls/winaspi/winescsi.h 2000/06/05 07:21:02 @@ -33,6 +33,7 @@ /* RegKey used for SCSI info under HKEY_DYN_DATA */ #define KEYNAME_SCSI "WineScsi" +#define KEYNAME_SCSI_CONTROLLERMAP "ControllerMap" /* Function prototypes from dlls/wnaspi32/aspi.c */ void