Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

l1394_card.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           l1394_card.cpp  -  description
00003                              -------------------
00004     begin                : Wed Jul 5 2000
00005     copyright            : (C) 2000-2004 by Michael Repplinger
00006     email                : repplix@studcs.uni-sb.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "l1394_card.h"
00019 
00020 using std::hex;
00021 using std::dec;
00022 
00023 namespace L1394{
00024 using namespace internal;
00025 Card::Card(const u_int32_t card_id, const u_int32_t node_id, raw1394handle_t default_handle)
00026     : Node(node_id, this)
00027 {
00028   message->debugStream() << "Card > create Card wit node_id" << node_id << endl ;
00029 
00030   setEvent(new Event(this, this));
00031 
00032   this->default_handle = default_handle;
00033   this->card_id        = card_id;
00034 
00035   transaction          = new Transaction(default_handle);
00036 
00037   node_container = internal::NodeContainer::getNodeContainer(); //get the global node_container
00038 
00039   readGuid();
00040 
00041 //begin: init some internal variables
00042   node_count  = 0;
00043   reset_count  = 0;
00044 
00045   setNodeType(_Card);
00046   topo_map    = NULL;
00047   node_array  = new Node*[64];
00048 
00049   for (int i = 0; i<64; i++)
00050     node_array[i] = NULL;
00051 
00052   //create an Csr
00053   rom_info = new CsrRom(this);
00054 
00055   //create bustopology
00056   bustopology = new BusTopology(this);
00057 //end: init some internal variables
00058 
00059   // insert this in node_container
00060   node_container->insert(this);
00061 
00062   message->debugStream()<< "Card < create Card " << endl;
00063 }
00064 
00065 
00066 Card::~Card()
00067 {
00068   message->debugStream()<< "Card > Delete Card object "<< endl;
00069 
00070   getEventObject()->call(NODE_DESTROY);
00071 
00072    for (u_int32_t i = 0; i<node_count; i++)
00073   {
00074     message->debugStream(this)<< "Card > releasing node " << i << " from card " << card_id << endl;
00075     node_container->release(node_array[i]);
00076     node_array[i] = 0;
00077   }
00078 
00079   delete[] node_array;//the nodes are deleted in the global NodeContainer
00080 
00081   delete transaction;
00082 
00083   node_container->removeNode(this);
00084 
00085   message->debugStream()<< "Card > Delete Card object "<< endl;
00086 }
00087 
00088 
00089 void Card::printNodeList() const
00090 {
00091   cout << "Node Count: " << node_count << endl;
00092    cout << " CardNr. | NodeNr. | Node Type    | Ref_count    |  GUID   " << endl;
00093   cout << "--------------------------------------------------------" << endl;
00094   for (u_int32_t i = 0; i< node_count; i++)
00095   cout << "    " << card_id << "         " << node_array[i]->getNodeID() << "       "
00096          << char_node_type[node_array[i]->getNodeType()] << "    " << node_array[i]->getRefCount() << "    " << hex << node_array[i]->getGuid() << dec << endl;
00097 
00098 }
00099 
00100 
00101 void Card::makeNodeList(const raw1394handle_t handle)
00102 {
00103   message->debugStream() << "Card > Begin updating node list on card" << card_id << endl;
00104 
00105   requestTransaction();
00106 
00107   reset_counter_array[card_id]++;
00108 
00109 /*  default_handle->generation     = handle->generation;
00110   default_handle->num_of_nodes   = handle->num_of_nodes ;
00111   default_handle->local_id       = handle->local_id;
00112 */
00113   default_handle = handle;
00114   u_int32_t old_node_count = node_count;
00115 
00116 //update some internal variables
00117   node_count  = raw1394_get_nodecount(default_handle);
00118   setNodeID(raw1394_get_local_id(default_handle) & 0x3f);
00119 
00120   releaseTransaction();
00121 //get a pointer to the new topology map
00122   readTopoMap();
00123 
00124   requestTransaction();
00125 
00126   message->debugStream() << *  topo_map << endl;
00127 
00128 //backup old node_array
00129   Node **old_node_array = node_array;
00130 
00131 // init new node_array
00132   node_array = new Node*[64];
00133   for (int i = 0; i<64; i++)
00134     node_array[i] = NULL;
00135 
00136 // update the new node_array
00137   NodeFactory* node_factory   = NodeFactory::getNodeFactory();
00138   for(u_int32_t i = 0; i<node_count; i++) {
00139     u_int64_t tmp_guid = readAGuid(i);
00140 
00141     if (nodeExist( tmp_guid )) {
00142       message->debugStream() << "Card > Node already exist" << endl;
00143 
00144       node_array[i] = node_container->getNode( tmp_guid );
00145       node_array[i]->setNodeID(i);
00146       node_array[i]->setParentCard(this);
00147     } else {
00148       releaseTransaction();
00149       Node* tmp_node = node_factory->createNode(this, i );
00150       requestTransaction();
00151       if (tmp_node != NULL)
00152       {
00153         if (tmp_node->getGuid() != 0)
00154         {
00155           node_container->insert( tmp_node );
00156           node_array[i] = node_container->getNode( tmp_node->getGuid() );
00157           if (node_array[i] == NULL)
00158               message->errorStream() << "Card > couldn't get inserted node" << endl;
00159         }  else {
00160           node_array[i] = tmp_node;
00161         }
00162       }
00163     }
00164   }
00165 
00166   for (u_int32_t i = 0; i < old_node_count ;i++)  {
00167     if (old_node_array[i] != NULL)  {
00168       if (old_node_array[i]->getGuid() == 0)
00169         delete old_node_array[i];
00170       else
00171         node_container->release(old_node_array[i]);
00172       old_node_array[i] = NULL;
00173     }
00174     else
00175       message->errorStream() << "Card > Couldn't release Node from old_node_array" << endl;
00176   }
00177 
00178   printNodeList();
00179   message->debugStream() << "Card > End updating node list on card" << card_id << endl;
00180   releaseTransaction();
00181 }
00182 
00183 
00184 bool Card::nodeExist(const u_int64_t guid) const {
00185   return node_container->nodeExist(guid);
00186 }
00187 
00188 
00189 
00190 Node* Card::findNode(const int node_type) const {
00191   for (u_int32_t i = 0; i < node_count; i++)  {
00192     if (node_array[i] != NULL)
00193       if (node_array[i]->getNodeType() == node_type) return node_array[i];
00194   }
00195   return NULL;
00196 }
00197 
00198 Node* Card::getNode(const u_int64_t guid) const {
00199   for (u_int32_t i = 0; i<node_count; i++)
00200     if (node_array[i]->getGuid() == guid)
00201       return node_array[i];
00202   return NULL;
00203 }
00204 
00205 u_int64_t Card::readAGuid(const int node_number) {
00206   int i = 0;
00207   while ( topo_map->getQuadlet(i).getBitRange(24,29) != (unsigned int)node_number && i < topo_map->getSize())
00208     i++; //check if it's a node with a physical layer
00209 
00210   if (topo_map->getQuadlet(i).getBit(22) == 0) return 0; // if it's a node with a physical layer return 0
00211 
00212   Quadlet tmp;
00213   u_int64_t node_guid = 0;
00214 
00215   transaction->read(CSR_REGISTER_BASE+CSR_CONFIG_ROM+0x0c, &tmp, node_number);
00216   node_guid = tmp.toInt();
00217   node_guid = node_guid << 32;
00218   transaction->read(CSR_REGISTER_BASE+CSR_CONFIG_ROM+0x10, &tmp, node_number);
00219   node_guid = node_guid | tmp.toInt();
00220   return node_guid;
00221 }
00222 
00223 
00224 list<Node*> Card::getAllNodes(const int node_type) const {
00225   list<Node*> node_list;
00226   for (u_int32_t i = 0; i < node_count; i++) {
00227     if (node_array[i]->getNodeType() == node_type)
00228       node_list.insert(node_list.end(),node_array[i]);
00229   }
00230   return node_list;
00231 }
00232 
00233 
00234 void Card::readTopoMap()
00235 {
00236   Quadlet tmp;
00237 
00238   transaction->read(CSR_REGISTER_BASE+CSR_TOPOLOGY_MAP, &tmp, getNodeID() );
00239   int rom_length = tmp.getBitRange(16,31)-2;
00240 
00241   QArray *new_topo_map = new QArray(rom_length);
00242 
00243   for (int i = 0; i<rom_length; i++)
00244   {
00245     transaction->read(CSR_REGISTER_BASE+CSR_TOPOLOGY_MAP+0x0c+i*4, &tmp, getNodeID());
00246     new_topo_map->insert(tmp,i);
00247   }
00248 
00249   QArray* old_topo_map = topo_map;
00250   topo_map = new_topo_map;
00251   delete old_topo_map;
00252 
00253 }
00254 
00255 
00256 const internal::Transaction* Card::requestTransaction() const {
00257   mutex.lock();
00258   return transaction;
00259 }
00260 
00261 
00262 void Card::releaseTransaction() const {
00263   mutex.unlock();
00264 }
00265 
00266 
00267 int Card::requestIsoChannel() const
00268 {
00269   int channel = -1;
00270   for (int i = 0; i < 64; i++)
00271   {
00272     channel = requestIsoChannel(i);
00273     if (channel == i)
00274       return channel;
00275   }
00276   return L1394_FAILED;
00277 }
00278 
00279 int Card::requestIsoChannel(const u_int32_t channel) const
00280 {
00281   if (channel >= 64)
00282     return -1;
00283 
00284   if (channel < 32)
00285   {
00286     if (low_iso_channel.getBit(channel) != 1)
00287     {
00288       low_iso_channel.setBit(channel,1);
00289       return channel;
00290     }
00291   } else {
00292     if (high_iso_channel.getBit(channel-32) != 1)
00293     {
00294       high_iso_channel.setBit(channel-32, 1);
00295       return (channel+32);
00296     }
00297   }
00298   return L1394_FAILED;
00299 }
00300 
00301 void Card::releaseIsoChannel(const u_int32_t channel) const
00302 {
00303   if (channel < 32)
00304   {
00305     if (low_iso_channel.getBit(channel) == 0)
00306       message->warningStream() << "Card > Iso channel not allocated" << endl;
00307     else
00308       low_iso_channel.setBit(channel, 0);
00309   } else {
00310     if (high_iso_channel.getBit(channel-32) == 0)
00311       message->warningStream() << "Card > Iso channel not allocatd" << endl;
00312     else
00313       high_iso_channel.setBit(channel-32, 0);
00314   }
00315 }
00316 
00317 int Card::reset() const {
00318   if (raw1394_reset_bus(default_handle) == -1)
00319     return L1394_FAILED;
00320   return L1394_SUCCESS;
00321 }
00322 } //end namespace L1394

Generated on Wed Aug 24 00:36:40 2005 for L1394 by doxygen 1.4.2
L1394 library (NMM) grahics.cs.uni-sb.de/~repplix/l1394_home/