📄 tc86c001.c
字号:
}static struct pci_device_id udc_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_USBD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,}};MODULE_DEVICE_TABLE (pci, udc_pci_tbl);static struct pci_driver udc_pci_driver = { name:UDC_NAME, id_table:udc_pci_tbl, probe:udc_probe, remove:__devexit_p (udc_remove),};/* *********************************************************************** *//* * Start of public functions. *//** * udc_start_in_irq - start transmit * @eendpoint: endpoint instance * * Called by bus interface driver to see if we need to start a data transmission. */voidudc_start_in_irq (struct usb_endpoint_instance *endpoint){ int i; for (i = 1; i < UDC_MAX_ENDPOINTS; i++) if (ep_endpoints[i] == endpoint) tc_start_in (i);}/** * udc_init - initialize * * Return non-zero if we cannot see device. **/intudc_init (void){ return pci_module_init (&udc_pci_driver);}#if 0 /* not used *//** * udc_start_in - start transmit * @eendpoint: endpoint instance * * Called by bus interface driver to see if we need to start a data transmission. */voidudc_start_in (struct usb_endpoint_instance *endpoint){}#endif/** * udc_stall_ep - stall endpoint * @ep: physical endpoint * * Stall the endpoint. */voidudc_stall_ep (unsigned int ep){ if (ep < UDC_MAX_ENDPOINTS) { writel (COMMAND_EP (ep) | COMMAND_STALL, &tc_udcregs->Command); }}/** * udc_reset_ep - reset endpoint * @ep: physical endpoint * reset the endpoint. * * returns : 0 if ok, -1 otherwise */voidudc_reset_ep (unsigned int ep){ if (ep < UDC_MAX_ENDPOINTS) { writel (COMMAND_EP (ep) | COMMAND_RESET, &tc_udcregs->Command); }}#if 0 /* not used *//** * udc_endpoint_halted - is endpoint halted * @ep: * * Return non-zero if endpoint is halted */intudc_endpoint_halted (unsigned int ep){ return 0;}#endif/** * udc_set_address - set the USB address for this device * @address: * * Called from control endpoint function after it decodes a set address setup packet. */voidudc_set_address (unsigned char address){ // address cannot be setup until ack received /* tc_udcregs->Address register is read-only */}/** * udc_serial_init - set a serial number if available */int __initudc_serial_init (struct usb_bus_instance *bus){ return -EINVAL;}/* *********************************************************************** *//** * udc_max_endpoints - max physical endpoints * * Return number of physical endpoints. */intudc_max_endpoints (void){ return UDC_MAX_ENDPOINTS;}/** * udc_check_ep - check logical endpoint * @lep: * * Return physical endpoint number to use for this logical endpoint or zero if not valid. */intudc_check_ep (int logical_endpoint, int packetsize){ int ep = logical_endpoint & 0xf; if (ep >= UDC_MAX_ENDPOINTS || packetsize > 64) return 0; /* ASSUMPTION: MstSetting.MST_connection == 0 */ /* MSTWR endpoint must be OUT */ if (ep == UDC_MSTWR_ENDPOINT && (logical_endpoint & USB_DIR_IN)) return 0; /* MSTRD endpoint must be IN */ if (ep == UDC_MSTRD_ENDPOINT && !(logical_endpoint & USB_DIR_IN)) return 0; return ep;}/** * udc_set_ep - setup endpoint * @ep: * @endpoint: * * Associate a physical endpoint with endpoint_instance */voidudc_setup_ep (struct usb_device_instance *device, unsigned int ep, struct usb_endpoint_instance *endpoint){ if (ep < UDC_MAX_ENDPOINTS) { ep_endpoints[ep] = endpoint; dbg_udc (1, "endpoint %d %p", ep, endpoint); // ep0 if (ep == 0) { } // IN else if (endpoint->endpoint_address & 0x80) { int mode = endpoint->tx_attributes & USB_ENDPOINT_XFERTYPE_MASK; int payload = 0; while (8 << payload < endpoint->tx_packetSize) payload++; writel ((payload << 3) | (mode << 1) | 1, &tc_udcregs->EPxMode[ep]); dbg_udc (1, "EP%dMode %x", ep, readl (&tc_udcregs->EPxMode[ep])); } // OUT else if (endpoint->endpoint_address) { int mode = endpoint->rcv_attributes & USB_ENDPOINT_XFERTYPE_MASK; int payload = 0; while (8 << payload < endpoint->rcv_packetSize) payload++; writel ((payload << 3) | (mode << 1) | 0, &tc_udcregs->EPxMode[ep]); if (nodma) { int payload_size = (8 << payload); if (endpoint->rcv_transferSize % payload_size == 0 && endpoint->rcv_transferSize > payload_size) endpoint->rcv_transferSize = payload_size; dbg_rx (1, "ep%d rcv_transferSize %d", ep, payload_size); } usbd_fill_rcv (device, endpoint, 64); /* increased for storage */ endpoint->rcv_urb = first_urb_detached (&endpoint->rdy); dbg_udc (1, "EP%dMode %x", ep, readl (&tc_udcregs->EPxMode[ep])); } }}/** * udc_disable_ep - disable endpoint * @ep: * * Disable specified endpoint */voidudc_disable_ep (unsigned int ep){ if (ep < UDC_MAX_ENDPOINTS) { struct usb_endpoint_instance *endpoint; if ((endpoint = ep_endpoints[ep])) { dbg_udc (1, "disabling endpoint %d %p", ep, endpoint); ep_endpoints[ep] = NULL; usbd_flush_ep (endpoint); } }}/* *********************************************************************** *//** * udc_connected - is the USB cable connected * * Return non-zeron if cable is connected. */intudc_connected (){ return readl (&tc_regs->PowerDetect) & PW_DETECT;}/** * udc_connect - enable pullup resistor * * Turn on the USB connection by enabling the pullup resistor. */voidudc_connect (void){ /* pullup will enabled on INT_USBRESET interrupt */}/** * udc_disconnect - disable pullup resistor * * Turn off the USB connection by disabling the pullup resistor. */voidudc_disconnect (void){ dbg_udc (1, "Disabling pullup"); writel (PW_RESETB, &tc_regs->PowerDetect);}/* *********************************************************************** *//** * udc_all_interrupts - enable interrupts * * Switch on UDC interrupts. * */voidudc_all_interrupts (struct usb_device_instance *device){ // set interrupt mask u32 val = INT_PWRDETECT | INT_SYSERROR | INT_ERR | INT_SETUP | INT_EPxDATASET (3) | INT_ENDPOINT0 | INT_USBRESET | INT_SUSPEND; /* ASSUMPTION: MstSetting.MST_connection == 0 */ /* endpoint 1 must be OUT */ if (nodma) val |= INT_EPxDATASET (1) | INT_EPxDATASET (2); else val |= INT_MSTWRSET | INT_MSTWREND | INT_MSTWRTMOUT | INT_MSTRDEND; writel (val, &tc_regs->IntEnable); dbg_udc (1, "udc_enable_interrupts");}/** * udc_suspended_interrupts - enable suspended interrupts * * Switch on only UDC resume interrupt. * */voidudc_suspended_interrupts (struct usb_device_instance *device){ dbg_udc (1, "udc_suspended_interrupts"); // set interrupt mask writel (INT_SUSPEND | INT_PWRDETECT | INT_USBRESET, &tc_regs->IntEnable);}/** * udc_disable_interrupts - disable interrupts. * * switch off interrupts */voidudc_disable_interrupts (struct usb_device_instance *device){ printk (KERN_DEBUG "udc_disable_interrupts:\n"); // reset interrupt mask writel (0, &tc_regs->IntEnable); tc_do_task_ep = 0;}/* *********************************************************************** *//** * udc_ep0_packetsize - return ep0 packetsize */intudc_ep0_packetsize (void){ return EP0_PACKETSIZE;}/** * udc_enable - enable the UDC * * Switch on the UDC */voidudc_enable (struct usb_device_instance *device){ int i; dbg_udc (1, "enable"); // save the device structure pointer udc_device = device; // ep0 urb if (!ep0_urb) { ep0_urb = usbd_alloc_urb (device, device->function_instance_array, 0, 512); if (!ep0_urb) { printk (KERN_ERR "ep0_enable: usbd_alloc_urb failed\n"); } } else { printk (KERN_ERR "udc_enable: ep0_urb already allocated\n"); } for (i = 0; i < UDC_MAX_ENDPOINTS; i++) ep_dmaaddrs[i] = 0; // enable UDC /* reset and initialize */ writel (0, &tc_regs->PowerDetect); writel (0, &tc_regs->IntEnable); /* need to read tc registers... */ writel (PW_RESETB, &tc_regs->PowerDetect); tc_power_detected ();}/** * udc_disable - disable the UDC * * Switch off the UDC */voidudc_disable (void){ dbg_udc (1, "disable"); // disable UDC writel (0, &tc_regs->PowerDetect); writel (0, &tc_regs->IntEnable); tc_do_task_ep = 0; /* need to read tc registers... */ writel (PW_RESETB, &tc_regs->PowerDetect); // reset device pointer udc_device = NULL; // ep0 urb if (ep0_urb) { usbd_dealloc_urb (ep0_urb); ep0_urb = NULL; }}/** * udc_startup - allow udc code to do any additional startup */voidudc_startup_events (struct usb_device_instance *device){ usbd_device_event (device, DEVICE_INIT, 0); usbd_device_event (device, DEVICE_CREATE, 0);#if 0 usbd_device_event (device, DEVICE_HUB_CONFIGURED, 0); usbd_device_event (device, DEVICE_RESET, 0); // XXX should be done from device event#endif}/* *********************************************************************** *//** * udc_name - return name of USB Device Controller */char *udc_name (void){ return UDC_NAME;}/** * udc_request_udc_irq - request UDC interrupt * * Return non-zero if not successful. */intudc_request_udc_irq (){ return 0; /* request_irq is called in udc_probe */}/** * udc_request_cable_irq - request Cable interrupt * * Return non-zero if not successful. */intudc_request_cable_irq (){ return -1;}/** * udc_request_udc_io - request UDC io region * * Return non-zero if not successful. */intudc_request_io (){ return 0; /* request_region is called in udc_probe */}/** * udc_release_udc_irq - release UDC irq */voidudc_release_udc_irq (){}/** * udc_release_cable_irq - release Cable irq */voidudc_release_cable_irq (){}/** * udc_release_release_io - release UDC io region */voidudc_release_io (){ if (tc_task.sync) { flush_scheduled_tasks (); } pci_unregister_driver (&udc_pci_driver);}/** * udc_regs - dump registers * * Dump registers with printk */voidudc_regs (void){ printk ("\n");}/* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -