int novacom_usb_transport_start(void) { novacom_shutdown = 0; platform_create_thread(&findandattach_thread, &novacom_usb_findandattach_thread, NULL); platform_mutex_init(&recovery_lock); return 0; }
/* main worker thread */ static void *novacom_usb_findandattach_thread(void *arg) { novacom_usb_handle_t *usb; /* init records */ usbrecords_init(); /* initialize records queue */ TAILQ_INIT(&t_recovery_queue); /* device discovery */ while (!novacom_shutdown) { usb = novacom_usb_open(); if (usb ) { usb->shutdown = false; TRACEF("usb_handle 0x%08x, bus=%03d dev=%03d\n", usb->usbll_handle, usb->busnum, usb->devnum); platform_event_create(&usb->tx_startup_event); platform_event_unsignal(&usb->tx_startup_event); usb->tx_startup_wait = 1; platform_event_create(&usb->tx_shutdown_event); platform_event_unsignal(&usb->tx_shutdown_event); platform_create_thread(NULL, &novacom_usb_rx_thread, (void *)usb); platform_create_thread(NULL, &novacom_usb_tx_thread, (void *)usb); } if (!novacom_shutdown) { sleep(1); // dont peg the cpu waiting for usb /* check recovery records, shutdown interface if timeout expired */ (void) usbrecords_update( 1 ); /* assume 1sec delay */ } } /* update records: forcing shutdown of all records */ usbrecords_update(TRANSPORT_RECOVERY_TIMEOUT); return NULL; }
int novacom_usb_transport_start(void) { /*clear auth */ auth_reset(); /* create an event to drive the io worker thread */ platform_event_create(&usb_online_event); platform_event_unsignal(&usb_online_event); /* create a set of events to track the status of the io threads */ platform_event_create(&rx_shutdown_event); platform_event_unsignal(&rx_shutdown_event); platform_event_create(&tx_shutdown_event); platform_event_unsignal(&tx_shutdown_event); /* create a thread to run the control endpoint */ platform_create_thread(NULL, &ep0_thread, NULL); return 0; }
static int set_usb_online(bool on) { if (on) { if (!usb_online) { /*init */ auth_init(); /* sleep for a second to let things settle down */ sleep(1); platform_event_unsignal(&tx_shutdown_event); platform_event_unsignal(&rx_shutdown_event); usbll_handle = novacom_usbll_create("host", MAX_MTU, 0, 0); ep1in_fd = open(ep1in_name, O_RDWR); LOG_PRINTF("ep1 %d\n", ep1in_fd); if (ep1in_fd < 0) { log_printf(LOG_ERROR, "error opening endpoint 1\n"); return -1; } fcntl(ep1in_fd, F_SETFD, FD_CLOEXEC); ep2out_fd = open(ep2out_name, O_RDWR); LOG_PRINTF("ep2 %d\n", ep2out_fd); if (ep2out_fd < 0) { log_printf(LOG_ERROR, "error opening endpoint 2\n"); close(ep1in_fd); return -1; } fcntl(ep2out_fd, F_SETFD, FD_CLOEXEC); usb_online = true; platform_event_signal(&usb_online_event); /* create the worker threads */ LOG_PRINTF("starting worker threads\n"); platform_create_thread(NULL, &tx_thread_entry, NULL); platform_create_thread(NULL, &rx_thread_entry, NULL); } else if(false == gadgetfs_online) { /* postponed_offline->online */ platform_event_signal(&usb_online_event); } } else { if (usb_online) { //change state before sending out signal! usb_online = false; platform_event_signal(&usb_online_event); /* wait for the existing worker threads to go away */ LOG_PRINTF("waiting for worker threads to go away\n"); platform_event_wait(&tx_shutdown_event); close(ep1in_fd); LOG_PRINTF("closed tx_thread\n"); platform_event_wait(&rx_shutdown_event); close(ep2out_fd); LOG_PRINTF("closed rx_thread\n"); novacom_usbll_destroy(usbll_handle); LOG_PRINTF("destroyed novacom usbll_handle\n"); /* clear auth */ auth_reset(); } } return 0; }