Ejemplo n.º 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;
}
Ejemplo n.º 2
0
/* This function is only used by "Simultaneous" */
static ZERO_OR_ERROR FS_w_simultaneous(struct one_wire_query *owq)
{
	if (SpecifiedBus(PN(owq))) {
		return FS_w_given_bus(owq);
	} else {
		struct simultaneous_struct ss ;
		ss.pin = Inbound_Control.head_port ; 
		memcpy( &(ss.owq), owq, sizeof(struct one_wire_query));	// shallow copy
		Simultaneous_write_callback_port( (void *) (&ss) ) ;
	}
	return 0;
}
Ejemplo n.º 3
0
// This function probably needs to be modified a bit...
static SIZE_OR_ERROR FS_r_simultaneous(struct one_wire_query *owq)
{
	// Device not locked.
	OWQ_allocate_struct_and_pointer(owq_given);

	if (SpecifiedBus(PN(owq))) {
		return FS_r_given_bus(owq);
	}

	memcpy(owq_given, owq, sizeof(struct one_wire_query));	// shallow copy

	// it's hard to know what we should return when reading /simultaneous/temperature
	SetKnownBus(0, PN(owq_given));
	return FS_r_given_bus(owq_given);
}
Ejemplo n.º 4
0
/* This function is only used by "Simultaneous" */
static ZERO_OR_ERROR FS_w_simultaneous(struct one_wire_query *owq)
{
	if (SpecifiedBus(PN(owq))) {
		return FS_w_given_bus(owq);
	} else if (Inbound_Control.head_port) {
		struct port_in * pin ;
		OWQ_allocate_struct_and_pointer(owq_given);

		memcpy(owq_given, owq, sizeof(struct one_wire_query));	// shallow copy

		for ( pin=Inbound_Control.head_port ; pin != NULL ; pin = pin->next ) {
			struct connection_in * cin;
					
			for( cin=pin->first; cin!=NO_CONNECTION ; cin=cin->next ) {
				SetKnownBus(cin->index, PN(owq_given));
				FS_w_given_bus(owq_given);
			}
		}
	}
	return 0;
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
// Early parsing -- only bus entries, uncached and text may have preceeded
static enum parse_enum Parse_Unspecified(char *pathnow, enum parse_pass remote_status, struct parsedname *pn)
{
	static regex_t rx_bus ;
	static regex_t rx_set ;
	static regex_t rx_sta ;
	static regex_t rx_str ;
	static regex_t rx_sys ;
	static regex_t rx_int ;
	static regex_t rx_tex ;
	static regex_t rx_jso ;
	static regex_t rx_unc ;
	static regex_t rx_una ;
	
	struct ow_regmatch orm ;
	orm.number = 1 ; // for bus
	
	ow_regcomp( &rx_bus, "^bus\\.([[:digit:]]+)/?", REG_ICASE ) ;
	ow_regcomp( &rx_set, "^settings/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_sta, "^statistics/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_str, "^structure/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_sys, "^system/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_int, "^interface/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_tex, "^text/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_jso, "^json/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_unc, "^uncached/?", REG_ICASE | REG_NOSUB ) ;
	ow_regcomp( &rx_una, "^unaliased/?", REG_ICASE | REG_NOSUB ) ;
	
	if ( ow_regexec( &rx_bus, pathnow, &orm ) == 0) {
		INDEX_OR_ERROR bus_number = (INDEX_OR_ERROR) atoi(orm.match[1]) ;
		ow_regexec_free( &orm ) ;
		return Parse_Bus( bus_number, pn);

	} else if (ow_regexec( &rx_set, pathnow, NULL ) == 0) {
		return set_type( ePN_settings, pn ) ;

	} else if (ow_regexec( &rx_sta, pathnow, NULL ) == 0) {
		return set_type( ePN_statistics, pn ) ;

	} else if (ow_regexec( &rx_str, pathnow, NULL ) == 0) {
		return set_type( ePN_structure, pn ) ;

	} else if (ow_regexec( &rx_sys, pathnow, NULL ) == 0) {
		return set_type( ePN_system, pn ) ;

	} else if (ow_regexec( &rx_int, pathnow, NULL ) == 0) {
		if (!SpecifiedBus(pn)) {
			return parse_error;
		}
		pn->type = ePN_interface;
		return parse_nonreal;

	} else if (ow_regexec( &rx_tex, pathnow, NULL ) == 0) {
		pn->state |= ePS_text;
		return parse_first;

	} else if (ow_regexec( &rx_jso, pathnow, NULL ) == 0) {
		pn->state |= ePS_json;
		return parse_first;

	} else if (ow_regexec( &rx_unc, pathnow, NULL ) == 0) {
		pn->state |= ePS_uncached;
		return parse_first;

	} else if (ow_regexec( &rx_una, pathnow, NULL ) == 0) {
		pn->state |= ePS_unaliased;
		return parse_first;

	}

	pn->type = ePN_real;
	return Parse_Branch(pathnow, remote_status, pn);
}