Пример #1
0
/* 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;
}
Пример #2
0
/* 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);
}