Пример #1
0
/* Write now that connection is set */
static ZERO_OR_ERROR FS_w_given_bus(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);

	if ( BAD(TestConnection(pn)) ) {
		return -ECONNABORTED;
	} else if (KnownBus(pn) && BusIsServer(pn->selected_connection)) {
		return ServerWrite(owq);
	} else if (OWQ_pn(owq).type == ePN_real) {
		ZERO_OR_ERROR write_or_error = DeviceLockGet(pn);
		if (write_or_error == 0) {
			write_or_error = FS_w_local(owq);
			DeviceLockRelease(pn);
		} else {
			LEVEL_DEBUG("Cannot lock device for writing") ;
		}
		return write_or_error ;
	} else if ( IsInterfaceDir(pn) ) {
		ZERO_OR_ERROR write_or_error;
		BUSLOCK(pn);
		write_or_error = FS_w_local(owq);
		BUSUNLOCK(pn);
		return write_or_error ;
	} else {
		return FS_w_local(owq);
	}
}
Пример #2
0
/* USB is a special case, in gets reenumerated, so we look for similar DS2401 chip */
GOOD_OR_BAD TestConnection(const struct parsedname *pn)
{
	GOOD_OR_BAD ret = 0;
	struct connection_in *in ;

	if ( pn == NO_PARSEDNAME ) {
		return gbGOOD ;
	}

	in = pn->selected_connection ;
	if ( in == NO_CONNECTION ) {
		return gbGOOD ;
	}
	
	// Test without a lock -- efficient
	if ( in->reconnect_state < reconnect_error ) {
		return gbGOOD;
	}
	
	// Lock the bus
	BUSLOCK(pn);
	// Test again
	if (in->reconnect_state >= reconnect_error) {
		// Add Statistics
		STAT_ADD1_BUS(e_bus_reconnects, in);

		// Close the bus (should leave enough reconnection information available)
		BUS_close(in);	// already locked

		// Call reconnection
		in->AnyDevices = anydevices_unknown ;
		if ( in->iroutines.reconnect != NO_RECONNECT_ROUTINE ) {
			// reconnect method exists
			ret = (in->iroutines.reconnect) (pn) ;	// call bus-specific reconnect
		} else {
			ret = BUS_detect(in->pown) ;	// call initial opener
		}
		if ( BAD( ret ) ) {
			in->reconnect_state = reconnect_ok + 1 ;
			// delay to slow thrashing
			UT_delay(200);
		} else {
			in->reconnect_state = reconnect_ok;
		}
	}
	BUSUNLOCK(pn);

	if ( BAD( ret ) ) {
		LEVEL_DEFAULT("Failed to reconnect %s bus master!", in->adapter_name);
	} else {
		LEVEL_DEFAULT("%s bus master reconnected", in->adapter_name);
	}

	return ret;
}
Пример #3
0
/* Then a series of bytes is sent and returned, including sending data and reading the return data */
GOOD_OR_BAD BUS_transaction(const struct transaction_log *tl, const struct parsedname *pn)
{
	GOOD_OR_BAD ret ;

	if (tl == NULL) {
		return gbGOOD;
	}
	BUSLOCK(pn);
	ret = BUS_transaction_nolock(tl, pn);
	BUSUNLOCK(pn);

	return ret;
}
Пример #4
0
static GOOD_OR_BAD OW_w_status(BYTE * data, size_t size, off_t offset, struct parsedname *pn)
{
	BYTE p[6] = { _1W_WRITE_STATUS, LOW_HIGH_ADDRESS(offset), data[0] };
	GOOD_OR_BAD ret = gbGOOD;
	struct transaction_log tfirst[] = {
		TRXN_START,
		TRXN_WR_CRC16(p, 4, 0),
		TRXN_PROGRAM,
		TRXN_READ1(p),
		TRXN_END,
	};

	if (size == 0) {
		return gbGOOD;
	}
	if (size == 1) {
		return BUS_transaction(tfirst, pn) || (p[0] & (~data[0]));
	}
	BUSLOCK(pn);
	if ( BAD(BUS_transaction(tfirst, pn)) || (p[0] & ~data[0])) {
		ret = gbBAD;
	} else {
		size_t i;
		const BYTE *d = &data[1];
		UINT s = offset + 1;
		struct transaction_log trest[] = {
			//TRXN_WR_CRC16_SEEDED( p, &s, 1, 0 ) ,
			TRXN_WR_CRC16_SEEDED(p, p, 1, 0),
			TRXN_PROGRAM,
			TRXN_READ1(p),
			TRXN_END,
		};
		for (i = 0; i < size; ++i, ++d, ++s) {
			if ( BAD(BUS_transaction(trest, pn)) || (p[0] & ~d[0])) {
				ret = gbBAD;
				break;
			}
		}
	}
	BUSUNLOCK(pn);
	return ret;
}
Пример #5
0
// This function should return number of bytes read... not status.
// Works for all the virtual directories, like statistics, interface, ...
// Doesn't need three-peat and bus was already set or not needed.
static SIZE_OR_ERROR FS_r_virtual(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);
	SIZE_OR_ERROR read_status = 0;

	if (SpecifiedRemoteBus(pn)) {
		/* The bus is not local... use a network connection instead */
		// Read afar -- returns already formatted in buffer
		read_status = ServerRead(owq);
		LEVEL_DEBUG("back from server");
		Debug_OWQ(owq);
	} else {
		/* local bus -- any special locking needs? */
		STAT_ADD1(read_calls);	/* statistics */
		switch (pn->type) {
		case ePN_structure:
			read_status = FS_structure(owq);
			break;
		case ePN_interface:
			BUSLOCK(pn);
			read_status = FS_r_local(owq);	// this returns status
			BUSUNLOCK(pn);
			break;
		case ePN_statistics:
			// reading /statistics/read/tries.ALL
			// will cause a deadlock since it calls STAT_ADD1(read_array);
			// Should perhaps create a new mutex for this.
			// Comment out this STATLOCK until it's solved.
			// STATLOCK now done at time of actual read in ow_stats.c
			read_status = FS_r_local(owq);	// this returns status
			break;
		default:
			read_status = FS_r_local(owq);	// this returns status
		}
		if (read_status >= 0) {
			// local success -- now format in buffer
			read_status = OWQ_parse_output(owq);	// this returns nr. bytes
		}
	}
	LEVEL_DEBUG("return %d", read_status);
	return read_status;
}