diff options
author | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-02-08 00:05:17 +0000 |
---|---|---|
committer | tzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-02-08 00:05:17 +0000 |
commit | 64c638c0fb48a9a123f91e5b7a34688447192ed4 (patch) | |
tree | 1228ee5d1d9ff90abb0b835651eb5d0c8b55f9c7 /xpp/xpp_usb.c | |
parent | 6fca4c0f3aae0b27d90bf5e2110831aab473fda0 (diff) |
Branch 1.4 is back in sync (currently: xorcom rev. 3332):
* 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.
* Reverse polarity and power denial detection.
* A short led flash at registration time.
* Add a real version of the xpp modules to them (independent of the Zaptel
version).
* Update our line status even when not registered.
* Fixed a false SIG_CHANGED when inserting or removing cable to FXO.
* Fixed compilation fixes for 2.6.20 (Bug #8982)
* A cleaner fix for the bool changes of 2.6.19 .
* Automatically detect echo_can_state_t at debug time.
* Automaitcally set XPP_DEBUGFS (depending on debugfs) at compile time.
* Bug-fixes to zaptel-helper. Moved to xpp/utils .
* Xbus protocol version: 2.4 (Zaptel 1.2.12/1.4.0 had 2.3).
XPS Init scripts renamed accordingly.
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@2123 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xpp_usb.c')
-rw-r--r-- | xpp/xpp_usb.c | 155 |
1 files changed, 55 insertions, 100 deletions
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c index c9e83a6..3325f59 100644 --- a/xpp/xpp_usb.c +++ b/xpp/xpp_usb.c @@ -48,7 +48,7 @@ static const char rcsid[] = "$Id$"; -DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */ +DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements"); /* must be before zap_debug.h */ #include "zap_debug.h" @@ -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; @@ -163,65 +158,24 @@ static int xusb_open (struct inode *inode, struct file *file); static int xusb_release (struct inode *inode, struct file *file); static void xusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs); #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#define USB_PASS_CB(u) struct urb *u, struct pt_regs *regs +#else +#define USB_PASS_CB(u) struct urb *u +#endif + static void xpp_urb_delete(struct urb *urb); static struct urb *xpp_urb_new(xusb_t *dev, enum xusb_dir dir, size_t size); -static void xpp_send_callback(struct urb *urb, struct pt_regs *regs); -static void xpp_receive_callback(struct urb *urb, struct pt_regs *regs); +static void xpp_send_callback(USB_PASS_CB(urb)); +static void xpp_receive_callback(USB_PASS_CB(urb)); static int xusb_probe (struct usb_interface *interface, const struct usb_device_id *id); 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 +187,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 +201,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 +215,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 +232,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 +251,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 +271,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 +281,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 +297,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 +465,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 +475,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 +585,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 +676,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 @@ -759,7 +715,7 @@ static void xusb_disconnect(struct usb_interface *interface) INFO("XUSB #%d now disconnected\n", minor); } -static void xpp_send_callback(struct urb *urb, struct pt_regs *regs) +static void xpp_send_callback(USB_PASS_CB(urb)) { xusb_t *xusb = (xusb_t *)urb->context; xbus_t *xbus = xusb->xbus; @@ -779,14 +735,15 @@ 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) +static void xpp_receive_callback(USB_PASS_CB(urb)) { 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 +779,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 +814,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 +895,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); |