summaryrefslogtreecommitdiff
path: root/xpp/xpp_usb.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-25 10:48:33 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-25 10:48:33 +0000
commitd717b83056e5076a64c9471dd85573de409582d7 (patch)
treef46ebf64df73d8f513989d29f54e5b22b8bce2a5 /xpp/xpp_usb.c
parenta11cf4664ea4fd14478f88c9118acd0f87ad7008 (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.c138
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);