int ecm_fd_function_enable (struct usbd_function_instance *function_instance) { struct usb_network_private *npd; struct usbd_class_ethernet_networking_descriptor *ethernet = &ecm_class_2; char address_str[14]; /* do normal network function enable first - this creates network private data */ RETURN_EINVAL_IF(net_fd_function_enable(function_instance, network_ecm, net_fd_recv_urb_ecm, net_fd_start_xmit_ecm, net_fd_start_recv_ecm, 0 )); npd = function_instance->privdata; /* if successful then lets allocate iMACAddress string */ TRACE_MSG6(NTT, "local: %02x:%02x:%02x:%02x:%02x:%02x", npd->local_dev_addr[0], npd->local_dev_addr[1], npd->local_dev_addr[2], npd->local_dev_addr[3], npd->local_dev_addr[4], npd->local_dev_addr[5]); TRACE_MSG6(NTT, "remote: %02x:%02x:%02x:%02x:%02x:%02x", npd->remote_dev_addr[0], npd->remote_dev_addr[1], npd->remote_dev_addr[2], npd->remote_dev_addr[3], npd->remote_dev_addr[4], npd->remote_dev_addr[5]); snprintf(address_str, 13, "%02x%02x%02x%02x%02x%02x", npd->remote_dev_addr[0], npd->remote_dev_addr[1], npd->remote_dev_addr[2], npd->remote_dev_addr[3], npd->remote_dev_addr[4], npd->remote_dev_addr[5]); ethernet->iMACAddress = usbd_alloc_string(function_instance, address_str); return 0; }
/*! blan_fd_urb_received_ep0 - callback for sent URB * * Handles notification that an urb has been sent (successfully or otherwise). * * @return non-zero for failure. */ int blan_fd_urb_received_ep0 (struct usbd_urb *urb, int urb_rc) { TRACE_MSG2(NTT,"urb: %p status: %d", urb, urb->status); RETURN_EINVAL_IF (USBD_URB_OK != urb->status); // TRACE_MSG1(NTT,"%s", urb->buffer); // QQSV is this really a NUL-terminated string??? return -EINVAL; // caller will de-allocate }
/*! * mxc_ocd_mod_init() - initial tcd setup * Allocate interrupts and setup hardware. */ int mxc_ocd_mod_init (struct otg_instance *otg) { int bwkup = request_irq (INT_USB_WAKEUP, pcd_bwkup_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD BWKUP", NULL); int func = request_irq (INT_USB_FUNC, pcd_func_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD FUNC", NULL); int ctrl = request_irq (INT_USB_CTRL, ocd_ctrl_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD CTRL", NULL); //int sof = request_irq (INT_USB_SOF, sof_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD SOF", NULL); //int host = request_irq (OTG_USBHOST, hcd_host_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD HOST", NULL); int host = 0; int dma = request_irq (INT_USB_DMA, ocd_dma_int_hndlr_isr, OTG_INTERRUPT, UDC_NAME " USBD DMA", NULL); TRACE_MSG0(otg->ocd->TAG, "1. Interrupts requested"); RETURN_EINVAL_IF(bwkup || dma || func || host || ctrl); return 0; }
/*! blan_fd_device_request * @brief process a received SETUP URB * * Processes a received setup packet and CONTROL WRITE data. * Results for a CONTROL READ are placed in urb->buffer. * * @param function_instance - pointer to this function instance * @param request - received request to interface or endpoint * @return non-zero for failure. */ int blan_fd_device_request (struct usbd_function_instance *function_instance, struct usbd_device_request *request) { struct usb_network_private *npd = function_instance->privdata; struct usbd_urb *urb; int index; /* Verify that this is a USB Class request per CDC specification or a vendor request. */ RETURN_ZERO_IF (!(request->bmRequestType & (USB_REQ_TYPE_CLASS | USB_REQ_TYPE_VENDOR))); /* Determine the request direction and process accordingly */ switch (request->bmRequestType & (USB_REQ_DIRECTION_MASK | USB_REQ_TYPE_MASK)) { case USB_REQ_HOST2DEVICE | USB_REQ_TYPE_VENDOR: switch (request->bRequest) { case MCCI_ENABLE_CRC: //if (make_crc_table()) // return -EINVAL; //npd->encapsulation = simple_crc; return 0; case BELCARRA_PING: TRACE_MSG1(NTT,"H2D VENDOR IP: %08x", npd->ip_addr); if ((npd->network_type == network_blan)) net_os_send_notification_later(function_instance); break; #if !defined(CONFIG_OTG_NETWORK_BLAN_DO_NOT_SETTIME) || !defined(CONFIG_OTG_NETWORK_SAFE_DO_NOT_SETTIME) case BELCARRA_SETTIME: npd->rfc868time = ntohl( request->wValue << 16 | request->wIndex); net_os_settime(function_instance, npd->rfc868time); break; #endif case BELCARRA_SETIP: #ifdef OTG_BIG_ENDIAN npd->ip_addr = ntohl( request->wValue | request->wIndex<< 16 ); #else /* OTG_BIG_ENDIAN */ npd->ip_addr = ntohl( request->wValue << 16 | request->wIndex); #endif /* OTG_BIG_ENDIAN */ TRACE_MSG1(NTT, "npd->ip_addr: %08x", npd->ip_addr); // XXX need to get in correct order here // XXX what about locally set mac addr // XXX UNLESS(npd->local_dev_set) { if (!(npd->override_MAC)) { npd->local_dev_addr[0] = 0xfe | 0x02; /* locally administered */ npd->local_dev_addr[1] = 0x00; npd->local_dev_addr[2] = (npd->ip_addr >> 24) & 0xff; npd->local_dev_addr[3] = (npd->ip_addr >> 16) & 0xff; npd->local_dev_addr[4] = (npd->ip_addr >> 8) & 0xff; npd->local_dev_addr[5] = (npd->ip_addr >> 0) & 0xff; } // XXX } break; case BELCARRA_SETMSK: #ifdef OTG_BIG_ENDIAN npd->network_mask = ntohl( request->wValue | request->wIndex << 16); #else /* OTG_BIG_ENDIAN */ npd->network_mask = ntohl( request->wValue << 16 | request->wIndex); #endif /* OTG_BIG_ENDIAN */ TRACE_MSG1(NTT, "npd->network_mask: %08x", npd->network_mask); break; case BELCARRA_SETROUTER: #ifdef OTG_BIG_ENDIAN npd->router_ip = ntohl( request->wValue | request->wIndex << 16); #else /* OTG_BIG_ENDIAN */ npd->router_ip = ntohl( request->wValue << 16 | request->wIndex); #endif /* OTG_BIG_ENDIAN */ TRACE_MSG1(NTT, "npd->router_ip: %08x", npd->router_ip); break; case BELCARRA_SETDNS: #ifdef OTG_BIG_ENDIAN npd->dns_server_ip = ntohl( request->wValue | request->wIndex < 16); #else /* OTG_BIG_ENDIAN */ npd->dns_server_ip = ntohl( request->wValue << 16 | request->wIndex); #endif /* OTG_BIG_ENDIAN */ break; #ifdef CONFIG_OTG_NETWORK_BLAN_FERMAT case BELCARRA_SETFERMAT: npd->fermat = 1; break; #endif #ifdef CONFIG_OTG_NETWORK_BLAN_HOSTNAME case BELCARRA_HOSTNAME: TRACE_MSG0(NTT,"HOSTNAME"); RETURN_EINVAL_IF(!(urb = usbd_alloc_urb_ep0(function_instance, le16_to_cpu(request->wLength), blant_fd_urb_received_ep0) )); RETURN_ZERO_IF(!usbd_start_out_urb(urb)); // return if no error usbd_free_urb(urb); // de-alloc if error return -EINVAL; #endif #ifdef CONFIG_OTG_NETWORK_BLAN_DATA_NOTIFY_OK case BELCARRA_DATA_NOTIFY: TRACE_MSG0(NTT,"DATA NOTIFY"); npd->data_notify = 1; return -EINVAL; #endif } switch (request->bRequest) { case BELCARRA_SETIP: case BELCARRA_SETMSK: case BELCARRA_SETROUTER: TRACE_MSG5(NTT, "npd->network_mask: %08x npd->ip_addr: %08x npd->router_ip: %08x flags: %08x %s", npd->network_mask, npd->ip_addr, npd->router_ip, npd->flags, (npd->flags & NETWORK_CONFIGURED) ? "CONFIGURED" : ""); BREAK_UNLESS (npd->network_mask && npd->ip_addr && npd->router_ip && (npd->flags & NETWORK_CONFIGURED)); // let the os layer know, if it's interested. #ifdef CONFIG_OTG_NETWORK_BLAN_AUTO_CONFIG net_os_config(function_instance); net_os_hotplug(function_instance); #endif /* CONFIG_OTG_NETWORK_BLAN_AUTO_CONFIG */ break; } return 0; default: break; }
/*! * otg_message_ioctl_internal() - ioctl call * @param cmd ioctl command. * @param arg ioctl arguement. * @return non-zero for error. */ int otg_message_ioctl_internal(unsigned int cmd, unsigned long arg) { int i; int len; int flag; struct otg_admin_command admin_command; struct otg_status_update status_update; struct otg_firmware_info firmware_info; struct otg_state otg_state; struct otg_test otg_test; struct otg_ioctl_name *otg_ioctl_name; static char func_buf[32]; char *sp, *dp; char *name; //printk(KERN_INFO"%s: cmd: %08x %08x\n", __FUNCTION__, cmd, _IOC_NR(cmd)); //TRACE_MSG2(CORE, "cmd: %08x %08x", cmd, _IOC_NR(cmd)); switch (_IOC_DIR(cmd)) { case _IOC_NONE: switch (_IOC_NR(cmd)) { } break; case _IOC_WRITE: switch (_IOC_NR(cmd)) { case _IOC_NR(OTGADMIN_SET_FUNCTION): TRACE_MSG0(CORE, "OTGADMIN_SET_FUNCTION"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); memset(&admin_command, 0x41, sizeof(struct otg_admin_command)); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); len = sizeof(mesg_otg_instance->function_name); admin_command.string[len] = '\0'; //TRACE_MSG1(CORE, "Setting function: \"%s\"", mesg_otg_instance->function_name); strncpy(mesg_otg_instance->function_name, admin_command.string, len); mesg_otg_instance->function_name[len-1] = '\0'; return 0; case _IOC_NR(OTGADMIN_SET_SERIAL): TRACE_MSG0(CORE, "OTGADMIN_SET_SERIAL"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); admin_command.string[sizeof(admin_command.string) - 1] = '\0'; //printk(KERN_INFO"%s: string: %s\n", __FUNCTION__, admin_command.string); for (sp = admin_command.string, dp = mesg_otg_instance->serial_number, i = 0; *sp && (i < (sizeof(admin_command.string) - 1)); i++, sp++) if (isxdigit(*sp)) *dp++ = toupper(*sp); *sp = '\0'; //TRACE_MSG1(CORE, "serial_number: %s", mesg_otg_instance->serial_number); printk(KERN_INFO"%s: serial: %s\n", __FUNCTION__, mesg_otg_instance->serial_number); return 0; case _IOC_NR(OTGADMIN_SET_INFO): TRACE_MSG0(CORE, "OTGADMIN_SET_INFO"); memset(&firmware_info, 0x41, sizeof(firmware_info)); RETURN_EINVAL_IF(copy_from_user(&firmware_info, (void *)arg, _IOC_SIZE(cmd))); return otg_mesg_set_firmware_info(&firmware_info); return 0; case _IOC_NR(OTGADMIN_SET_STATE): //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE"); RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loading); //TRACE_MSG0(CORE, "OTGADMIN_SET_STATE"); RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loading->number_of_states); memcpy(otg_firmware_loading->otg_states + otg_state.state, &otg_state, sizeof(otg_state)); return 0; case _IOC_NR(OTGADMIN_SET_TEST): //TRACE_MSG0(CORE, "OTGADMIN_GET/SET"); RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loading); //TRACE_MSG1(CORE, "OTGADMIN_SET_TEST : %d", otg_test.test); RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loading->number_of_tests); memcpy(otg_firmware_loading->otg_tests + otg_test.test, &otg_test, sizeof(otg_test)); return 0; } break; case _IOC_READ: switch (_IOC_NR(cmd)) { case _IOC_NR(OTGADMIN_GET_FUNCTION): TRACE_MSG0(CORE, "OTGADMIN_GET_FUNCTION"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); name = otg_usbd_ops->function_name(admin_command.n); admin_command.string[0] = '\0'; if (name) strncat(admin_command.string, name, sizeof(admin_command.string)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_SERIAL): TRACE_MSG0(CORE, "OTGADMIN_GET_SERIAL"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); strncpy(admin_command.string, mesg_otg_instance->serial_number, sizeof(admin_command.string)); admin_command.string[sizeof(admin_command.string) - 1] = '\0'; RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_STATUS): //TRACE_MSG0(CORE, "OTGADMIN_STATUS"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); memset(&status_update, 0, sizeof(struct otg_status_update)); otg_mesg_get_status_update(&status_update); RETURN_EINVAL_IF(copy_to_user((void *)arg, &status_update, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_INFO): TRACE_MSG0(CORE, "OTGADMIN_GET_INFO"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); otg_mesg_get_firmware_info(&firmware_info); RETURN_EINVAL_IF(copy_to_user((void *)arg, &firmware_info, _IOC_SIZE(cmd))); //TRACE_MSG0(CORE, "OTGADMIN_GET_INFO: finished"); return 0; case _IOC_NR(OTGADMIN_GET_STATE): //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE"); RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loaded); //TRACE_MSG0(CORE, "OTGADMIN_GET_STATE"); RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loaded->number_of_states); memcpy(&otg_state, otg_firmware_loaded->otg_states + otg_state.state, sizeof(otg_state)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_state, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_TEST): //TRACE_MSG0(CORE, "OTGADMIN_GET/SET"); RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loaded); //TRACE_MSG1(CORE, "OTGADMIN_GET_TEST: %d", otg_test.test); RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loaded->number_of_tests); memcpy(&otg_test, otg_firmware_loaded->otg_tests + otg_test.test, sizeof(otg_test)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_test, _IOC_SIZE(cmd))); return 0; } break; } TRACE_MSG0(CORE, "OTGADMIN_"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); for (otg_ioctl_name = otg_ioctl_names; otg_ioctl_name && otg_ioctl_name->cmd; otg_ioctl_name++) { //TRACE_MSG4(CORE, "lookup: %04x %04x %08x %08x", // _IOC_NR(cmd), _IOC_NR(otg_ioctl_name->cmd), cmd, otg_ioctl_name->cmd); BREAK_IF(_IOC_NR(otg_ioctl_name->cmd) == _IOC_NR(cmd)); } //TRACE_MSG3(CORE, "checking %d %08x %08x", _IOC_NR(cmd), otg_ioctl_name->cmd, cmd); RETURN_EINVAL_UNLESS(otg_ioctl_name->cmd); __get_user(flag, (int *)arg); //TRACE_MSG3(CORE, "%s %08x flag: %d", otg_ioctl_name->name, otg_ioctl_name->set, flag); otg_event (mesg_otg_instance, flag ? otg_ioctl_name->set : _NOT(otg_ioctl_name->set), CORE, otg_ioctl_name->name); return 0; }