summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/linux/opcmciasystem.cpp
Unidiff
Diffstat (limited to 'libopie2/opiecore/linux/opcmciasystem.cpp') (more/less context) (show 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;
45#include <sys/ioctl.h> 45#include <sys/ioctl.h>
46#include <sys/types.h> 46#include <sys/types.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <unistd.h>
49
50#define PROC_DEVICES "/proc/devices"
48 51
49/*====================================================================================== 52/*======================================================================================
50 * OPcmciaSystem 53 * OPcmciaSystem
@@ -53,8 +56,34 @@ using namespace Opie::Core;
53OPcmciaSystem* OPcmciaSystem::_instance = 0; 56OPcmciaSystem* OPcmciaSystem::_instance = 0;
54 57
55OPcmciaSystem::OPcmciaSystem() 58OPcmciaSystem::OPcmciaSystem()
59 :_major( 0 )
56{ 60{
57 qDebug( "OPcmciaSystem::OPcmciaSystem()" ); 61 qDebug( "OPcmciaSystem::OPcmciaSystem()" );
62
63 // get major node number out of /proc/devices
64 QFile procfile( PROC_DEVICES );
65 if ( procfile.exists() && procfile.open( IO_ReadOnly ) )
66 {
67 QTextStream devstream( &procfile );
68 devstream.readLine(); // skip header
69 while ( !devstream.atEnd() && !_major )
70 {
71 int nodenumber;
72 QString driver;
73 devstream >> nodenumber >> driver;
74 if ( driver == "pcmcia" )
75 {
76 qDebug( "OPcmciaSystem::OPcmciaSystem(): gotcha! pcmcia node number = %d", nodenumber );
77 _major = nodenumber;
78 break;
79 }
80 }
81 }
82 else
83 {
84 qWarning( "OPcmciaSystem::OPcmciaSystem() - can't open /proc/devices - continuing with limited functionality." );
85 }
86
58 synchronize(); 87 synchronize();
59} 88}
60 89
@@ -87,7 +116,7 @@ void OPcmciaSystem::synchronize()
87 qDebug( "strSocket = '%s', numSocket = '%d', colon = '%c', cardName = '%s'", (const char*) strSocket, numSocket, colon, ( const char*) cardName ); 116 qDebug( "strSocket = '%s', numSocket = '%d', colon = '%c', cardName = '%s'", (const char*) strSocket, numSocket, colon, ( const char*) cardName );
88 if ( strSocket == "Socket" && colon == ':' ) 117 if ( strSocket == "Socket" && colon == ':' )
89 { 118 {
90 _interfaces.append( new OPcmciaSocket( numSocket, this, (const char*) cardName ) ); 119 _interfaces.append( new OPcmciaSocket( _major, numSocket, this, (const char*) cardName ) );
91 } 120 }
92 else 121 else
93 { 122 {
@@ -139,23 +168,115 @@ OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const
139 * OPcmciaSocket 168 * OPcmciaSocket
140 *======================================================================================*/ 169 *======================================================================================*/
141 170
142OPcmciaSocket::OPcmciaSocket( int socket, QObject* parent, const char* name ) 171OPcmciaSocket::OPcmciaSocket( int major, int socket, QObject* parent, const char* name )
143 :QObject( parent, name ), _socket( socket ) 172 :QObject( parent, name ), _major( major ), _socket( socket )
144{ 173{
145 odebug << "OPcmciaSocket::OPcmciaSocket()" << oendl; 174 qDebug( "OPcmciaSocket::OPcmciaSocket()" );
175
146 init(); 176 init();
177 buildInformation();
147} 178}
148 179
149 180
150OPcmciaSocket::~OPcmciaSocket() 181OPcmciaSocket::~OPcmciaSocket()
151{ 182{
183 qDebug( "OPcmciaSocket::~OPcmciaSocket()" );
184 cleanup();
152} 185}
153 186
154 187
155/* internal */ void OPcmciaSocket::init() 188/* internal */ void OPcmciaSocket::init()
156{ 189{
190 // open control socket and gather file descriptor
191 if ( _major )
192 {
193 dev_t dev = ::makedev( _major, _socket );
194 QString filename = QString().sprintf( "/tmp/opcmciasystem-%d", ::getpid() );
195 if ( ::mknod( (const char*) filename, ( S_IFCHR|S_IREAD|S_IWRITE ), dev ) == 0 )
196 {
197 _fd = ::open( (const char*) filename, O_RDONLY);
198 if ( !_fd )
199 {
200 qWarning( "OPcmciaSocket::init() - can't open control socket (%s)", strerror( errno ) );
201 }
202 else
203 {
204 ::unlink( (const char*) filename );
205 }
206 }
207 else
208 {
209 qWarning( "OPcmciaSocket::init() - can't create device node (%s)", strerror( errno ) );
210 }
211 }
212}
213
214/* internal */ void OPcmciaSocket::buildInformation()
215{
216 cistpl_vers_1_t *vers = &_ioctlarg.tuple_parse.parse.version_1;
217 cistpl_manfid_t *manfid = &_ioctlarg.tuple_parse.parse.manfid;
218 cistpl_funcid_t *funcid = &_ioctlarg.tuple_parse.parse.funcid;
219 config_info_t config;
220
221 if ( getTuple( CISTPL_VERS_1 ) )
222 {
223 for ( int i = 0; i < CISTPL_VERS_1_MAX_PROD_STRINGS; ++i )
224 {
225 qDebug( " PRODID = '%s'", vers->str+vers->ofs[i] );
226 _productId += vers->str+vers->ofs[i];
227 }
228 }
229 /*
230 for (i = 0; i < 4; i++)
231 printf("PRODID_%d=\"%s\"\n", i+1,
232 (i < vers->ns) ? vers->str+vers->ofs[i] : "");
233 *manfid = (cistpl_manfid_t) { 0, 0 };
234 get_tuple(fd, CISTPL_MANFID, &arg);
235 printf("MANFID=%04x,%04x\n", manfid->manf, manfid->card);
236 *funcid = (cistpl_funcid_t) { 0xff, 0xff };
237 get_tuple(fd, CISTPL_FUNCID, &arg);
238 printf("FUNCID=%d\n", funcid->func);
239 config.Function = config.ConfigBase = 0;
240 */
241}
242
243/* internal */ void OPcmciaSocket::cleanup()
244{
245 // close control socket
246}
247
248/* internal */ bool OPcmciaSocket::getTuple( cisdata_t tuple )
249{
250 _ioctlarg.tuple.DesiredTuple = tuple;
251 _ioctlarg.tuple.Attributes = TUPLE_RETURN_COMMON;
252 _ioctlarg.tuple.TupleOffset = 0;
253
254 int result;
255 result = ::ioctl(_fd, DS_GET_FIRST_TUPLE, &_ioctlarg);
256 if ( result != 0 )
257 {
258 qWarning( "OPcmciaSocket::getTuple() - DS_GET_FIRST_TUPLE failed (%s)", strerror( errno ) );
259 return false;
157} 260}
158 261
262 result = ::ioctl(_fd, DS_GET_TUPLE_DATA, &_ioctlarg);
263 if ( result != 0 )
264 {
265 qWarning( "OPcmciaSocket::getTuple() - DS_GET_TUPLE_DATA failed (%s)", strerror( errno ) );
266 return false;
267 }
268
269 result = ::ioctl(_fd, DS_PARSE_TUPLE, &_ioctlarg);
270 if ( result != 0 )
271 {
272 qWarning( "OPcmciaSocket::getTuple() - DS_PARSE_TUPLE failed (%s)", strerror( errno ) );
273 return false;
274 }
275
276 return true;
277}
278
279
159/* internal */ bool OPcmciaSocket::command( const QString& cmd ) 280/* internal */ bool OPcmciaSocket::command( const QString& cmd )
160{ 281{
161 QString cmdline = QString().sprintf( "cardctl %s %d &", (const char*) cmd, _socket ); 282 QString cmdline = QString().sprintf( "cardctl %s %d &", (const char*) cmd, _socket );
@@ -216,3 +337,16 @@ bool OPcmciaSocket::reset()
216{ 337{
217 return command( "reset"); 338 return command( "reset");
218} 339}
340
341const QStringList& OPcmciaSocket::productIdentity() const
342{
343 return _productId;
344}
345
346#if 0
347const QPair& OPcmciaSocket::manufacturerIdentity() const
348{
349 return _manufId;
350}
351#endif
352