• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

klaptopdaemon

kpcmcia.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2001 George Staikos <staikos@kde.org>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 /*
00022  *   Much of the linux code was migrated from:
00023  *   kardinfo   Copyright 1999, Mirko Sucker <mirko.sucker@unibw-hamburg.de>
00024  */
00025 
00026 #include <QTimer>
00027 #include <QFile>
00028 #include <QRegExp>
00029 //Added by qt3to4:
00030 #include <QTextStream>
00031 #include <Q3MemArray>
00032 
00033 #include <klocale.h>
00034 #include <kcomponentdata.h>
00035 #include <kstandarddirs.h>
00036 
00037 
00038 #include "kpcmcia.h"
00039 
00040 
00041 #ifdef __linux__
00042    extern "C" {
00043       #include <sys/types.h>
00044       #include <unistd.h>
00045       #include <fcntl.h>
00046       #include <sys/stat.h>
00047       #include <sys/ioctl.h>
00048       #include <sys/file.h>
00049       #include <sys/time.h>
00050       #include "linux/version.h"
00051       #include "linux/cs_types.h"
00052       #include "linux/cs.h"
00053       #include "linux/cistpl.h"
00054       #include "linux/ds.h"
00055    }
00056 
00057 // Taken from cardinfo.c
00058 typedef struct event_tag_t {
00059    event_t event;
00060    const char *name;
00061 } event_tag_t;
00062 
00063 
00064 static event_tag_t event_tag[] = {
00065    { CS_EVENT_CARD_INSERTION, "card insertion" },
00066    { CS_EVENT_CARD_REMOVAL, "card removal" },
00067    { CS_EVENT_RESET_PHYSICAL, "prepare for reset" },
00068    { CS_EVENT_CARD_RESET, "card reset successful" },
00069    { CS_EVENT_RESET_COMPLETE, "reset request complete" },
00070    { CS_EVENT_EJECTION_REQUEST, "user eject request" },
00071    { CS_EVENT_INSERTION_REQUEST, "user insert request" },
00072    { CS_EVENT_PM_SUSPEND, "suspend card" },
00073    { CS_EVENT_PM_RESUME, "resume card" },
00074    { CS_EVENT_REQUEST_ATTENTION, "request attention" }
00075 };
00076 
00077 #define NTAGS (sizeof(event_tag)/sizeof(event_tag_t))
00078 
00079 static int lookupDevice(const char *x);
00080 static int openDevice(dev_t dev);
00081 
00082 #else
00083 #include <unistd.h>
00084 #endif
00085 
00086 
00087 
00088 KPCMCIACard::KPCMCIACard() {
00089   _fd = -1;
00090   _num = 9999999;
00091   _status = 0;
00092   _last = 0;
00093         _interrupt = -1;
00094         _ports = "";
00095         _device = "";
00096         _module = "";
00097         _type = "";
00098         _iotype = 0;
00099         _cardname = i18n("Empty slot.");
00100         _vcc = _vpp = _vpp2 = 0;
00101         _inttype = 0;
00102         _cfgbase = 0;
00103 }
00104 
00105 
00106 KPCMCIACard::~KPCMCIACard() {
00107   if (_fd != -1) close(_fd);
00108 }
00109 
00110 
00111 
00112 // RETURN: <0      => error
00113 //         =0      => no error, no update
00114 //         >0      => no error, update happened
00115 //
00116 int KPCMCIACard::refresh() {
00120 #ifdef __linux__
00121 struct timeval tv;
00122 cs_status_t status;
00123 fd_set rfds;
00124 int rc;
00125 event_t event;
00126 struct stat sb;
00127 config_info_t cfg;
00128 KPCMCIACard oldValues(*this);
00129 int updated = 0;
00130 oldValues._fd = -1;
00131 
00132 #define CHECK_CHANGED(x, y) do { if (x.y != y) updated = 1; } while(0)
00133 
00137 tv.tv_sec = 0;  tv.tv_usec = 0;
00138      FD_ZERO(&rfds);
00139      FD_SET(_fd, &rfds);
00140      rc = select(_fd+1, &rfds, NULL, NULL, &tv);
00141      if (rc > 0) {
00142         rc = read(_fd, (void *)&event, 4);
00143         if (rc == 4) {
00144        int thisEvent = -1;  // thisEvent is the index of event in event_tag
00145            for (unsigned int j = 0; j < NTAGS; j++) {
00146               if (event_tag[j].event == event) {
00147                  thisEvent = j;
00148                  break;
00149               }
00150               if (thisEvent < 0) return -1;
00151            }
00152         } else {
00153            return -1;
00154         }
00155      } else return updated;
00156 
00157      if (event == CS_EVENT_EJECTION_REQUEST) {
00158         _interrupt = -1;
00159         _ports = "";
00160         _device = "";
00161         _module = "";
00162         _type = "";
00163         _iotype = 0;
00164         _inttype = 0;
00165         _cfgbase = 0;
00166         _cardname = i18n("Empty slot.");
00167         _vcc = _vpp = _vpp2 = 0;
00168         return updated;
00169      }
00170 
00174      if (!stat(_stabPath.latin1(), &sb) && sb.st_mtime >= _last) {
00175         QFile f(_stabPath.latin1());
00176 
00177         if (f.open(QIODevice::ReadOnly)) {
00178           QTextStream ts(&f);
00179           bool foundit = false;
00180           QString _thisreg = "^Socket %1: ";
00181           QRegExp thisreg ( _thisreg.arg(_num) );
00182 
00183           if (flock(f.handle(), LOCK_SH)) return updated;
00184 
00185           _last = sb.st_mtime;
00186 
00187           // find the card
00188           while(!foundit) {
00189             QString s;
00190             if (ts.eof()) break;
00191             s = ts.readLine();
00192             if (s.contains(thisreg)) {
00193                _cardname = s.right(s.length() - s.find(':') - 1);
00194                _cardname = _cardname.trimmed();
00195                foundit = true;
00196                CHECK_CHANGED(oldValues, _cardname);
00197             }
00198           }
00199 
00200           // read it in
00201           if (foundit && !ts.eof()) {  // FIXME: ts.eof() is a bad error!!
00202             QString s = ts.readLine();
00203             int end;
00204             s.simplified();
00205 
00206             end = s.find(QRegExp("[ \r\t\n]"));
00207             s = s.remove(0, end+1);
00208 
00209             end = s.find(QRegExp("[ \r\t\n]"));
00210             _type = s;
00211             _type.truncate(end);
00212             s = s.remove(0, end+1);
00213 
00214             end = s.find(QRegExp("[ \r\t\n]"));
00215             _module = s;
00216             _module.truncate(end);
00217             s = s.remove(0, end+1);
00218 
00219             end = s.find(QRegExp("[ \r\t\n]"));
00220             s = s.remove(0, end+1);
00221 
00222             end = s.find(QRegExp("[ \r\t\n]"));
00223             _device = s;
00224             _device.truncate(end);
00225             s = s.remove(0, end+1);
00226             CHECK_CHANGED(oldValues, _type);
00227             CHECK_CHANGED(oldValues, _module);
00228             CHECK_CHANGED(oldValues, _device);
00229           }
00230 
00231           flock(f.handle(), LOCK_UN);
00232           f.close();
00233         } else return -1;
00234      } else return updated;
00235 
00236 
00240      status.Function = 0;
00241      ioctl(_fd, DS_GET_STATUS, &status);
00242      memset(&cfg, 0, sizeof(cfg));
00243      ioctl(_fd, DS_GET_CONFIGURATION_INFO, &cfg);
00244      // status is looked up in the table at the top
00245      if (cfg.Attributes & CONF_VALID_CLIENT) {
00246         if (cfg.AssignedIRQ == 0)
00247           _interrupt = -1;
00248         else _interrupt = cfg.AssignedIRQ;
00249 
00250         if (cfg.NumPorts1 > 0) {
00251            int stop = cfg.BasePort1 + cfg.NumPorts1;
00252            if (cfg.NumPorts2 > 0) {
00253               if (stop == cfg.BasePort2) {
00254                  _ports.sprintf("%#x-%#x", cfg.BasePort1, stop+cfg.NumPorts2-1);
00255               } else {
00256                  _ports.sprintf("%#x-%#x, %#x-%#x", cfg.BasePort1, stop-1,
00257                                cfg.BasePort2, cfg.BasePort2+cfg.NumPorts2-1);
00258               }
00259            } else {
00260               _ports.sprintf("%#x-%#x", cfg.BasePort1, stop-1);
00261            }
00262         }
00263         CHECK_CHANGED(oldValues, _ports);
00264         CHECK_CHANGED(oldValues, _interrupt);
00265      }
00266 
00267      _vcc = cfg.Vcc;
00268      _vpp = cfg.Vpp1;
00269      _vpp2 = cfg.Vpp2;
00270      CHECK_CHANGED(oldValues, _vcc);
00271      CHECK_CHANGED(oldValues, _vpp);
00272      CHECK_CHANGED(oldValues, _vpp2);
00273      _inttype = cfg.IntType;
00274      CHECK_CHANGED(oldValues, _inttype);
00275      _iotype = cfg.IOAddrLines;
00276      CHECK_CHANGED(oldValues, _iotype);
00277      _cfgbase = cfg.ConfigBase;
00278      CHECK_CHANGED(oldValues, _cfgbase);
00279 
00280      if (status.CardState & CS_EVENT_CARD_DETECT)
00281         _status |= CARD_STATUS_PRESENT;
00282      if (status.CardState & CS_EVENT_CARD_REMOVAL)
00283         _status &= ~CARD_STATUS_PRESENT;
00284      if (event & CS_EVENT_CARD_REMOVAL)
00285         _status &= ~CARD_STATUS_PRESENT;
00286 
00287      if (!(status.CardState & CS_EVENT_PM_SUSPEND)) {
00288         if (status.CardState & CS_EVENT_READY_CHANGE) {
00289            _status |= CARD_STATUS_READY;
00290            _status &= ~(CARD_STATUS_BUSY|CARD_STATUS_SUSPEND);
00291         } else {
00292            _status |= CARD_STATUS_BUSY;
00293            _status &= ~(CARD_STATUS_READY|CARD_STATUS_SUSPEND);
00294         }
00295      } else if (status.CardState & CS_EVENT_PM_SUSPEND) {
00296         _status |= CARD_STATUS_SUSPEND;
00297         _status &= ~(CARD_STATUS_READY|CARD_STATUS_BUSY);
00298      }
00299 
00300      CHECK_CHANGED(oldValues, _status);
00301 
00302 return updated;
00303 #else
00304 return 0;
00305 #endif
00306 }
00307 
00308 
00309 int KPCMCIACard::insert() {
00310 #ifdef __linux__
00311   ioctl(_fd, DS_INSERT_CARD);
00312   return 0;
00313 #else
00314   return -1;
00315 #endif
00316 }
00317 
00318 
00319 
00320 int KPCMCIACard::eject() {
00321 #ifdef __linux__
00322   ioctl(_fd, DS_EJECT_CARD);
00323   return 0;
00324 #else
00325   return -1;
00326 #endif
00327 }
00328 
00329 
00330 
00331 int KPCMCIACard::reset() {
00332 #ifdef __linux__
00333   ioctl(_fd, DS_RESET_CARD);
00334   return 0;
00335 #else
00336   return -1;
00337 #endif
00338 }
00339 
00340 
00341 
00342 int KPCMCIACard::suspend() {
00343 #ifdef __linux__
00344   ioctl(_fd, DS_SUSPEND_CARD);
00345   return 0;
00346 #else
00347   return -1;
00348 #endif
00349 }
00350 
00351 
00352 
00353 int KPCMCIACard::resume() {
00354 #ifdef __linux__
00355   ioctl(_fd, DS_RESUME_CARD);
00356   return 0;
00357 #else
00358   return -1;
00359 #endif
00360 }
00361 
00362 
00363 
00364 
00365 
00366 KPCMCIA::KPCMCIA(int maxSlots, const char *stabpath) : _maxSlots(maxSlots),
00367                                                        _stabPath(stabpath)  {
00368 
00369 _refreshSpeed = 750;
00370 
00371 _haveCardServices = false;
00372 _timer = new QTimer(this);
00373 connect(_timer, SIGNAL(timeout()), this, SLOT(updateCardInfo()));
00374 _cards = new Q3MemArray<KPCMCIACard *>(_maxSlots+1);
00375 _cardCnt = 0;
00376 
00377 
00379 //  LINUX code
00381 #ifdef __linux__
00382 servinfo_t serv;
00383 
00384    int device = lookupDevice("pcmcia");
00385 
00386    if (device >= 0) {
00387       for (int z = 0; z < _maxSlots; z++) {
00388          int fd = openDevice((device << 8) + z);
00389          if (fd < 0) break;
00390          (*_cards)[_cardCnt] = new KPCMCIACard;
00391          (*_cards)[_cardCnt]->_stabPath = _stabPath;
00392          (*_cards)[_cardCnt]->_fd = fd;
00393          (*_cards)[_cardCnt]->_num = _cardCnt;
00394          //(*_cards)[_cardCnt]->refresh();
00395          _cardCnt++;
00396          //kDebug() << "Found a pcmcia slot" ;
00397       }
00398 
00399       if (_cardCnt > 0) {
00400          if (ioctl((*_cards)[0]->_fd, DS_GET_CARD_SERVICES_INFO, &serv) == 0) {
00401             // FIXME: what to do here?
00402          }
00403          _haveCardServices = true;
00404       }
00405    }
00406 
00407 
00408 
00409 _timer->start(_refreshSpeed, true);
00410 
00412 //  No supported platform.
00414 #else
00415 
00416 #endif
00417 }
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 KPCMCIA::~KPCMCIA() {
00428 //  LINUX code
00430 #ifdef __linux__
00431 
00432 
00434 //  No supported platform.
00436 #else
00437 
00438 #endif
00439 
00440 
00441 delete _timer;
00442 delete _cards;
00443 }
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 KPCMCIACard* KPCMCIA::getCard(int num) {
00452   if (num >= _cardCnt || num < 0) return NULL;
00453   return (*_cards)[num];
00454 }
00455 
00456 
00457 
00458 
00459 void KPCMCIA::updateCardInfo() {
00460  for (int i = 0; i < _cardCnt; i++) {
00461    int rc = (*_cards)[i]->refresh();
00462   /*
00463    kDebug() << "CARD UPDATED: " << i  
00464              << " Name: " << (*_cards)[i]->_cardname << endl
00465              << " Device: " << (*_cards)[i]->_device << endl
00466              << " VCC: " << (*_cards)[i]->_vcc       << endl
00467              << " VPP: " << (*_cards)[i]->_vpp       << endl
00468              << " IRQ: " << (*_cards)[i]->_interrupt << endl
00469              << " Ports: " << (*_cards)[i]->_ports   << endl
00470              << " Type: " << (*_cards)[i]->_type     << endl
00471              << " Module: " << (*_cards)[i]->_module << endl
00472              << endl;
00473    */
00474    if (rc > 0) emit cardUpdated(i);
00475  }
00476 _timer->start(_refreshSpeed, true);
00477 }
00478 
00479 
00480 
00481 void KPCMCIA::setRefreshSpeed(int msec) {
00482   _refreshSpeed = msec;
00483 }
00484 
00485 
00486 int KPCMCIA::getCardCount() {
00487    return _cardCnt;
00488 }
00489 
00490 
00491 bool KPCMCIA::haveCardServices() {
00492   return _haveCardServices;
00493 }
00494 
00495 
00496 #include "kpcmcia.moc"
00497 
00498 
00499 
00500 #ifdef __linux__
00501 static int lookupDevice(const char *x) {
00502 QFile df("/proc/devices");
00503 QString thisreg;
00504 
00505    thisreg = "^[0-9]+ %1$";
00506    thisreg = thisreg.arg(x);
00507 
00508    if (df.open(QIODevice::ReadOnly)) {
00509       QTextStream t(&df);
00510       QString s;
00511       while (!t.eof()) {
00512          s = t.readLine();
00513 
00514          if (s.contains(QRegExp(thisreg))) {
00515             int n = (s.left(3).trimmed()).toInt();
00516             df.close();
00517             return n;
00518          }
00519       }
00520       df.close();
00521    }
00522 return -1;
00523 }
00524 
00525 static int openDevice(dev_t dev) {
00526 QString tmp_path = locateLocal("tmp", KGlobal::mainComponent().componentName());
00527 QString ext = "_socket%1";
00528 
00529   tmp_path += ext.arg((int)dev);
00530 
00531   int rc = mknod(tmp_path.latin1(), (S_IFCHR | S_IREAD), dev);
00532   if (rc < 0) return -1;
00533 
00534   int fd = open(tmp_path.latin1(), O_RDONLY);
00535   if (fd < 0) {
00536      unlink(tmp_path.latin1());
00537      return -1;
00538   }
00539 
00540   if (unlink(tmp_path.latin1()) < 0) {
00541      close(fd);
00542      return -1;
00543   }
00544 
00545   return fd;
00546 }
00547 
00548 #endif
00549 
00550 

klaptopdaemon

Skip menu "klaptopdaemon"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdeutils

Skip menu "kdeutils"
  • ark
  • kcalc
  • kcharselect
  • kdelirc
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • kjots
  • klaptopdaemon
  • kmilo
  • ksim
  • ktimer
  • kwallet
  • superkaramba
Generated for kdeutils by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal