diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-01-25 10:48:33 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-01-25 10:48:33 +0000 |
commit | d717b83056e5076a64c9471dd85573de409582d7 (patch) | |
tree | f46ebf64df73d8f513989d29f54e5b22b8bce2a5 /xpp/xpp_usb.c | |
parent | a11cf4664ea4fd14478f88c9118acd0f87ad7008 (diff) |
* Xbus protocol version: 2.4 (Zaptel 1.2.12/1.4.0 had 2.3).
XPS Init scripts renamed accordingly.
* Performance improvements for multi-XPD (span) devices.
* Astribank BRI driver (in next commit).
* Changes under /proc:
- XBUS and XPD numbers have two digits.
- Every script wildcard should be replaced from XBUS-? to XBUS-[0-9]*
- Added /proc/xpp/XBUS-*/XPD-*/blink: echo 1 to start and 0 to stop.
* Several countries (South Africa, UAE, anybody else) require a shorter
ring delay. Adjust FXO reg 0x17 (23)'s bits 0:2 to 011.
* Use tasklets to move most of the interrupt PCM copying out of the interrupt.
* Debugfs-based code to dump data to userspace (used to debug BRI D channel).
* Pretend every 2.6.9 actually has later RHEL's typedefs.
* fpga_load supports /dev/bus/usb .
* Fixed physical order sorting in genzaptelconf.
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1966 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xpp_usb.c')
-rw-r--r-- | xpp/xpp_usb.c | 138 |
1 files changed, 43 insertions, 95 deletions
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c index c9e83a6..5e9d7d1 100644 --- a/xpp/xpp_usb.c +++ b/xpp/xpp_usb.c @@ -57,7 +57,6 @@ DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) # define URB_ASYNC_UNLINK 0 #endif -#define USBDEV_MAX 10 /* Get a minor range for your devices from the usb maintainer */ #define USB_SKEL_MINOR_BASE 192 @@ -78,21 +77,19 @@ struct xusb_endpoint { usb_complete_t callback; }; -static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack); +static int xusb_xframe_send(xbus_t *xbus, xframe_t *xframe); xbus_ops_t xusb_ops = { - .packet_send = xusb_packet_send, - .packet_new = NULL, // Default allocator - .packet_free = NULL, // Default deallocator + .xframe_send = xusb_xframe_send, + .xframe_new = NULL, // Default allocator + .xframe_free = NULL, // Default deallocator }; enum { - XUSB_N_RX_PACKETS, - XUSB_N_TX_PACKETS, + XUSB_N_RX_FRAMES, + XUSB_N_TX_FRAMES, XUSB_N_RX_ERRORS, XUSB_N_TX_ERRORS, - XUSB_N_PCM_READS, - XUSB_N_PCM_WRITES, }; #define XUSB_COUNTER(xusb, counter) ((xusb)->counters[XUSB_N_ ## counter]) @@ -102,12 +99,10 @@ enum { static struct xusb_counters { char *name; } xusb_counters[] = { - C_(RX_PACKETS), - C_(TX_PACKETS), + C_(RX_FRAMES), + C_(TX_FRAMES), C_(RX_ERRORS), C_(TX_ERRORS), - C_(PCM_READS), - C_(PCM_WRITES), }; #undef C_ @@ -145,7 +140,7 @@ typedef struct xpp_usb_bus { } xusb_t; static spinlock_t xusb_lock = SPIN_LOCK_UNLOCKED; -static xusb_t *xusb_array[USBDEV_MAX] = {}; +static xusb_t *xusb_array[MAX_BUSES] = {}; static unsigned bus_count = 0; @@ -173,55 +168,7 @@ static void xusb_disconnect (struct usb_interface *interface); static int xusb_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); /*------------------------------------------------------------------*/ - #if 0 -/** - * Allocates a new XPP packet. - * @xbus The XPP bus in which the packet will flow (for counters - * maintenance) - * @flags Flags for kernel memory allocation. - * @returns A pointer to the new packet, or NULL in case of failure. - * - * - * Packet allocation/deallocation: - * Sent packets: - * - Allocated by protocol commands - * - Deallocated by xmus_xmitter - * Receive packets: - * - Allocated/deallocated by xbus_xmiter - */ -xpacket_t *xusb_packet_new(xbus_t *xbus, int flags) -{ - xpacket_t *pack; - - /* To avoid races we increament counter in advance and decrement it later - * in case of failure */ - atomic_inc(&xbus->packet_counter); - //DBG("Incremented packet_counter of bus %s (new packet) to %d\n", - // xbus->busname, atomic_read(&xbus->packet_counter)); - pack = kmem_cache_alloc(packet_cache, flags); - if (pack) { - memset(pack, 0, sizeof(xpacket_t)); - atomic_inc(&xpacket_count); - } else { - atomic_dec(&xbus->packet_counter); - //DBG("Decremented packet_counter of bus %s (failed new packet) to %d\n", - // xbus->busname, atomic_read(&xbus->packet_counter)); - } - return pack; -} - -void xusb_packet_free(xbus_t *xbus, xpacket_t *p) -{ - kmem_cache_free(packet_cache, p); - atomic_dec(&xpacket_count); - atomic_dec(&xbus->packet_counter); - //DBG("Decremented packet_counter of bus %s (freed packet) to %d\n", - // xbus->busname, atomic_read(&xbus->packet_counter)); -} - -#endif - #ifndef DEBUG #define packet_debug(m, x, p) @@ -233,7 +180,7 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack) { char title[XBUS_DESCLEN]; - if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_READ)) { + if(pack->opcode == XPROTO_NAME(GLOBAL,PCM_READ)) { #ifdef DEBUG_PCM_TIMING /* * DEBUG: high-res timing of PCM_READ to PCM_WRITE @@ -247,7 +194,7 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack) dump_packet("USB RECEIVE PCM", pack, print_dbg); #endif return; - } else if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_WRITE)) { + } else if(pack->opcode == XPROTO_NAME(GLOBAL,PCM_WRITE)) { #ifdef DEBUG_PCM_TIMING /* * DEBUG: high-res timing of PCM_READ to PCM_WRITE @@ -261,7 +208,7 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack) dump_packet("USB SEND PCM", pack, print_dbg); #endif return; - } else if(pack->content.opcode == XPROTO_NAME(GLOBAL, REGISTER_REQUEST)) { + } else if(pack->opcode == XPROTO_NAME(GLOBAL, REGISTER_REQUEST)) { reg_cmd_t *regcmd; regcmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd); @@ -278,16 +225,18 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack) return; } #if 0 - } else if(pack->content.opcode == XPROTO_NAME(FXS, REGISTER_REPLY)) { + } else if(pack->opcode == XPROTO_NAME(FXS, REGISTER_REPLY)) { return; #endif } snprintf(title, XBUS_DESCLEN, "%s: %s", msg, xusb->xbus->busname); dump_packet(title, pack, print_dbg); } + +#endif #endif -static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) +static int xusb_xframe_send(xbus_t *xbus, xframe_t *xframe) { xusb_t *xusb; struct urb *urb; @@ -295,7 +244,7 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) size_t size; struct xusb_endpoint *xusb_ep; - BUG_ON(!pack); + BUG_ON(!xframe); BUG_ON(!xbus); xusb = xbus->priv; BUG_ON(!xusb); @@ -315,7 +264,9 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) ret = -ENODEV; goto freepack; } - size = PACKET_LEN(pack); + if (print_dbg) + dump_xframe("USB_FRAME_SEND", xbus, xframe); + size = XFRAME_LEN(xframe); xusb_ep = &xusb->endpoints[XUSB_SEND]; urb = xpp_urb_new(xusb, XUSB_SEND, size); if (!urb) { @@ -323,10 +274,10 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) ret = -ENOMEM; goto freepack; } - packet_debug("USB_PACKET_SEND", xusb, pack); /* FIXME: FIXME: FIXME: we use copy+free until low-level drivers allocate memory themselves */ - memcpy(urb->transfer_buffer, &pack->content, size); + + memcpy(urb->transfer_buffer, xframe->packets, size); ret = usb_submit_urb(urb, GFP_ATOMIC); if(ret < 0) { @@ -339,10 +290,8 @@ static int xusb_packet_send(xbus_t *xbus, xpacket_t *pack) goto freepack; } atomic_inc(&xusb->pending_writes); - if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_WRITE)) - XUSB_COUNTER(xusb, PCM_WRITES)++; freepack: - xbus->ops->packet_free(xbus, pack); // FIXME: eventually will be done in the urb callback + xbus->ops->xframe_free(xbus, xframe); // FIXME: eventually will be done in the urb callback if(ret < 0) XUSB_COUNTER(xusb, TX_ERRORS)++; return ret; @@ -509,7 +458,7 @@ static int set_endpoints(xusb_t *xusb, struct usb_interface *interface, struct x } if(usb_pipein(ep_addr)) { // Input if(ep_addr == model_info->in.ep_addr) { - if(endpoint->wMaxPacketSize < sizeof(xpacket_raw_t)) { + if(endpoint->wMaxPacketSize < sizeof(xframe_t)) { NOTICE("USB input endpoint 0x%X support only wMaxPacketSize=%d (need USB-2)\n", ep_addr, endpoint->wMaxPacketSize); } xusb_ep = &xusb->endpoints[XUSB_RECV]; @@ -519,7 +468,7 @@ static int set_endpoints(xusb_t *xusb, struct usb_interface *interface, struct x } } else { // Output if(ep_addr == model_info->out.ep_addr) { - if(endpoint->wMaxPacketSize < sizeof(xpacket_raw_t)) { + if(endpoint->wMaxPacketSize < sizeof(xframe_t)) { NOTICE("USB output endpoint 0x%X support only wMaxPacketSize=%d (need USB-2)\n", ep_addr, endpoint->wMaxPacketSize); } xusb_ep = &xusb->endpoints[XUSB_SEND]; @@ -629,12 +578,12 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i xbus->max_packet_size = min(xusb->endpoints[XUSB_SEND].max_size , xusb->endpoints[XUSB_RECV].max_size); spin_lock_irqsave(&xusb_lock, flags); - for(i = 0; i < USBDEV_MAX; i++) { + for(i = 0; i < MAX_BUSES; i++) { if(xusb_array[i] == NULL) break; } spin_unlock_irqrestore(&xusb_lock, flags); - if(i >= USBDEV_MAX) { + if(i >= MAX_BUSES) { ERR("xpp_usb: Too many XPP USB buses\n"); retval = -ENOMEM; goto probe_failed; @@ -720,11 +669,11 @@ static void xusb_disconnect(struct usb_interface *interface) xbus = xusb->xbus; /* find our xusb */ - for(i = 0; i < USBDEV_MAX; i++) { + for(i = 0; i < MAX_BUSES; i++) { if(xusb_array[i] == xusb) break; } - BUG_ON(i >= USBDEV_MAX); + BUG_ON(i >= MAX_BUSES); xusb_array[i] = NULL; #ifdef CONFIG_PROC_FS @@ -779,7 +728,7 @@ static void xpp_send_callback(struct urb *urb, struct pt_regs *regs) return; } /* allow device read, write and ioctl */ - XUSB_COUNTER(xusb, TX_PACKETS)++; + XUSB_COUNTER(xusb, TX_FRAMES)++; } static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs) @@ -787,6 +736,7 @@ static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs) xusb_t *xusb = (xusb_t *)urb->context; xbus_t *xbus; xpacket_t *pack; + xframe_t *xframe; size_t size; int retval; bool do_resubmit = 1; @@ -822,25 +772,22 @@ static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs) do_resubmit = 0; goto end; } - pack = xbus->ops->packet_new(xbus, GFP_ATOMIC); - if(!pack) { + xframe = xbus->ops->xframe_new(xbus, GFP_ATOMIC); + if(!xframe) { ERR("%s: Not enough memory for packets. Dropping\n", __FUNCTION__); goto end; } - size = urb->actual_length; - memcpy(&pack->content, urb->transfer_buffer, size); - - pack->datalen = size - sizeof(xpd_addr_t) - 1; // opcode size - // DBG("datalen of new packet: %d\n", pack->datalen); + atomic_set(&xframe->frame_len, size); + pack = (xpacket_t *)xframe->packets; + memcpy(xframe->packets, urb->transfer_buffer, size); - packet_debug("USB_PACKET_RECEIVE", xusb, pack); - XUSB_COUNTER(xusb, RX_PACKETS)++; - if(pack->content.opcode == XPROTO_NAME(GLOBAL,PCM_READ)) - XUSB_COUNTER(xusb, PCM_READS)++; + if (print_dbg) + dump_xframe("USB_FRAME_RECEIVE", xbus, xframe); + XUSB_COUNTER(xusb, RX_FRAMES)++; // Send UP - packet_receive(xbus, pack); -end: + xframe_receive(xbus, xframe); +end: if(is_inuse) up_read(&xbus->in_use); if(do_resubmit) { @@ -860,7 +807,7 @@ int __init xpp_usb_init(void) int result; //xusb_t *xusb; - INFO("%s\n", THIS_MODULE->name); + INFO("%s revision %s\n", THIS_MODULE->name, XPP_VERSION); /* register this driver with the USB subsystem */ result = usb_register(&xusb_driver); @@ -941,6 +888,7 @@ out: MODULE_DESCRIPTION("XPP USB Driver"); MODULE_AUTHOR("Oron Peled <oron@actcom.co.il>"); MODULE_LICENSE("GPL"); +MODULE_VERSION(XPP_VERSION); module_init(xpp_usb_init); module_exit(xpp_usb_cleanup); |