summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/linux/opcmciasystem.cpp
Unidiff
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
@@ -36,34 +36,63 @@ using namespace Opie::Core;
36/* QT */ 36/* QT */
37#include <qfile.h> 37#include <qfile.h>
38#include <qtextstream.h> 38#include <qtextstream.h>
39 39
40/* STD */ 40/* STD */
41#include <errno.h> 41#include <errno.h>
42#include <fcntl.h> 42#include <fcntl.h>
43#include <string.h> 43#include <string.h>
44#include <stdlib.h> 44#include <stdlib.h>
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
51 *======================================================================================*/ 54 *======================================================================================*/
52 55
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
61void OPcmciaSystem::synchronize() 90void OPcmciaSystem::synchronize()
62{ 91{
63 qDebug( "OPcmciaSystem::synchronize()" ); 92 qDebug( "OPcmciaSystem::synchronize()" );
64 _interfaces.clear(); 93 _interfaces.clear();
65 94
66 //FIXME: Use cardmgr subsystem ioctls 95 //FIXME: Use cardmgr subsystem ioctls
67 96
68 QString fileName; 97 QString fileName;
69 if ( QFile::exists( "/var/run/stab" ) ) { fileName = "/var/run/stab"; } 98 if ( QFile::exists( "/var/run/stab" ) ) { fileName = "/var/run/stab"; }
@@ -78,25 +107,25 @@ void OPcmciaSystem::synchronize()
78 QTextStream cardinfo( &cardinfofile ); 107 QTextStream cardinfo( &cardinfofile );
79 while ( !cardinfo.atEnd() ) 108 while ( !cardinfo.atEnd() )
80 { 109 {
81 QString strSocket; 110 QString strSocket;
82 int numSocket; 111 int numSocket;
83 char colon; 112 char colon;
84 QString cardName; 113 QString cardName;
85 cardinfo >> strSocket >> numSocket >> colon; 114 cardinfo >> strSocket >> numSocket >> colon;
86 cardName = cardinfo.readLine().stripWhiteSpace(); 115 cardName = cardinfo.readLine().stripWhiteSpace();
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 {
94 continue; 123 continue;
95 } 124 }
96 } 125 }
97} 126}
98 127
99 128
100int OPcmciaSystem::count() const 129int OPcmciaSystem::count() const
101{ 130{
102 return _interfaces.count(); 131 return _interfaces.count();
@@ -130,41 +159,133 @@ OPcmciaSystem* OPcmciaSystem::instance()
130 159
131 160
132OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const 161OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const
133{ 162{
134 return OPcmciaSystem::CardIterator( _interfaces ); 163 return OPcmciaSystem::CardIterator( _interfaces );
135} 164}
136 165
137 166
138/*====================================================================================== 167/*======================================================================================
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 */
157} 241}
158 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;
260 }
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 );
162 ::system( (const char*) cmdline ); 283 ::system( (const char*) cmdline );
163} 284}
164 285
165int OPcmciaSocket::number() const 286int OPcmciaSocket::number() const
166{ 287{
167 return _socket; 288 return _socket;
168} 289}
169 290
170 291
@@ -207,12 +328,25 @@ bool OPcmciaSocket::suspend()
207 return command( "suspend" ); 328 return command( "suspend" );
208} 329}
209 330
210bool OPcmciaSocket::resume() 331bool OPcmciaSocket::resume()
211{ 332{
212 return command( "resume"); 333 return command( "resume");
213} 334}
214 335
215bool OPcmciaSocket::reset() 336bool 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