/* Read real device (Non-virtual). Will repeat 3 times if needed */ static SIZE_OR_ERROR FS_read_real(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); SIZE_OR_ERROR read_or_error; /* First try */ /* in and bus_nr already set */ read_or_error = FS_read_distribute(owq); /* Second Try */ /* if not a specified bus, relook for chip location */ if (read_or_error < 0) { //error STAT_ADD1(read_tries[1]); if (SpecifiedBus(pn)) { // this bus or bust! if ( BAD(TestConnection(pn)) ) { read_or_error = -ECONNABORTED; } else { read_or_error = FS_read_distribute(owq); // 2nd try if (read_or_error < 0) { // third try STAT_ADD1(read_tries[2]); read_or_error = FS_read_distribute(owq); } } } else if (BusIsServer(pn->selected_connection)) { int bus_nr = pn->selected_connection->index ; // current selected bus INDEX_OR_ERROR busloc_or_error = ReCheckPresence(pn) ; // special handling or remote // only repeat if the bus number is wrong // because the remote does the rereads if ( bus_nr != busloc_or_error ) { if (busloc_or_error < 0) { read_or_error = -ENOENT; } else { read_or_error = FS_read_distribute(owq); if (read_or_error < 0) { // third try STAT_ADD1(read_tries[2]); read_or_error = FS_read_distribute(owq); } } } } else { INDEX_OR_ERROR busloc_or_error = ReCheckPresence(pn); // search again if (busloc_or_error < 0) { read_or_error = -ENOENT; } else { read_or_error = FS_read_distribute(owq); if (read_or_error < 0) { // third try STAT_ADD1(read_tries[2]); read_or_error = FS_read_distribute(owq); } } } } return read_or_error; }
/* If error, try twice more */ static ZERO_OR_ERROR FS_write_real(int depth, struct one_wire_query *owq) { ZERO_OR_ERROR write_or_error; struct parsedname *pn = PN(owq); struct filetype * ft = pn->selected_filetype ; INDEX_OR_ERROR initial_bus = pn->selected_connection->index ; // current selected bus INDEX_OR_ERROR rechecked_bus ; if ( depth > 1 ) { LEVEL_DEBUG("Too many bus changes for write"); return -ENODEV ; } if ( ft->write == FS_w_alias ) { // Special check for alias // it's ok for fake and tester and mock as well // so do this before the fake test // also no need to three-peat. return FS_write_owq(owq) ; } /* Special case for "fake" adapter */ switch (get_busmode(pn->selected_connection)) { case bus_mock: // Mock -- write even "unwritable" to the cache for testing OWQ_Cache_Add(owq) ; // fall through case bus_fake: case bus_tester: return ( ft->write == NO_WRITE_FUNCTION ) ? -ENOTSUP : 0 ; default: // non-virtual devices get handled below break ; } /* First try */ /* in and bus_nr already set */ STAT_ADD1(write_tries[0]); write_or_error = FS_w_given_bus(owq); if ( write_or_error ==0 ) { return 0 ; } /* Second Try */ STAT_ADD1(write_tries[1]); if (SpecifiedBus(pn)) { // The bus number casn't be changed -- it was specified in the path write_or_error = FS_w_given_bus(owq); if ( write_or_error == 0 ) { return 0 ; } // The bus number casn't be changed -- it was specified in the path STAT_ADD1(write_tries[2]); return FS_w_given_bus(owq); } /* Recheck location */ /* if not a specified bus, relook for chip location */ rechecked_bus = ReCheckPresence(pn) ; if ( rechecked_bus < 0 ) { // can't find the location return -ENOENT ; } if ( initial_bus == rechecked_bus ) { // special handling for remote // only repeat if the bus number is wrong // because the remote does the rewrites if (BusIsServer(pn->selected_connection)) { return write_or_error ; } // try again STAT_ADD1(write_tries[1]); write_or_error = FS_w_given_bus(owq); if ( write_or_error == 0 ) { return 0 ; } // third try STAT_ADD1(write_tries[2]); return FS_w_given_bus(owq); } // Changed location retry everything LEVEL_DEBUG("Bus location changed from %d to %d\n",initial_bus,rechecked_bus); return FS_write_real(depth+1,owq); }