Ejemplo n.º 1
0
void threecom3c505_device::do_receive_command()
{
	// receive pending and no other command is pending
	if (m_rx_pending > 0 && !m_command_pending)
	{
		if (m_rx_data_buffer.get_length() == 0 && !m_rx_fifo.is_empty())
		{
			m_rx_fifo.get(&m_rx_data_buffer);
		}

		// receive data available ?
		if (m_rx_data_buffer.get_length() > 0)
		{
			LOG2(("do_receive_command - data_length=%x rx_pending=%d",
							m_rx_data_buffer.get_length(), m_rx_pending));

			m_rx_pending--;
			set_command_pending(1);

			// preset receive response PCB
			memcpy(&m_response, &m_rcv_response, sizeof(m_rcv_response));

//          m_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
//          m_response.length = 16;
//          m_response.data.rcv_resp.buf_ofs = htole16(0);
//          m_response.data.rcv_resp.buf_seg = htole16(0);
//          m_response.data.rcv_resp.buf_len = htole16(buf_len);

			// htole16 and friends are not portable beyond Linux.  It's named differently on *BSD and differently again on OS X.  Avoid!
			m_response.data.rcv_resp.pkt_len = uint16_to_le(m_rx_data_buffer.get_length());
			m_response.data.rcv_resp.timeout = 0; // successful completion
			m_response.data.rcv_resp.status  = uint16_to_le(m_rx_data_buffer.get_length() > 0 ? 0 : 0xffff);
			m_response.data.rcv_resp.timetag = 0; // TODO: time tag

			// compute and check no of bytes to be DMA'ed (must be even)
			UINT16 buf_len = uint16_from_le(m_response.data.rcv_resp.buf_len) & ~1;
			if (m_rx_data_buffer.get_length() > buf_len)
			{
				LOG1(("do_receive_command !!! buffer size too small (%d < %d)", buf_len, m_rx_data_buffer.get_length()));
				m_response.data.rcv_resp.pkt_len = uint16_to_le(buf_len);
				m_response.data.rcv_resp.status = 0xffff;
			}
			else
			{
				buf_len = (m_rx_data_buffer.get_length() + 1) & ~1;
				m_response.data.rcv_resp.buf_len = uint16_to_le(buf_len);
			}

			m_response_length = m_response.length + 2;
			m_response_index = 0;

			m_status |= ACRF; /* set adapter command register full */
			if (m_control & CMDE)
			{
				set_interrupt(ASSERT_LINE);
			}
		}
	}
}
Ejemplo n.º 2
0
void client_send_red_brick_enumerate(Client *client, EnumerationType type) {
    EnumerateCallback enumerate_callback;
    uint32_t uid = red_usb_gadget_get_uid(); // always little endian

    memset(&enumerate_callback, 0, sizeof(enumerate_callback));

    enumerate_callback.header.uid = uid;
    enumerate_callback.header.length = sizeof(enumerate_callback);
    enumerate_callback.header.function_id = CALLBACK_ENUMERATE;
    packet_header_set_sequence_number(&enumerate_callback.header, 0);
    packet_header_set_response_expected(&enumerate_callback.header, true);

    base58_encode(enumerate_callback.uid, uint32_from_le(uid));
    enumerate_callback.connected_uid[0] = '0';
    enumerate_callback.position = '0';
    enumerate_callback.hardware_version[0] = 1; // FIXME
    enumerate_callback.hardware_version[1] = 0;
    enumerate_callback.hardware_version[2] = 0;
    enumerate_callback.firmware_version[0] = _redapid_version[0];
    enumerate_callback.firmware_version[1] = _redapid_version[1];
    enumerate_callback.firmware_version[2] = _redapid_version[2];
    enumerate_callback.device_identifier = uint16_to_le(RED_BRICK_DEVICE_IDENTIFIER);
    enumerate_callback.enumeration_type = type;

    client_dispatch_response(client, NULL, (Packet *)&enumerate_callback, true, false);
}
Ejemplo n.º 3
0
void threecom3c505_device::do_command()
{
	pcb_struct &command_pcp = (pcb_struct &) m_command_buffer;

	// default to successful completion
	m_response.command = command_pcp.command + CMD_RESPONSE_OFFSET;
	m_response.length = 1;
	m_response.data.failed = 0; // successful completion

	switch (command_pcp.command)
	{
	case CMD_RESET: // 0x00
		// FIXME: should never occur
		break;

	case CMD_CONFIGURE_ADAPTER_MEMORY: // 0x01
		// TODO
		break;

	case CMD_CONFIGURE_82586: // 0x02
		m_i82586_config = command_pcp.data.raw[0] + (command_pcp.data.raw[1] << 8);
		break;

	case CMD_RECEIVE_PACKET: // 0x08
		// preset response PCB from the Receive Command PCB
		m_rcv_response.command = CMD_RECEIVE_PACKET_COMPLETE; // 0x38
		m_rcv_response.length = sizeof(struct Rcv_resp);
		m_rcv_response.data.rcv_resp.buf_ofs = command_pcp.data.rcv_pkt.buf_ofs;
		m_rcv_response.data.rcv_resp.buf_seg = command_pcp.data.rcv_pkt.buf_seg;
		m_rcv_response.data.rcv_resp.buf_len = command_pcp.data.rcv_pkt.buf_len;
		m_rcv_response.data.rcv_resp.pkt_len = 0;
		m_rcv_response.data.rcv_resp.timeout = 0;
		m_rcv_response.data.rcv_resp.status = 0;
		m_rcv_response.data.rcv_resp.timetag = 0L; // TODO

		m_rx_pending++;
		set_command_pending(0);
		return;
		// break;

	case CMD_TRANSMIT_PACKET_F9:
		m_response.command = CMD_TRANSMIT_PACKET_COMPLETE;
		// fall through

	case CMD_TRANSMIT_PACKET: // 0x09
	case CMD_TRANSMIT_PACKET_18: // 0x18
		m_response.length = sizeof(struct Xmit_resp);
		m_response.data.xmit_resp.buf_ofs = 0;
		m_response.data.xmit_resp.buf_seg = 0;
		m_response.data.xmit_resp.c_stat = 0; // successful completion
		m_response.data.xmit_resp.status = 0;
		break;

	case CMD_EXECUTE_PROGRAM: // 0x0e
		// m_response.length = 0;

		// FIXME: hack?
		m_status |= ASF_PCB_END;
		break;

	case CMD_NETWORK_STATISTICS: // 0x0a
		m_response.length = sizeof(struct Netstat);
		m_response.data.netstat.tot_recv = uint16_to_le(m_netstat.tot_recv);
		m_response.data.netstat.tot_xmit = uint16_to_le(m_netstat.tot_xmit);
		m_response.data.netstat.err_CRC = uint16_to_le(m_netstat.err_CRC);
		m_response.data.netstat.err_align = uint16_to_le(m_netstat.err_align);
		m_response.data.netstat.err_res = uint16_to_le(m_netstat.err_res);
		m_response.data.netstat.err_ovrrun = uint16_to_le(m_netstat.err_ovrrun);
		break;

	case CMD_ADAPTER_INFO: // 0x11
		m_response.length = sizeof(struct Info);
		// FIXME: using demo data
		m_response.data.info.minor_vers = 1;
		m_response.data.info.major_vers = 2;
		m_response.data.info.ROM_cksum = uint16_to_le(3);
		m_response.data.info.RAM_sz = uint16_to_le(4);
		m_response.data.info.free_ofs = uint16_to_le(5);
		m_response.data.info.free_seg = uint16_to_le(6);
		break;

	case CMD_LOAD_MULTICAST_LIST:// 0x0b
		if (command_pcp.length > sizeof(m_multicast_list)
				|| (command_pcp.length % ETHERNET_ADDR_SIZE) != 0)
		{
			LOG(("CMD_LOAD_MULTICAST_LIST - unexpected data size %d", command_pcp.length));
		}
		else
		{
			memset(m_multicast_list, 0, sizeof(m_multicast_list));
			memcpy(m_multicast_list, command_pcp.data.multicast, command_pcp.length- 2);
			set_filter_list();
		}
		break;

	case CMD_SET_STATION_ADDRESS: // 0x10
		if (command_pcp.length != sizeof(m_station_address))
		{
			LOG(("CMD_SET_STATION_ADDRESS - unexpected data size %d", command_pcp.length));
			memset(m_station_address, 0, sizeof(m_station_address));
		}
		else
		{
			memcpy(m_station_address, command_pcp.data.eth_addr, command_pcp.length);
		}
		set_filter_list();
		set_mac((char *) m_station_address);
		break;

	case CMD_MC_17: // 0x17
		m_microcode_running = 1;
		break;

	case CMD_DOWNLOAD_PROGRAM: // 0x0d
		UINT16 mc_version = m_program_buffer.get_word(1);
		switch (mc_version)
		{
		case APOLLO_MC_VERSION_SR10_2:
		case APOLLO_MC_VERSION_SR10_4:
			m_microcode_version = mc_version;
			break;
		default:
			m_microcode_version = 0;
			LOG(("CMD_DOWNLOAD_PROGRAM - unexpected microcode version %04x", mc_version));
			break;
		}
		// return microcode version as program id
		m_response.length = 2;
		m_response.data.raw[0] = m_microcode_version & 0xff;
		m_response.data.raw[1] = (m_microcode_version >> 8) & 0xff;
		break;
	}

	m_response_index = 0;
	m_response_length = m_response.length + 2;

	m_status |= ACRF; /* set adapter command register full */
	if (m_control & CMDE)
	{
		set_interrupt(ASSERT_LINE);
	}
}