summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/linux/opcmciasystem.cpp
Side-by-side diff
Diffstat (limited to 'libopie2/opiecore/linux/opcmciasystem.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/linux/opcmciasystem.cpp142
1 files changed, 138 insertions, 4 deletions
diff --git a/libopie2/opiecore/linux/opcmciasystem.cpp b/libopie2/opiecore/linux/opcmciasystem.cpp
index c310b85..7bd7178 100644
--- a/libopie2/opiecore/linux/opcmciasystem.cpp
+++ b/libopie2/opiecore/linux/opcmciasystem.cpp
@@ -45,6 +45,9 @@ using namespace Opie::Core;
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
+
+#define PROC_DEVICES "/proc/devices"
/*======================================================================================
* OPcmciaSystem
@@ -53,8 +56,34 @@ using namespace Opie::Core;
OPcmciaSystem* OPcmciaSystem::_instance = 0;
OPcmciaSystem::OPcmciaSystem()
+ :_major( 0 )
{
qDebug( "OPcmciaSystem::OPcmciaSystem()" );
+
+ // get major node number out of /proc/devices
+ QFile procfile( PROC_DEVICES );
+ if ( procfile.exists() && procfile.open( IO_ReadOnly ) )
+ {
+ QTextStream devstream( &procfile );
+ devstream.readLine(); // skip header
+ while ( !devstream.atEnd() && !_major )
+ {
+ int nodenumber;
+ QString driver;
+ devstream >> nodenumber >> driver;
+ if ( driver == "pcmcia" )
+ {
+ qDebug( "OPcmciaSystem::OPcmciaSystem(): gotcha! pcmcia node number = %d", nodenumber );
+ _major = nodenumber;
+ break;
+ }
+ }
+ }
+ else
+ {
+ qWarning( "OPcmciaSystem::OPcmciaSystem() - can't open /proc/devices - continuing with limited functionality." );
+ }
+
synchronize();
}
@@ -87,7 +116,7 @@ void OPcmciaSystem::synchronize()
qDebug( "strSocket = '%s', numSocket = '%d', colon = '%c', cardName = '%s'", (const char*) strSocket, numSocket, colon, ( const char*) cardName );
if ( strSocket == "Socket" && colon == ':' )
{
- _interfaces.append( new OPcmciaSocket( numSocket, this, (const char*) cardName ) );
+ _interfaces.append( new OPcmciaSocket( _major, numSocket, this, (const char*) cardName ) );
}
else
{
@@ -139,23 +168,115 @@ OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const
* OPcmciaSocket
*======================================================================================*/
-OPcmciaSocket::OPcmciaSocket( int socket, QObject* parent, const char* name )
- :QObject( parent, name ), _socket( socket )
+OPcmciaSocket::OPcmciaSocket( int major, int socket, QObject* parent, const char* name )
+ :QObject( parent, name ), _major( major ), _socket( socket )
{
- odebug << "OPcmciaSocket::OPcmciaSocket()" << oendl;
+ qDebug( "OPcmciaSocket::OPcmciaSocket()" );
+
init();
+ buildInformation();
}
OPcmciaSocket::~OPcmciaSocket()
{
+ qDebug( "OPcmciaSocket::~OPcmciaSocket()" );
+ cleanup();
}
/* internal */ void OPcmciaSocket::init()
{
+ // open control socket and gather file descriptor
+ if ( _major )
+ {
+ dev_t dev = ::makedev( _major, _socket );
+ QString filename = QString().sprintf( "/tmp/opcmciasystem-%d", ::getpid() );
+ if ( ::mknod( (const char*) filename, ( S_IFCHR|S_IREAD|S_IWRITE ), dev ) == 0 )
+ {
+ _fd = ::open( (const char*) filename, O_RDONLY);
+ if ( !_fd )
+ {
+ qWarning( "OPcmciaSocket::init() - can't open control socket (%s)", strerror( errno ) );
+ }
+ else
+ {
+ ::unlink( (const char*) filename );
+ }
+ }
+ else
+ {
+ qWarning( "OPcmciaSocket::init() - can't create device node (%s)", strerror( errno ) );
+ }
+ }
+}
+
+/* internal */ void OPcmciaSocket::buildInformation()
+{
+ cistpl_vers_1_t *vers = &_ioctlarg.tuple_parse.parse.version_1;
+ cistpl_manfid_t *manfid = &_ioctlarg.tuple_parse.parse.manfid;
+ cistpl_funcid_t *funcid = &_ioctlarg.tuple_parse.parse.funcid;
+ config_info_t config;
+
+ if ( getTuple( CISTPL_VERS_1 ) )
+ {
+ for ( int i = 0; i < CISTPL_VERS_1_MAX_PROD_STRINGS; ++i )
+ {
+ qDebug( " PRODID = '%s'", vers->str+vers->ofs[i] );
+ _productId += vers->str+vers->ofs[i];
+ }
+ }
+ /*
+ for (i = 0; i < 4; i++)
+ printf("PRODID_%d=\"%s\"\n", i+1,
+ (i < vers->ns) ? vers->str+vers->ofs[i] : "");
+ *manfid = (cistpl_manfid_t) { 0, 0 };
+ get_tuple(fd, CISTPL_MANFID, &arg);
+ printf("MANFID=%04x,%04x\n", manfid->manf, manfid->card);
+ *funcid = (cistpl_funcid_t) { 0xff, 0xff };
+ get_tuple(fd, CISTPL_FUNCID, &arg);
+ printf("FUNCID=%d\n", funcid->func);
+ config.Function = config.ConfigBase = 0;
+ */
}
+/* internal */ void OPcmciaSocket::cleanup()
+{
+ // close control socket
+}
+
+/* internal */ bool OPcmciaSocket::getTuple( cisdata_t tuple )
+{
+ _ioctlarg.tuple.DesiredTuple = tuple;
+ _ioctlarg.tuple.Attributes = TUPLE_RETURN_COMMON;
+ _ioctlarg.tuple.TupleOffset = 0;
+
+ int result;
+ result = ::ioctl(_fd, DS_GET_FIRST_TUPLE, &_ioctlarg);
+ if ( result != 0 )
+ {
+ qWarning( "OPcmciaSocket::getTuple() - DS_GET_FIRST_TUPLE failed (%s)", strerror( errno ) );
+ return false;
+ }
+
+ result = ::ioctl(_fd, DS_GET_TUPLE_DATA, &_ioctlarg);
+ if ( result != 0 )
+ {
+ qWarning( "OPcmciaSocket::getTuple() - DS_GET_TUPLE_DATA failed (%s)", strerror( errno ) );
+ return false;
+ }
+
+ result = ::ioctl(_fd, DS_PARSE_TUPLE, &_ioctlarg);
+ if ( result != 0 )
+ {
+ qWarning( "OPcmciaSocket::getTuple() - DS_PARSE_TUPLE failed (%s)", strerror( errno ) );
+ return false;
+ }
+
+ return true;
+}
+
+
/* internal */ bool OPcmciaSocket::command( const QString& cmd )
{
QString cmdline = QString().sprintf( "cardctl %s %d &", (const char*) cmd, _socket );
@@ -216,3 +337,16 @@ bool OPcmciaSocket::reset()
{
return command( "reset");
}
+
+const QStringList& OPcmciaSocket::productIdentity() const
+{
+ return _productId;
+}
+
+#if 0
+const QPair& OPcmciaSocket::manufacturerIdentity() const
+{
+ return _manufId;
+}
+#endif
+