From 2180de1cac54afa7c8a97b723af334169b2d7285 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 29 Apr 2004 04:12:56 +0000 Subject: [PATCH] update memory cards for 2.6 kernel --- .../src/arch/MemoryCard/MemoryCardDriver.h | 6 +- .../MemoryCardDriverThreaded_Linux.cpp | 156 +++++++++++++++--- 2 files changed, 141 insertions(+), 21 deletions(-) diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriver.h b/stepmania/src/arch/MemoryCard/MemoryCardDriver.h index e824aee962..a3d2c8d5c8 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriver.h +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriver.h @@ -11,7 +11,8 @@ struct UsbStorageDevice iBus = -1; iPort = -1; iLevel = -1; - iUsbStorageIndex = -1; + iScsiIndex = -1; + sScsiDevice = ""; sSerial = ""; sOsMountDir = ""; }; @@ -19,7 +20,8 @@ struct UsbStorageDevice int iPort; int iLevel; CString sSerial; - int iUsbStorageIndex; + int iScsiIndex; + CString sScsiDevice; CString sOsMountDir; // WITHOUT trailing slash CString sName; // Name in the profile on the memory card. // This is passed here because it's read in the mounting thread. diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp index 56ce333ee2..f6732e3581 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp @@ -12,8 +12,10 @@ #include #include #include - #include +#include +#include +#include const CString TEMP_MOUNT_POINT = "@mctemp/"; @@ -22,6 +24,68 @@ static const char *ETC_MTAB = "/etc/mtab"; void GetNewStorageDevices( vector& vDevicesOut ); +static int RunProgram( const char *path, char *const args[], CString &out ) +{ + int fds[2]; + if( pipe(fds) == -1 ) + return -1; + + int pid = fork(); + if( pid == -1 ) + { + close( fds[0] ); + close( fds[1] ); + return -1; + } + + if( pid == 0 ) + { + close( fds[0] ); + close( fileno(stdout) ); + + dup2( fds[1], fileno(stdout) ); + + for( int i = 0; i < 1024; ++i ) + if( i != fileno(stdout) ) + close( i ); + execvp( path, args ); + _exit(1); + } + + close( fds[1] ); + + while( 1 ) + { + char buf[1024]; + int got = read( fds[0], buf, sizeof(buf) ); + if( got == -1 ) + { + if( errno == EINTR ) + continue; + fprintf( stderr, "err %s\n", strerror(errno) ); + exit(0); + } + + if( got == 0 ) + break; + + out.append( buf, got ); + } + + close( fds[0] ); + int status; + int ret = waitpid( pid, &status, 0 ); + + if( ret == -1 ) + return -1; + + if( !WIFEXITED(status) ) + return -1; /* signal */ + + return WEXITSTATUS(status); +} + + template bool VectorsAreEqual( const T &a, const T &b ) { @@ -254,8 +318,8 @@ void GetNewStorageDevices( vector& vDevicesOut ) if( iClass == 8 ) // storage class { vDevicesOut.push_back( usbd ); - LOG->Trace( "iUsbStorageIndex: %d, iBus: %d, iLevel: %d, iPort: %d", - usbd.iUsbStorageIndex, usbd.iBus, usbd.iLevel, usbd.iPort ); + LOG->Trace( "iScsiIndex: %d, iBus: %d, iLevel: %d, iPort: %d", + usbd.iScsiIndex, usbd.iBus, usbd.iLevel, usbd.iPort ); } continue; // stop processing this line } @@ -264,8 +328,17 @@ void GetNewStorageDevices( vector& vDevicesOut ) { // Find the usb-storage device index for all storage class devices. - for( unsigned i=0; true; i++ ) - { + const CString sDir = "/proc/scsi/usb-storage/"; + DIR *dirp = opendir( sDir ); + struct dirent *direntp; + while ( (direntp = readdir( dirp )) != NULL ) + { + if( stricmp(direntp->d_name,".")==0 || stricmp(direntp->d_name,"..")==0 ) + continue; + + int iScsiIndex = atoi( direntp->d_name ); + CString fn = sDir + direntp->d_name; + // Read the usb-storage descriptor. It looks like: // Host scsi0: usb-storage @@ -277,8 +350,7 @@ void GetNewStorageDevices( vector& vDevicesOut ) // GUID: 04e801000001125198948886 // Attached: Yes - CString fn = ssprintf( "/proc/scsi/usb-storage-%d/%d", i, i ); - ifstream f; + ifstream f; f.open(fn); if( !f.is_open() ) break; @@ -298,9 +370,9 @@ void GetNewStorageDevices( vector& vDevicesOut ) if( usbd.sSerial == szSerial ) { - usbd.iUsbStorageIndex = i; - LOG->Trace( "iUsbStorageIndex: %d, iBus: %d, iLevel: %d, iPort: %d, sSerial: %s", - usbd.iUsbStorageIndex, usbd.iBus, usbd.iLevel, usbd.iPort, usbd.sSerial.c_str() ); + usbd.iScsiIndex = iScsiIndex; + LOG->Trace( "iScsiIndex: %d, iBus: %d, iLevel: %d, iPort: %d, sSerial: %s", + usbd.iScsiIndex, usbd.iBus, usbd.iLevel, usbd.iPort, usbd.sSerial.c_str() ); break; // done looking for the corresponding device. } } @@ -308,8 +380,54 @@ void GetNewStorageDevices( vector& vDevicesOut ) } } } + + closedir( dirp ); } + { + // Get the mapping from Scsi device number to Scsi file device. Requires "sg-utils". + // sg_scan. It looks like: + + // /dev/sg0: scsi47 channel=0 id=0 lun=0 [em] type=0 + // /dev/sg1: scsi46 channel=0 id=0 lun=0 [em] type=0 + + CString sOutput; + RunProgram( "/usr/bin/sg_scan", NULL, sOutput ); + + CStringArray vsLines; + split( sOutput, "\n", vsLines ); + + for( unsigned i=0; iTrace( "sLine: %s", sLine.c_str() ); + + int iSg; + int iScsiIndex; + int iRet = sscanf( sLine.c_str(), "/dev/sg%i: scsi%d", &iSg, &iScsiIndex ); + if( iRet != 2 ) + continue; // don't process this line + + // search for the usb-storage device corresponding to the SCSI device + for( unsigned i=0; iTrace( "iScsiIndex: %d, iBus: %d, iLevel: %d, iPort: %d, sScsiDevice: %s", + usbd.iScsiIndex, usbd.iBus, usbd.iLevel, usbd.iPort, usbd.sScsiDevice.c_str() ); + break; // stop looking for a match + } + } + } + } + done_mapping: + int blah = 0; // hack around "label must be followed by statement" + + { // Find where each device is mounted. Output looks like: @@ -336,14 +454,13 @@ void GetNewStorageDevices( vector& vDevicesOut ) return; } - // /dev/sda1 /mnt/flash1 auto noauto,owner 0 0 - char cScsiDev; + char szScsiDevice[1024]; char szMountPoint[1024]; - int iRet = sscanf( sLine.c_str(), "/dev/sd%c1 %s", &cScsiDev, szMountPoint ); + int iRet = sscanf( sLine, "%s %s", szScsiDevice, szMountPoint ); if( iRet != 2 ) continue; // don't process this line - int iUsbStorageIndex = cScsiDev - 'a'; + CString sMountPoint = szMountPoint; TrimLeft( sMountPoint ); TrimRight( sMountPoint ); @@ -352,12 +469,12 @@ void GetNewStorageDevices( vector& vDevicesOut ) for( unsigned i=0; iTrace( "iUsbStorageIndex: %d, iBus: %d, iLevel: %d, iPort: %d, sOsMountDir: %s", - usbd.iUsbStorageIndex, usbd.iBus, usbd.iLevel, usbd.iPort, usbd.sOsMountDir.c_str() ); + LOG->Trace( "iScsiIndex: %d, sScsiDevice: %s, iBus: %d, iLevel: %d, iPort: %d, sOsMountDir: %s", + usbd.iScsiIndex, usbd.sScsiDevice.c_str(), usbd.iBus, usbd.iLevel, usbd.iPort, usbd.sOsMountDir.c_str() ); break; // stop looking for a match } @@ -421,8 +538,9 @@ void MemoryCardDriverThreaded_Linux::Flush( UsbStorageDevice* pDevice ) void MemoryCardDriverThreaded_Linux::ResetUsbStorage() { - ExecuteCommand( "rmmod usb-storage" ); - ExecuteCommand( "modprobe usb-storage" ); + // This isn't necessary in 2.6 because SCSI file devices are recycled. + // ExecuteCommand( "rmmod usb-storage" ); + // ExecuteCommand( "modprobe usb-storage" ); }