Exemplo n.º 1
0
static void *novacom_usb_tx_thread(void *arg)
{
	novacom_usb_handle_t *handle = (novacom_usb_handle_t *)arg;
	int rc;
	struct novacom_tx_packet packet;
	char *buf;

	buf = platform_calloc(MAX_MTU);
	platform_assert(buf != NULL);

	LTRACEF("start::wait for startup event: %p\n", handle);
	platform_event_wait(&handle->tx_startup_event);   //why waiting rx for starting ???
	handle->tx_startup_wait = 0;			  //change status to started
	LTRACEF("start::startup event received, continue: %p\n", handle);

	handle->tx_timeout = novacom_usbll_get_timeout(handle->usbll_handle);
	while (!novacom_shutdown && !handle->shutdown) {
		// see if we have something to send
		packet.len = novacom_usbll_get_mtu(handle->usbll_handle);
		packet.buf = buf;
		if (novacom_usbll_prepare_tx_packet(handle->usbll_handle, &packet, 100) != TX_NO_PACKET) {
			// write a block back
#if FAULTY_TX
			if (rand() < (RAND_MAX / 10)) {
				TRACEF("dropped tx packet\n");
			} else {
#endif
				rc = novacom_usb_write(handle, packet.buf, packet.len);
				if (rc < 0) {
					platform_time_t st;
					platform_time_t et;
					int time_used = 0;
					unsigned int count = 0;
					TRACEL(LOG_ALWAYS, "usbll(%08x) error writing packet, result(%d), errno %d\n", novacom_usbll_getuid(handle->usbll_handle), rc, errno);
					platform_get_time(&st);
					while (rc < 0 && !handle->shutdown) { //shutdown asap
						platform_get_time(&et);
						if (platform_delta_time_msecs(&st, &et) >= g_usbio_retry_timeout) {
							handle->shutdown = true;
							break;
						}
						if (g_usbio_retry_delay > 0) {
							if ((g_usbio_retry_timeout-time_used) >= g_usbio_retry_delay) {
								usleep(g_usbio_retry_delay * 1000);
								time_used += g_usbio_retry_delay;
							}
							else {
								usleep((g_usbio_retry_timeout - time_used) * 1000);
								time_used = g_usbio_retry_timeout;
							}
						}
						rc = novacom_usb_write(handle, packet.buf, packet.len);
						count++;

					}
		    			TRACEL(LOG_ALWAYS, "usbll(%08x) writing packet, writes(%ld), duration(%dms), result(%d), last_errno %ld\n", novacom_usbll_getuid(handle->usbll_handle), count, platform_delta_time_msecs(&st, &et), rc, errno);
					count = 0;
				}
				if (rc >=0) {
					TRACEF/*LOG_PRINTF*/("usbll(%08x) wrote tx packet len=%d\n", novacom_usbll_getuid(handle->usbll_handle), rc);
				}

#if FAULTY_TX
			}
#endif
		}
	}

	LTRACEF("shutting down handle %p\n", handle);

	platform_event_signal(&handle->tx_shutdown_event);

	platform_free(buf);

	return NULL;
}
Exemplo n.º 2
0
static void *tx_thread_entry(void *arg)
{
	device_pthread_setaffinity();

	int rc;
	int state;
	struct novacom_tx_packet packet;

	const struct aiocb * list[1];
	list[0] = &txaio;

	LOG_PRINTF("entry\n");
	while (usb_online) {
		// see if we have something to send
		packet.len = novacom_usbll_get_mtu(usbll_handle);
		packet.buf = tx_buffer;
		state = novacom_usbll_get_state(usbll_handle);		
		if (novacom_usbll_prepare_tx_packet(usbll_handle, &packet, 100) != TX_NO_PACKET) {

#if	LOCAL_TRACE_RW
			// write a block back
			LTRACEF("going to write packet\n");
#endif

#if 0
			rc = write(ep1in_fd, packet.buf, packet.len);
			LTRACEF("rc %d\n", rc);
			if (rc < 0) {
				TRACEF("error writing packet\n");
				break;
			}
#else
			rc = queue_tx(ep1in_fd, packet.buf, packet.len);
			if (rc < 0) {
				LOG_PRINTF("USB aio_write error, ret=%d, errno=%d\n", rc, errno);
				usleep(1000*GADGETFS_IO_RETRY_DELAY);
				novacom_usbll_changeback_state(usbll_handle, state);
				continue;
			}
			struct timespec timeout;
			rc = suspend(list, 1, &timeout);
			while (rc < 0 && errno == EAGAIN) {
				LOG_PRINTF("USB aio_suspend (for write) error, ret=%d, errno=%d\n", rc, errno);
				rc = suspend(list, 1, &timeout);
				if (rc >= 0) {
					LOG_PRINTF("USB aio_suspend (for write) ret=%d, errno=%d\n", rc, errno);
				}
			};
#if 0
			//do we need it ???
			if (rc < 0) {
				LTRACEF("timeout on tx\n");
				rc = aio_suspend(list, 1, NULL);
			}
#endif
			if (aio_error(&txaio) != EINPROGRESS) {
				rc = aio_return(&txaio);
				if (rc < 0) {
					/* online->offline transition */
					LOG_PRINTF("USB aio_return (for write) error, ret=%d, \n", rc);
					if( (usb_online != gadgetfs_online) && (true == usb_online) ) {
						int ret = platform_event_wait_timeout(&usb_online_event, TRANSPORT_RECOVERY_TIMEOUT * 1000*2);
						if (!ret) {
							LOG_PRINTF("platform_event_wait_timeout for usb_online_event, ret=%d\n", ret);
						}
						else {
							LOG_PRINTF("platform_event_wait_timeout for usb_online_event, ret=%d, ignored\n", ret);
						}
					}
				}
			}
			else {
				LOG_PRINTF("we should never enter here (EINPROGRESS=%d), USB aio write seems to have problem!\n", EINPROGRESS);
			}
			if (rc < 0) {
				novacom_usbll_changeback_state(usbll_handle, state);
			}
			else {
				static platform_time_t prior;
				static int init = 0;
				static unsigned int tx_bytes = 0, tx_packets = 0;
				platform_time_t curr;

				tx_bytes += packet.len;
				tx_packets++;
				if (!init) {
					platform_get_time(&prior);
					init = 1;
				}
				platform_get_time(&curr);
				if (platform_delta_time_msecs(&prior, &curr) >= 2800) { //logging for every 3sec
					platform_get_time(&prior);
					LOG_PRINTF("wrote %u bytes, %u packets\n",tx_bytes, tx_packets);
				}
			}
#endif
		}
	}

	LOG_PRINTF("shutting down\n");
	platform_event_signal(&tx_shutdown_event);

	return NULL;
}