summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-05-31 14:34:02 (UTC)
committer mickeyl <mickeyl>2005-05-31 14:34:02 (UTC)
commit6d2273fb22e10474ae26dd249fa2836e100ffdaf (patch) (unidiff)
tree52ff0e10b629dab847077a8b3afcd3f8c0d1b830
parent930f91069c505082a33e43ce5fdca019531a4b5e (diff)
downloadopie-6d2273fb22e10474ae26dd249fa2836e100ffdaf.zip
opie-6d2273fb22e10474ae26dd249fa2836e100ffdaf.tar.gz
opie-6d2273fb22e10474ae26dd249fa2836e100ffdaf.tar.bz2
misc. opcmciasystem improvements
start implementing recursve dirlocks in ODirNotification
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/linux/ofilenotify.cpp59
-rw-r--r--libopie2/opiecore/linux/opcmciasystem.cpp125
-rw-r--r--libopie2/opiecore/linux/opcmciasystem.h39
3 files changed, 141 insertions, 82 deletions
diff --git a/libopie2/opiecore/linux/ofilenotify.cpp b/libopie2/opiecore/linux/ofilenotify.cpp
index 36ec6bf..3096f7e 100644
--- a/libopie2/opiecore/linux/ofilenotify.cpp
+++ b/libopie2/opiecore/linux/ofilenotify.cpp
@@ -254,153 +254,164 @@ bool OFileNotification::activate( const OFileNotificationEvent* e )
254 case DeleteSelf: emit deleted( _path ); break; 254 case DeleteSelf: emit deleted( _path ); break;
255 case Unmount: emit unmounted( _path ); break; 255 case Unmount: emit unmounted( _path ); break;
256 default: assert( 0 ); 256 default: assert( 0 );
257 } 257 }
258 258
259 if ( !_multi ) stop(); 259 if ( !_multi ) stop();
260 260
261 return true; 261 return true;
262} 262}
263 263
264 264
265bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) 265bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
266{ 266{
267 OFileNotification* ofn = new OFileNotification(); 267 OFileNotification* ofn = new OFileNotification();
268 ofn->_signal.connect( receiver, member ); 268 ofn->_signal.connect( receiver, member );
269 return ofn->watch( path, true, type ) != -1; 269 return ofn->watch( path, true, type ) != -1;
270} 270}
271 271
272 272
273void OFileNotification::inotifyEventHandler() 273void OFileNotification::inotifyEventHandler()
274{ 274{
275 qDebug( "OFileNotification::inotifyEventHandler(): reached." ); 275 qDebug( "OFileNotification::inotifyEventHandler(): reached." );
276 276
277 char buffer[16384]; 277 char buffer[16384];
278 ssize_t buffer_i; 278 ssize_t buffer_i;
279 struct inotify_event *pevent, *event; 279 struct inotify_event *pevent, *event;
280 ssize_t r; 280 ssize_t r;
281 size_t event_size; 281 size_t event_size;
282 int count = 0; 282 int count = 0;
283 283
284 r = ::read(_fd, buffer, 16384); 284 r = ::read(_fd, buffer, 16384);
285 285
286 if ( r <= 0 ) 286 if ( r <= 0 )
287 return; 287 return;
288 288
289 buffer_i = 0; 289 buffer_i = 0;
290 while ( buffer_i < r ) 290 while ( buffer_i < r )
291 { 291 {
292 pevent = (struct inotify_event *)&buffer[buffer_i]; 292 pevent = (struct inotify_event *)&buffer[buffer_i];
293 event_size = sizeof(struct inotify_event) + pevent->len; 293 event_size = sizeof(struct inotify_event) + pevent->len;
294 OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask, 294 OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask,
295 pevent->cookie, pevent->len ? pevent->name : 0 ); 295 pevent->cookie, pevent->len ? pevent->name : 0 );
296 e->activate(); 296 e->activate();
297 buffer_i += event_size; 297 buffer_i += event_size;
298 count++; 298 count++;
299 } 299 }
300 300
301 qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count ); 301 qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count );
302} 302}
303 303
304 304
305bool OFileNotification::registerEventHandler() 305bool OFileNotification::registerEventHandler()
306{ 306{
307 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY ); 307 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY );
308 if ( OFileNotification::_fd < 0 ) 308 if ( OFileNotification::_fd < 0 )
309 { 309 {
310 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) ); 310 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) );
311 return false; 311 return false;
312 } 312 }
313 313
314 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" ); 314 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" );
315 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) ); 315 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) );
316 316
317 qDebug( "OFileNotification::registerEventHandler(): done" ); 317 qDebug( "OFileNotification::registerEventHandler(): done" );
318 return true; 318 return true;
319} 319}
320 320
321 321
322void OFileNotification::unregisterEventHandler() 322void OFileNotification::unregisterEventHandler()
323{ 323{
324 if ( _sn ) delete _sn; 324 if ( _sn ) delete _sn;
325 if ( OFileNotification::_fd ) 325 if ( OFileNotification::_fd )
326 ::close( OFileNotification::_fd ); 326 ::close( OFileNotification::_fd );
327 qDebug( "OFileNotification::unregisterEventHandler(): done" ); 327 qDebug( "OFileNotification::unregisterEventHandler(): done" );
328} 328}
329 329
330//================================================================================================= 330//=================================================================================================
331// ODirNotification 331// ODirNotification
332//================================================================================================= 332//=================================================================================================
333ODirNotification::ODirNotification( QObject* parent, const char* name ) 333ODirNotification::ODirNotification( QObject* parent, const char* name )
334 :QObject( parent, name ) 334 :QObject( parent, name )
335{ 335{
336 qDebug( "ODirNotification::ODirNotification()" ); 336 qDebug( "ODirNotification::ODirNotification()" );
337} 337}
338 338
339 339
340ODirNotification::~ODirNotification() 340ODirNotification::~ODirNotification()
341{ 341{
342 qDebug( "ODirNotification::~ODirNotification()" ); 342 qDebug( "ODirNotification::~ODirNotification()" );
343} 343}
344 344
345 345
346int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) 346int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
347{ 347{
348 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse ); 348 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse );
349 349
350 if ( recurse == 0 ) 350 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
351 int result = fn->startWatching( path, sshot, type );
352 if ( result != -1 )
351 { 353 {
352 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" ); 354 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
353 int result = fn->startWatching( path, sshot, type ); 355 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
354 if ( result != -1 ) 356 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
357 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
358 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
359 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
360 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
361 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
362 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
363 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
364 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
365 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
366 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
367 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
368
369 if ( recurse )
355 { 370 {
356 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) ); 371 QDir directory( path );
357 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) ); 372 QStringList subdirs = directory.entryList( QDir::Dirs );
358 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) ); 373
359 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) ); 374 for ( QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it )
360 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) ); 375 {
361 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) ); 376 if ( (*it) == "." || (*it) == ".." ) continue;
362 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) ); 377 QString subpath = QString( "%1/%2" ).arg( path ).arg( *it );
363 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) ); 378 int subresult = watch( subpath, sshot, type, recurse-1 );
364 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) ); 379 if ( subresult == -1 )
365 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );; 380 {
366 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) ); 381 qDebug( "ODirNotification::watch(): subresult for '%s' was -1. Interrupting", (const char*) (*it) );
367 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) ); 382 return -1;
368 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) ); 383 }
369 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) ); 384 }
370 } 385 }
371 return result; 386//connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
372 }
373 else
374 {
375
376 return 1;
377 } 387 }
388 else return -1;
378} 389}
379 390
380 391
381// void ODirNotification::subdirCreated( const QString& name ) 392// void ODirNotification::subdirCreated( const QString& name )
382 393
383 394
384/* 395/*
385 Love-Trowbridge recursive directory scanning algorithm: 396 Love-Trowbridge recursive directory scanning algorithm:
386 397
387 Step 1. Start at initial directory foo. Add watch. 398 Step 1. Start at initial directory foo. Add watch.
388 399
389 Step 2. Setup handlers for watch created in Step 1. 400 Step 2. Setup handlers for watch created in Step 1.
390 Specifically, ensure that a directory created 401 Specifically, ensure that a directory created
391 in foo will result in a handled CREATE_SUBDIR 402 in foo will result in a handled CREATE_SUBDIR
392 event. 403 event.
393 404
394 Step 3. Read the contents of foo. 405 Step 3. Read the contents of foo.
395 406
396 Step 4. For each subdirectory of foo read in step 3, repeat 407 Step 4. For each subdirectory of foo read in step 3, repeat
397 step 1. 408 step 1.
398 409
399 Step 5. For any CREATE_SUBDIR event on bar, if a watch is 410 Step 5. For any CREATE_SUBDIR event on bar, if a watch is
400 not yet created on bar, repeat step 1 on bar. 411 not yet created on bar, repeat step 1 on bar.
401*/ 412*/
402 413
403 414
404} // namespace Ui 415} // namespace Ui
405 416
406} // namespace Opie 417} // namespace Opie
diff --git a/libopie2/opiecore/linux/opcmciasystem.cpp b/libopie2/opiecore/linux/opcmciasystem.cpp
index 0f7ff46..929e289 100644
--- a/libopie2/opiecore/linux/opcmciasystem.cpp
+++ b/libopie2/opiecore/linux/opcmciasystem.cpp
@@ -79,274 +79,301 @@ OPcmciaSystem::OPcmciaSystem()
79 } 79 }
80 } 80 }
81 } 81 }
82 else 82 else
83 { 83 {
84 qWarning( "OPcmciaSystem::OPcmciaSystem() - can't open /proc/devices - continuing with limited functionality." ); 84 qWarning( "OPcmciaSystem::OPcmciaSystem() - can't open /proc/devices - continuing with limited functionality." );
85 } 85 }
86 86
87 synchronize(); 87 synchronize();
88} 88}
89 89
90void OPcmciaSystem::synchronize() 90void OPcmciaSystem::synchronize()
91{ 91{
92 qDebug( "OPcmciaSystem::synchronize()" ); 92 qDebug( "OPcmciaSystem::synchronize()" );
93 _interfaces.clear(); 93 _interfaces.clear();
94 94
95 //FIXME: Use cardmgr subsystem ioctls 95 //FIXME: Use cardmgr subsystem ioctls
96 96
97 QString fileName; 97 QString fileName;
98 if ( QFile::exists( "/var/run/stab" ) ) { fileName = "/var/run/stab"; } 98 if ( QFile::exists( "/var/run/stab" ) ) { fileName = "/var/run/stab"; }
99 else if ( QFile::exists( "/var/state/pcmcia/stab" ) ) { fileName = "/var/state/pcmcia/stab"; } 99 else if ( QFile::exists( "/var/state/pcmcia/stab" ) ) { fileName = "/var/state/pcmcia/stab"; }
100 else { fileName = "/var/lib/pcmcia/stab"; } 100 else { fileName = "/var/lib/pcmcia/stab"; }
101 QFile cardinfofile( fileName ); 101 QFile cardinfofile( fileName );
102 if ( !cardinfofile.exists() || !cardinfofile.open( IO_ReadOnly ) ) 102 if ( !cardinfofile.exists() || !cardinfofile.open( IO_ReadOnly ) )
103 { 103 {
104 qWarning( "pcmcia info file not found or unaccessible" ); 104 qWarning( "pcmcia info file not found or unaccessible" );
105 return; 105 return;
106 } 106 }
107 QTextStream cardinfo( &cardinfofile ); 107 QTextStream cardinfo( &cardinfofile );
108 while ( !cardinfo.atEnd() ) 108 while ( !cardinfo.atEnd() )
109 { 109 {
110 QString strSocket; 110 QString strSocket;
111 int numSocket; 111 int numSocket;
112 char colon; 112 char colon;
113 QString cardName; 113 QString cardName;
114 cardinfo >> strSocket >> numSocket >> colon; 114 cardinfo >> strSocket >> numSocket >> colon;
115 cardName = cardinfo.readLine().stripWhiteSpace(); 115 cardName = cardinfo.readLine().stripWhiteSpace();
116 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 );
117 if ( strSocket == "Socket" && colon == ':' ) 117 if ( strSocket == "Socket" && colon == ':' )
118 { 118 {
119 _interfaces.append( new OPcmciaSocket( _major, numSocket, this, (const char*) cardName ) ); 119 _interfaces.append( new OPcmciaSocket( _major, numSocket, this, (const char*) cardName ) );
120 } 120 }
121 else 121 else
122 { 122 {
123 continue; 123 continue;
124 } 124 }
125 } 125 }
126} 126}
127 127
128 128
129int OPcmciaSystem::count() const 129int OPcmciaSystem::count() const
130{ 130{
131 return _interfaces.count(); 131 return _interfaces.count();
132} 132}
133 133
134 134
135int OPcmciaSystem::cardCount() const 135int OPcmciaSystem::cardCount() const
136{ 136{
137 int nonEmpty = 0; 137 int nonEmpty = 0;
138 OPcmciaSystem::CardIterator it = iterator(); 138 OPcmciaSystem::CardIterator it = iterator();
139 while ( it.current() ) 139 while ( it.current() )
140 { 140 {
141 if ( !it.current()->isEmpty() ) nonEmpty++; 141 if ( !it.current()->isEmpty() ) nonEmpty++;
142 ++it; 142 ++it;
143 } 143 }
144 return nonEmpty; 144 return nonEmpty;
145} 145}
146 146
147 147
148OPcmciaSocket* OPcmciaSystem::socket( unsigned int number ) 148OPcmciaSocket* OPcmciaSystem::socket( unsigned int number )
149{ 149{
150 return _interfaces.at( number ); 150 return _interfaces.at( number );
151} 151}
152 152
153 153
154OPcmciaSystem* OPcmciaSystem::instance() 154OPcmciaSystem* OPcmciaSystem::instance()
155{ 155{
156 if ( !_instance ) _instance = new OPcmciaSystem(); 156 if ( !_instance ) _instance = new OPcmciaSystem();
157 return _instance; 157 return _instance;
158} 158}
159 159
160 160
161OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const 161OPcmciaSystem::CardIterator OPcmciaSystem::iterator() const
162{ 162{
163 return OPcmciaSystem::CardIterator( _interfaces ); 163 return OPcmciaSystem::CardIterator( _interfaces );
164} 164}
165 165
166 166
167/*====================================================================================== 167/*======================================================================================
168 * OPcmciaSocket 168 * OPcmciaSocket
169 *======================================================================================*/ 169 *======================================================================================*/
170 170
171OPcmciaSocket::OPcmciaSocket( int major, int socket, QObject* parent, const char* name ) 171OPcmciaSocket::OPcmciaSocket( int major, int socket, QObject* parent, const char* name )
172 :QObject( parent, name ), _major( major ), _socket( socket ) 172 :QObject( parent, name ), _major( major ), _socket( socket )
173{ 173{
174 qDebug( "OPcmciaSocket::OPcmciaSocket()" ); 174 qDebug( "OPcmciaSocket::OPcmciaSocket()" );
175
176 init(); 175 init();
177 buildInformation();
178} 176}
179 177
180 178
181OPcmciaSocket::~OPcmciaSocket() 179OPcmciaSocket::~OPcmciaSocket()
182{ 180{
183 qDebug( "OPcmciaSocket::~OPcmciaSocket()" ); 181 qDebug( "OPcmciaSocket::~OPcmciaSocket()" );
184 cleanup(); 182 cleanup();
185} 183}
186 184
187 185
188/* internal */ void OPcmciaSocket::init() 186/* internal */ void OPcmciaSocket::init()
189{ 187{
190 // open control socket and gather file descriptor 188 // open control socket and gather file descriptor
191 if ( _major ) 189 if ( _major )
192 { 190 {
193 dev_t dev = makedev( _major, _socket ); 191 dev_t dev = makedev( _major, _socket );
194 QString filename = QString().sprintf( "/tmp/opcmciasystem-%d", ::getpid() ); 192 QString filename = QString().sprintf( "/tmp/opcmciasystem-%d", ::getpid() );
195 if ( ::mknod( (const char*) filename, ( S_IFCHR|S_IREAD|S_IWRITE ), dev ) == 0 ) 193 if ( ::mknod( (const char*) filename, ( S_IFCHR|S_IREAD|S_IWRITE ), dev ) == 0 )
196 { 194 {
197 _fd = ::open( (const char*) filename, O_RDONLY); 195 _fd = ::open( (const char*) filename, O_RDONLY);
198 if ( !_fd ) 196 if ( !_fd )
199 { 197 {
200 qWarning( "OPcmciaSocket::init() - can't open control socket (%s)", strerror( errno ) ); 198 qWarning( "OPcmciaSocket::init() - can't open control socket (%s)", strerror( errno ) );
201 } 199 }
202 else 200 else
203 { 201 {
204 ::unlink( (const char*) filename ); 202 ::unlink( (const char*) filename );
205 } 203 }
206 } 204 }
207 else 205 else
208 { 206 {
209 qWarning( "OPcmciaSocket::init() - can't create device node (%s)", strerror( errno ) ); 207 qWarning( "OPcmciaSocket::init() - can't create device node (%s)", strerror( errno ) );
210 } 208 }
211 } 209 }
212} 210}
213 211
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() 212/* internal */ void OPcmciaSocket::cleanup()
244{ 213{
245 // close control socket 214 // close control socket
246} 215}
247 216
248/* internal */ bool OPcmciaSocket::getTuple( cisdata_t tuple ) 217/* internal */ bool OPcmciaSocket::getTuple( cisdata_t tuple ) const
249{ 218{
250 _ioctlarg.tuple.DesiredTuple = tuple; 219 _ioctlarg.tuple.DesiredTuple = tuple;
251 _ioctlarg.tuple.Attributes = TUPLE_RETURN_COMMON; 220 _ioctlarg.tuple.Attributes = TUPLE_RETURN_COMMON;
252 _ioctlarg.tuple.TupleOffset = 0; 221 _ioctlarg.tuple.TupleOffset = 0;
253 222
254 int result; 223 int result;
255 result = ::ioctl(_fd, DS_GET_FIRST_TUPLE, &_ioctlarg); 224 result = ::ioctl(_fd, DS_GET_FIRST_TUPLE, &_ioctlarg);
256 if ( result != 0 ) 225 if ( result != 0 )
257 { 226 {
258 qWarning( "OPcmciaSocket::getTuple() - DS_GET_FIRST_TUPLE failed (%s)", strerror( errno ) ); 227 qWarning( "OPcmciaSocket::getTuple() - DS_GET_FIRST_TUPLE failed (%s)", strerror( errno ) );
259 return false; 228 return false;
260 } 229 }
261 230
262 result = ::ioctl(_fd, DS_GET_TUPLE_DATA, &_ioctlarg); 231 result = ::ioctl(_fd, DS_GET_TUPLE_DATA, &_ioctlarg);
263 if ( result != 0 ) 232 if ( result != 0 )
264 { 233 {
265 qWarning( "OPcmciaSocket::getTuple() - DS_GET_TUPLE_DATA failed (%s)", strerror( errno ) ); 234 qWarning( "OPcmciaSocket::getTuple() - DS_GET_TUPLE_DATA failed (%s)", strerror( errno ) );
266 return false; 235 return false;
267 } 236 }
268 237
269 result = ::ioctl(_fd, DS_PARSE_TUPLE, &_ioctlarg); 238 result = ::ioctl( _fd, DS_PARSE_TUPLE, &_ioctlarg );
270 if ( result != 0 ) 239 if ( result != 0 )
271 { 240 {
272 qWarning( "OPcmciaSocket::getTuple() - DS_PARSE_TUPLE failed (%s)", strerror( errno ) ); 241 qWarning( "OPcmciaSocket::getTuple() - DS_PARSE_TUPLE failed (%s)", strerror( errno ) );
273 return false; 242 return false;
274 } 243 }
275 244
276 return true; 245 return true;
277} 246}
278 247
279 248
280/* internal */ bool OPcmciaSocket::command( const QString& cmd )
281{
282 QString cmdline = QString().sprintf( "cardctl %s %d &", (const char*) cmd, _socket );
283 ::system( (const char*) cmdline );
284}
285
286int OPcmciaSocket::number() const 249int OPcmciaSocket::number() const
287{ 250{
288 return _socket; 251 return _socket;
289} 252}
290 253
291 254
292QString OPcmciaSocket::identity() const 255QString OPcmciaSocket::identity() const
293{ 256{
294 return ( strcmp( name(), "empty" ) == 0 ) ? "<Empty Socket>" : name(); 257 return ( strcmp( name(), "empty" ) == 0 ) ? "<Empty Socket>" : name();
295} 258}
296 259
297 260
261const OPcmciaSocket::OPcmciaSocketCardStatus OPcmciaSocket::status() const
262{
263 cs_status_t cs_status;
264 cs_status.Function = 0;
265 int result = ::ioctl( _fd, DS_GET_STATUS, &cs_status );
266 if ( result != 0 )
267 {
268 qWarning( "OPcmciaSocket::status() - DS_GET_STATUS failed (%s)", strerror( errno ) );
269 return Unknown;
270 }
271 else
272 {
273 qDebug( " card status = 0x%08x", cs_status.CardState );
274 qDebug( " socket status = 0x%08x", cs_status.SocketState );
275 return (OPcmciaSocket::OPcmciaSocketCardStatus) (cs_status.CardState + cs_status.SocketState);
276 }
277}
278
279
298bool OPcmciaSocket::isUnsupported() const 280bool OPcmciaSocket::isUnsupported() const
299{ 281{
300 return ( strcmp( name(), "unsupported card" ) == 0 ); 282 return ( strcmp( name(), "unsupported card" ) == 0 );
301} 283}
302 284
303 285
304bool OPcmciaSocket::isEmpty() const 286bool OPcmciaSocket::isEmpty() const
305{ 287{
306 return ( strcmp( name(), "empty" ) == 0 ); 288 return ! status() && ( Occupied || OccupiedCardBus );
307} 289}
308 290
309 291
310bool OPcmciaSocket::isSuspended() const 292bool OPcmciaSocket::isSuspended() const
311{ 293{
312 //FIXME 294 return status() && Suspended;
313 return false;
314} 295}
315 296
297
316bool OPcmciaSocket::eject() 298bool OPcmciaSocket::eject()
317{ 299{
318 return command( "eject" ); 300 return ::ioctl( _fd, DS_EJECT_CARD );
319} 301}
320 302
303
321bool OPcmciaSocket::insert() 304bool OPcmciaSocket::insert()
322{ 305{
323 return command( "insert" ); 306 return ::ioctl( _fd, DS_INSERT_CARD );
324} 307}
325 308
309
326bool OPcmciaSocket::suspend() 310bool OPcmciaSocket::suspend()
327{ 311{
328 return command( "suspend" ); 312 return ::ioctl( _fd, DS_SUSPEND_CARD );
329} 313}
330 314
315
331bool OPcmciaSocket::resume() 316bool OPcmciaSocket::resume()
332{ 317{
333 return command( "resume"); 318 return ::ioctl( _fd, DS_RESUME_CARD );
334} 319}
335 320
321
336bool OPcmciaSocket::reset() 322bool OPcmciaSocket::reset()
337{ 323{
338 return command( "reset"); 324 return ::ioctl( _fd, DS_RESET_CARD );
339} 325}
340 326
341const QStringList& OPcmciaSocket::productIdentity() const 327
328QStringList OPcmciaSocket::productIdentity() const
342{ 329{
343 return _productId; 330 QStringList list;
331 cistpl_vers_1_t *vers = &_ioctlarg.tuple_parse.parse.version_1;
332 if ( getTuple( CISTPL_VERS_1 ) )
333 {
334 for ( int i = 0; i < CISTPL_VERS_1_MAX_PROD_STRINGS; ++i )
335 {
336 qDebug( " PRODID = '%s'", vers->str+vers->ofs[i] );
337 list += vers->str+vers->ofs[i];
338 }
339 }
340 else
341 {
342 list += "<unknown>";
343 }
344 return list;
344} 345}
345 346
347
346#if 0 348#if 0
347const QPair& OPcmciaSocket::manufacturerIdentity() const 349const QPair& OPcmciaSocket::manufacturerIdentity() const
348{ 350{
349 return _manufId; 351 return _manufId;
350} 352}
351#endif 353#endif
352 354
355
356QString OPcmciaSocket::function() const
357{
358 cistpl_funcid_t *funcid = &_ioctlarg.tuple_parse.parse.funcid;
359 if ( getTuple( CISTPL_FUNCID ) )
360 {
361 switch ( funcid->func )
362 {
363 case 0: return "Multifunction"; break;
364 case 1: return "Memory"; break;
365 case 2: return "Serial"; break;
366 case 3: return "Parallel"; break;
367 case 4: return "Fixed Disk"; break;
368 case 5: return "Video"; break;
369 case 6: return "Network"; break;
370 case 7: return "AIMS"; break;
371 case 8: return "SCSI"; break;
372 default: return "<unknown>"; break;
373 }
374 }
375 else
376 {
377 return "<unknown>";
378 }
379}
diff --git a/libopie2/opiecore/linux/opcmciasystem.h b/libopie2/opiecore/linux/opcmciasystem.h
index ef34964..ac6c1de 100644
--- a/libopie2/opiecore/linux/opcmciasystem.h
+++ b/libopie2/opiecore/linux/opcmciasystem.h
@@ -16,187 +16,208 @@
16    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 16    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
17  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 17  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.=       =       ; Library General Public License for more 18..}^=.=       =       ; Library General Public License for more
19++=   -.     .`     .: details. 19++=   -.     .`     .: details.
20 :     =  ...= . :.=- 20 :     =  ...= . :.=-
21 -.   .:....=;==+<; You should have received a copy of the GNU 21 -.   .:....=;==+<; You should have received a copy of the GNU
22  -_. . .   )=.  = Library General Public License along with 22  -_. . .   )=.  = Library General Public License along with
23    --        :-=` this library; see the file COPYING.LIB. 23    --        :-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation, 24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, 25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA. 26 Boston, MA 02111-1307, USA.
27 27
28*/ 28*/
29 29
30#ifndef OPCMCIASYSTEM_H 30#ifndef OPCMCIASYSTEM_H
31#define OPCMCIASYSTEM_H 31#define OPCMCIASYSTEM_H
32 32
33#include "linux_pcmcia.h" 33#include "linux_pcmcia.h"
34 34
35#include <qobject.h> 35#include <qobject.h>
36#include <qlist.h> 36#include <qlist.h>
37 37
38namespace Opie { 38namespace Opie {
39namespace Core { 39namespace Core {
40 40
41class OPcmciaSocket; 41class OPcmciaSocket;
42 42
43/*====================================================================================== 43/*======================================================================================
44 * OPcmciaSystem 44 * OPcmciaSystem
45 *======================================================================================*/ 45 *======================================================================================*/
46 46
47/** 47/**
48 * @brief A container class for the linux pcmcia subsystem 48 * @brief A container class for the linux pcmcia subsystem
49 * 49 *
50 * This class provides access to all available pcmcia/cf cards on your device. 50 * This class provides access to all available pcmcia/cf cards on your device.
51 * 51 *
52 * @author Michael 'Mickey' Lauer <mickey@Vanille.de> 52 * @author Michael 'Mickey' Lauer <mickey@Vanille.de>
53 */ 53 */
54class OPcmciaSystem : public QObject 54class OPcmciaSystem : public QObject
55{ 55{
56 Q_OBJECT 56 Q_OBJECT
57 57
58 public: 58 public:
59 typedef QList<OPcmciaSocket> CardList; 59 typedef QList<OPcmciaSocket> CardList;
60 typedef QListIterator<OPcmciaSocket> CardIterator; 60 typedef QListIterator<OPcmciaSocket> CardIterator;
61 61
62 public: 62 public:
63 /** 63 /**
64 * @returns the number of available sockets 64 * @returns the number of available sockets
65 */ 65 */
66 int count() const; 66 int count() const;
67 /** 67 /**
68 * @returns the number of populated sockets 68 * @returns the number of populated sockets
69 */ 69 */
70 int cardCount() const; 70 int cardCount() const;
71 /** 71 /**
72 * @returns a pointer to the (one and only) @ref OSystem instance. 72 * @returns a pointer to the (one and only) @ref OSystem instance.
73 */ 73 */
74 static OPcmciaSystem* instance(); 74 static OPcmciaSystem* instance();
75 /** 75 /**
76 * @returns an iterator usable for iterating through all sound cards. 76 * @returns an iterator usable for iterating through all sound cards.
77 */ 77 */
78 CardIterator iterator() const; 78 CardIterator iterator() const;
79 /** 79 /**
80 * @returns a pointer to the @ref OPcmciaSocket object correspinding to socket number n, or 0, if not found 80 * @returns a pointer to the @ref OPcmciaSocket object correspinding to socket number n, or 0, if not found
81 * @see OPcmciaSocket 81 * @see OPcmciaSocket
82 */ 82 */
83 OPcmciaSocket* socket( unsigned int number ); 83 OPcmciaSocket* socket( unsigned int number );
84 /** 84 /**
85 * @internal Rebuild the internal database 85 * @internal Rebuild the internal database
86 * @note Sometimes it might be useful to call this from client code, 86 * @note Sometimes it might be useful to call this from client code,
87 * e.g. after issuing a cardctl insert 87 * e.g. after issuing a cardctl insert
88 */ 88 */
89 void synchronize(); 89 void synchronize();
90 90
91 protected: 91 protected:
92 OPcmciaSystem(); 92 OPcmciaSystem();
93 93
94 private: 94 private:
95 static OPcmciaSystem* _instance; 95 static OPcmciaSystem* _instance;
96 CardList _interfaces; 96 CardList _interfaces;
97 int _major; 97 int _major;
98 98
99 private: 99 private:
100 class Private; 100 class Private;
101 Private *d; 101 Private *d;
102}; 102};
103 103
104 104
105/*====================================================================================== 105/*======================================================================================
106 * OPcmciaSocket 106 * OPcmciaSocket
107 *======================================================================================*/ 107 *======================================================================================*/
108 108
109class OPcmciaSocket : public QObject 109class OPcmciaSocket : public QObject
110{ 110{
111 Q_OBJECT 111 Q_OBJECT
112 public:
113
114 enum OPcmciaSocketCardStatus
115 {
116 Unknown = 0,
117 Occupied = CS_EVENT_CARD_DETECT,
118 OccupiedCardBus = CS_EVENT_CB_DETECT,
119 WriteProtected = CS_EVENT_WRITE_PROTECT,
120 BatteryLow = CS_EVENT_BATTERY_LOW,
121 BatteryDead = CS_EVENT_BATTERY_DEAD,
122 Ready = CS_EVENT_READY_CHANGE,
123 Suspended = CS_EVENT_PM_SUSPEND,
124 Attention = CS_EVENT_REQUEST_ATTENTION,
125 InsertionInProgress = CS_EVENT_CARD_INSERTION,
126 RemovalInProgress = CS_EVENT_CARD_REMOVAL,
127 ThreeVolts = CS_EVENT_3VCARD,
128 SupportsVoltage = CS_EVENT_XVCARD,
129 };
112 130
113 public: 131 public:
114 /** 132 /**
115 * Constructor. Normally you don't create @ref OPcmciaSocket objects yourself, 133 * Constructor. Normally you don't create @ref OPcmciaSocket objects yourself,
116 * but access them via @ref OPcmciaSystem::socket(). 134 * but access them via @ref OPcmciaSystem::socket().
117 */ 135 */
118 OPcmciaSocket( int major, int socket, QObject* parent, const char* name ); 136 OPcmciaSocket( int major, int socket, QObject* parent, const char* name );
119 /** 137 /**
120 * Destructor. 138 * Destructor.
121 */ 139 */
122 virtual ~OPcmciaSocket(); 140 virtual ~OPcmciaSocket();
123 /** 141 /**
124 * @returns the corresponding socket number 142 * @returns the corresponding socket number
125 */ 143 */
126 int number() const; 144 int number() const;
127 /** 145 /**
128 * @returns the identification string of the card in this socket, or "<Empty Socket>" 146 * @returns the card managers idea of the cards' identy, or "<Empty Socket>"
129 */ 147 */
130 QString identity() const; 148 QString identity() const;
131 /** 149 /**
150 * @returns the socket status
151 */
152 const OPcmciaSocketCardStatus status() const;
153 /**
132 * @returns true, if the card is unsupported by the cardmgr 154 * @returns true, if the card is unsupported by the cardmgr
133 */ 155 */
134 bool isUnsupported() const; 156 bool isUnsupported() const;
135 /** 157 /**
136 * @returns true, if the socket is empty 158 * @returns true, if the socket is empty
137 */ 159 */
138 bool isEmpty() const; 160 bool isEmpty() const;
139 /** 161 /**
140 * @returns true, if the socket is suspended 162 * @returns true, if the socket is suspended
141 */ 163 */
142 bool isSuspended() const; 164 bool isSuspended() const;
143 /** 165 /**
144 * Eject card. @returns true, if operation succeeded 166 * Eject card. @returns true, if operation succeeded
145 * @note: This operation needs root privileges 167 * @note: This operation needs root privileges
146 */ 168 */
147 bool eject(); 169 bool eject();
148 /** 170 /**
149 * Insert card. @returns true, if operation succeeded 171 * Insert card. @returns true, if operation succeeded
150 * @note: This operation needs root privileges 172 * @note: This operation needs root privileges
151 */ 173 */
152 bool insert(); 174 bool insert();
153 /** 175 /**
154 * Suspend card. @returns true, if operation succeeded 176 * Suspend card. @returns true, if operation succeeded
155 * @note: This operation needs root privileges 177 * @note: This operation needs root privileges
156 */ 178 */
157 bool suspend(); 179 bool suspend();
158 /** 180 /**
159 * Resume card. @returns true, if operation succeeded 181 * Resume card. @returns true, if operation succeeded
160 * @note: This operation needs root privileges 182 * @note: This operation needs root privileges
161 */ 183 */
162 bool resume(); 184 bool resume();
163 /** 185 /**
164 * Reset card. @returns true, if operation succeeded 186 * Reset card. @returns true, if operation succeeded
165 * @note: This operation needs root privileges 187 * @note: This operation needs root privileges
166 */ 188 */
167 bool reset(); 189 bool reset();
168 /** 190 /**
169 * @returns a list of product IDs 191 * @returns a list of product IDs
170 */ 192 */
171 const QStringList& productIdentity() const; 193 QStringList productIdentity() const;
172 /** 194 /**
173 * @returns the manufacturer ID pair 195 * @returns the manufacturer ID pair
174 */ 196 */
175#if 0 197#if 0
176 const QPair& manufacturerIdentity() const; 198 const QPair& manufacturerIdentity() const;
177#endif 199#endif
178 200 /**
179 private: 201 * @returns the function string
180 QStringList _productId; 202 */
203 QString function() const;
181 204
182 private: 205 private:
183 void init(); 206 void init();
184 void buildInformation();
185 void cleanup(); 207 void cleanup();
186 bool command( const QString& cmd ); 208 bool getTuple( cisdata_t tuple ) const;
187 bool getTuple( cisdata_t tuple );
188 int _major; 209 int _major;
189 int _socket; 210 int _socket;
190 int _fd; 211 int _fd;
191 ds_ioctl_arg_t _ioctlarg; 212 mutable ds_ioctl_arg_t _ioctlarg;
192 213
193 private: 214 private:
194 class Private; 215 class Private;
195 Private *d; 216 Private *d;
196}; 217};
197 218
198 219
199} 220}
200} 221}
201 222
202#endif // OPCMCIASYSTEM_H 223#endif // OPCMCIASYSTEM_H