/*===========================================================================* * main * *===========================================================================*/ int main(int UNUSED(argc), char * UNUSED(argv[])) { int ret_val; USB_MSG("Starting USBD"); USB_MSG("Built: %s %s", __DATE__, __TIME__); /* Basic SEF,DDE,... initialization */ usbd_init(); /* Assume failure unless usbd_start exits gracefully */ ret_val = EXIT_FAILURE; /* USB host controllers initialization */ if (EXIT_SUCCESS == usbd_init_hcd()) { /* Try initializing 'devman' */ if (EXIT_SUCCESS == devman_init()) { /* Run USB driver (actually DDEKit threads) * until this call returns: */ ret_val = usbd_start(); } else USB_MSG("Initializing devman, failed"); /* Clean whatever was initialized */ usbd_deinit_hcd(); } else USB_MSG("Initializing HCDs, failed"); return ret_val; }
/*===========================================================================* * usbd_start * *===========================================================================*/ static int usbd_start(void) { ddekit_thread_t * usbd_th; DEBUG_DUMP; /* Driver's "main loop" is within DDEKit server thread */ usbd_th = ddekit_thread_create(usbd_server_thread, NULL, "ddekit_usb"); /* After spawning, allow server thread to work */ if (NULL != usbd_th) { /* Allow URB scheduling */ if (usbd_init_scheduler()) { USB_MSG("Failed to start URB scheduler"); } else { /* This will lock current thread until DDEKit exits */ ddekit_minix_wait_exit(); } /* Disallow URB scheduling */ usbd_deinit_scheduler(); /* Cleanup */ ddekit_thread_terminate(usbd_th); return EXIT_SUCCESS; } else return EXIT_FAILURE; }
/*===========================================================================* * usbd_signal_handler * *===========================================================================*/ static void usbd_signal_handler(int UNUSED(signo)) { DEBUG_DUMP; USB_MSG("Signal received, exiting USBD..."); /* Try graceful DDEKit exit */ ddekit_shutdown(); /* Unreachable, when ddekit_shutdown works correctly */ USB_ASSERT(0, "Calling ddekit_shutdown failed!"); }
/*===========================================================================* * usbd_sef_handler * *===========================================================================*/ static int usbd_sef_handler(int type, sef_init_info_t * UNUSED(info)) { /* No DEBUG_DUMP, threading unavailable yet */ switch (type) { case SEF_INIT_FRESH: USB_MSG("Initializing"); return EXIT_SUCCESS; case SEF_INIT_LU: USB_MSG("Updating, not implemented"); return EXIT_FAILURE; case SEF_INIT_RESTART: USB_MSG("Restarting, not implemented"); return EXIT_FAILURE; default: USB_MSG("illegal SEF type"); return EXIT_FAILURE; } }
/*===========================================================================* * ddekit_usb_info * *===========================================================================*/ long ddekit_usb_info(struct ddekit_usb_dev * dev, long type, long value) { hcd_event event; hcd_reg1 val; DEBUG_DUMP; /* Decode event */ hcd_decode_info(type, value, &event, &val); if (HCD_EVENT_INVALID == event) { USB_MSG("Invalid info message received"); return EXIT_FAILURE; } else { /* Let HCD handle info message */ hcd_handle_event((hcd_device_state *)dev, event, val); return EXIT_SUCCESS; } }
/*===========================================================================* * hcd_decode_urb * *===========================================================================*/ static void hcd_decode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb) { DEBUG_DUMP; /* Remember original */ urb->original_urb = (void *)dde_urb; /* No UBR error initially */ urb->inout_status = EXIT_SUCCESS; /* Check transfer direction */ switch (dde_urb->direction) { case DDEKIT_USB_IN: urb->direction = HCD_DIRECTION_IN; break; case DDEKIT_USB_OUT: urb->direction = HCD_DIRECTION_OUT; break; default: USB_MSG("URB direction error"); goto URB_ERROR; } /* Check transfer type */ switch (dde_urb->type) { case DDEKIT_USB_TRANSFER_ISO: urb->type = HCD_TRANSFER_ISOCHRONOUS; break; case DDEKIT_USB_TRANSFER_INT: urb->type = HCD_TRANSFER_INTERRUPT; break; case DDEKIT_USB_TRANSFER_CTL: urb->type = HCD_TRANSFER_CONTROL; break; case DDEKIT_USB_TRANSFER_BLK: urb->type = HCD_TRANSFER_BULK; break; default: USB_MSG("URB type error"); goto URB_ERROR; } /* Check transfer endpoint validity */ if ((dde_urb->endpoint <= (int)HCD_LAST_EP) && (dde_urb->endpoint >= (int)HCD_DEFAULT_EP)) urb->endpoint = (hcd_reg1)dde_urb->endpoint; else { USB_MSG("URB endpoint error"); goto URB_ERROR; } /* Check transfer interval validity */ if ((dde_urb->interval <= (int)HCD_HIGHEST_INTERVAL) && (dde_urb->interval >= (int)HCD_LOWEST_INTERVAL)) urb->interval = (hcd_reg1)dde_urb->interval; else { USB_MSG("URB interval error"); goto URB_ERROR; } /* TODO: Alignment of setup packet. Can DDE client guarantee that? */ /* Transfer data assignment */ urb->inout_data = (hcd_reg1 *)dde_urb->data; urb->in_setup = (hcd_ctrlrequest *)dde_urb->setup_packet; /* TODO: Sane size check? */ urb->in_size = (hcd_reg4)dde_urb->size; /* Buffer validity check */ if ((NULL == urb->inout_data) && (NULL == urb->in_setup)) { USB_MSG("URB buffer error"); goto URB_ERROR; } /* Remember device and check for NULL */ if (NULL == (urb->target_device = (hcd_device_state *)dde_urb->dev)) { USB_MSG("URB device pointer error"); goto URB_ERROR; } /* Decoding completed */ return; URB_ERROR: urb->inout_status = EXIT_FAILURE; }