Exemple #1
0
/**
 * Get TX statistics
 *
 * @v smsc95xx		SMSC95xx device
 * @v stats		Statistics to fill in
 * @ret rc		Return status code
 */
static int smsc95xx_get_tx_statistics ( struct smsc95xx_device *smsc95xx,
					struct smsc95xx_tx_statistics *stats ) {
	int rc;

	/* Get statistics */
	if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_GET_STATISTICS, 0,
				  SMSC95XX_TX_STATISTICS, stats,
				  sizeof ( *stats ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not get TX statistics: "
		       "%s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	return 0;
}
Exemple #2
0
/**
 * Write register (without byte-swapping)
 *
 * @v smsc95xx		SMSC95xx device
 * @v address		Register address
 * @v value		Register value
 * @ret rc		Return status code
 */
static int smsc95xx_raw_writel ( struct smsc95xx_device *smsc95xx,
				 unsigned int address, uint32_t value ) {
	int rc;

	/* Write register */
	DBGCIO ( smsc95xx, "SMSC95XX %p [%03x] <= %08x\n",
		 smsc95xx, address, le32_to_cpu ( value ) );
	if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_REGISTER_WRITE, 0,
				  address, &value, sizeof ( value ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not write %03x: %s\n",
		       smsc95xx, address, strerror ( rc ) );
		return rc;
	}

	return 0;
}
Exemple #3
0
/**
 * Read register (without byte-swapping)
 *
 * @v smsc95xx		SMSC95xx device
 * @v address		Register address
 * @ret value		Register value
 * @ret rc		Return status code
 */
static int smsc95xx_raw_readl ( struct smsc95xx_device *smsc95xx,
				unsigned int address, uint32_t *value ) {
	int rc;

	/* Read register */
	if ( ( rc = usb_control ( smsc95xx->usb, SMSC95XX_REGISTER_READ, 0,
				  address, value, sizeof ( *value ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not read %03x: %s\n",
		       smsc95xx, address, strerror ( rc ) );
		return rc;
	}
	DBGCIO ( smsc95xx, "SMSC95XX %p [%03x] => %08x\n",
		 smsc95xx, address, le32_to_cpu ( *value ) );

	return 0;
}
Exemple #4
0
void usb_isr(void)
{
	uint8_t status, stat, t;

	//serial_print("isr");
	//status = USB0_ISTAT;
	//serial_phex(status);
	//serial_print("\n");
	restart:
	status = USB0_ISTAT;

	if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) {
		if (usb_configuration) {
			t = usb_reboot_timer;
			if (t) {
				usb_reboot_timer = --t;
				if (!t) _reboot_Teensyduino_();
			}
#ifdef CDC_DATA_INTERFACE
			t = usb_cdc_transmit_flush_timer;
			if (t) {
				usb_cdc_transmit_flush_timer = --t;
				if (t == 0) usb_serial_flush_callback();
			}
#endif
#if SEREMU_INTERFACE
			t = usb_seremu_transmit_flush_timer;
			if (t) {
				usb_seremu_transmit_flush_timer = --t;
				if (t == 0) usb_seremu_flush_callback();
			}
#endif
		}
		USB0_ISTAT = USB_INTEN_SOFTOKEN;
	}

	if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
		uint8_t endpoint;
		stat = USB0_STAT;
		//serial_print("token: ep=");
		//serial_phex(stat >> 4);
		//serial_print(stat & 0x08 ? ",tx" : ",rx");
		//serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
		endpoint = stat >> 4;
		if (endpoint == 0) {
			usb_control(stat);
		} else {
			bdt_t *b = stat2bufferdescriptor(stat);
			usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
#if 0
			serial_print("ep:");
			serial_phex(endpoint);
			serial_print(", pid:");
			serial_phex(BDT_PID(b->desc));
			serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
			serial_print(", count:");
			serial_phex(b->desc >> 16);
			serial_print("\n");
#endif
			endpoint--;	// endpoint is index to zero-based arrays

			if (stat & 0x08) { // transmit
				usb_free(packet);
				packet = tx_first[endpoint];
				if (packet) {
					//serial_print("tx packet\n");
					tx_first[endpoint] = packet->next;
					b->addr = packet->buf;
					switch (tx_state[endpoint]) {
					  case TX_STATE_BOTH_FREE_EVEN_FIRST:
						tx_state[endpoint] = TX_STATE_ODD_FREE;
						break;
					  case TX_STATE_BOTH_FREE_ODD_FIRST:
						tx_state[endpoint] = TX_STATE_EVEN_FREE;
						break;
					  case TX_STATE_EVEN_FREE:
					  case TX_STATE_ODD_FREE:
					  default:
						tx_state[endpoint] = TX_STATE_NONE_FREE;
						break;
					}
					b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
				} else {
					//serial_print("tx no packet\n");
					switch (tx_state[endpoint]) {
					  case TX_STATE_BOTH_FREE_EVEN_FIRST:
					  case TX_STATE_BOTH_FREE_ODD_FIRST:
						break;
					  case TX_STATE_EVEN_FREE:
						tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST;
						break;
					  case TX_STATE_ODD_FREE:
						tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST;
						break;
					  default:
						tx_state[endpoint] = ((uint32_t)b & 8) ?
						  TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE;
						break;
					}
				}
			} else { // receive
				packet->len = b->desc >> 16;
				packet->index = 0;
				packet->next = NULL;
				if (rx_first[endpoint] == NULL) {
					//serial_print("rx 1st, epidx=");
					//serial_phex(endpoint);
					//serial_print(", packet=");
					//serial_phex32((uint32_t)packet);
					//serial_print("\n");
					rx_first[endpoint] = packet;
				} else {
					//serial_print("rx Nth, epidx=");
					//serial_phex(endpoint);
					//serial_print(", packet=");
					//serial_phex32((uint32_t)packet);
					//serial_print("\n");
					rx_last[endpoint]->next = packet;
				}
				rx_last[endpoint] = packet;
				// TODO: implement a per-endpoint maximum # of allocated packets
				// so a flood of incoming data on 1 endpoint doesn't starve
				// the others if the user isn't reading it regularly
				packet = usb_malloc();
				if (packet) {
					b->addr = packet->buf;
					b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0);
				} else {
					//serial_print("starving ");
					//serial_phex(endpoint + 1);
					//serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n");
					b->desc = 0;
					usb_rx_memory_needed++;
				}
			}




		}
		USB0_ISTAT = USB_ISTAT_TOKDNE;
		goto restart;
	}