summaryrefslogtreecommitdiff
path: root/xpp/card_global.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/card_global.c')
-rw-r--r--xpp/card_global.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/xpp/card_global.c b/xpp/card_global.c
index 8b73f6e..dda4480 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -1,6 +1,6 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2004-2005, Xorcom
+ * Copyright (C) 2004-2006, Xorcom
*
* All rights reserved.
*
@@ -24,6 +24,7 @@
#include "xpd.h"
#include "xpp_zap.h"
#include "xproto.h"
+#include "zap_debug.h"
#include <linux/module.h>
static const char rcsid[] = "$Id$";
@@ -61,13 +62,10 @@ static void global_packet_dump(xpacket_t *pack);
byte *pcm;
byte *start_pcm;
int i;
- extern ulong pcm_gen;
BUG_ON(!xbus);
BUG_ON(!xpd);
- lines &= xpd->enabled_chans;
- if(pcm_gen != 0)
- return 0;
+ lines &= ~xpd->no_pcm;
// if(lines == 0)
// return 0;
@@ -81,7 +79,7 @@ static void global_packet_dump(xpacket_t *pack);
XPACKET_NEW(pack, xbus, GLOBAL, PCM_WRITE, xpd->id);
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
start_pcm = pcm = RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, pcm);
- for(i = 0; i < CHANNELS_PERXPD; i++) {
+ for_each_line(xpd, i) {
if(IS_SET(lines, i)) {
memcpy(pcm, (byte *)buf, ZT_CHUNKSIZE);
pcm += ZT_CHUNKSIZE;
@@ -116,32 +114,44 @@ static void global_packet_dump(xpacket_t *pack);
/*---------------- GLOBAL: Astribank Reply Handlers -----------------------*/
+HANDLER_DEF(GLOBAL, NULL_REPLY)
+{
+ DBG("got len=%d\n", pack->datalen);
+ return 0;
+}
+
HANDLER_DEF(GLOBAL, DEV_DESC)
{
byte rev = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, rev);
byte type = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, type);
xpp_line_t line_status = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, line_status);
- int xpd_num = XPD_NUM(pack->content.addr);
+ xpd_addr_t xpd_addr = RPACKET_FIELD(pack, GLOBAL, DEV_DESC, addr);
struct card_desc_struct *card_desc;
+ unsigned long flags;
- DBG("xpd=%d type=%d rev=%d line_status=0x%04X\n",
- xpd_num, type, rev, line_status);
+ BUG_ON(!xbus);
if((card_desc = kmalloc(sizeof(struct card_desc_struct), GFP_ATOMIC)) == NULL) {
ERR("%s: Card description allocation failed.\n", __FUNCTION__);
return -ENOMEM;
}
memset(card_desc, 0, sizeof(struct card_desc_struct));
card_desc->magic = CARD_DESC_MAGIC;
+ INIT_LIST_HEAD(&card_desc->card_list);
card_desc->xbus = xbus;
card_desc->type = type;
card_desc->rev = rev;
- card_desc->xpd_num = xpd_num;
- INIT_WORK(&card_desc->work, card_detected, card_desc);
- DBG("Queueing xpp_worker for xpd %d\n", xpd_num);
- if(!queue_work(xpp_worker, &card_desc->work)) {
- ERR("Failed to queue card description work\n");
- return -EINVAL;
- }
+ card_desc->xpd_addr = xpd_addr;
+ spin_lock_irqsave(&xbus->lock, flags);
+ DBG("xpd=%d-%d type=%d rev=%d line_status=0x%04X\n",
+ xpd_addr.unit, xpd_addr.subunit, type, rev, line_status);
+ if(type == XPD_TYPE_NOMODULE)
+ XBUS_COUNTER(xbus, DEV_DESC_EMPTY)++;
+ else
+ XBUS_COUNTER(xbus, DEV_DESC_FULL)++;
+ atomic_inc(&xbus->count_poll_answers);
+ wake_up(&xbus->wait_for_polls);
+ list_add_tail(&card_desc->card_list, &xbus->poll_results);
+ spin_unlock_irqrestore(&xbus->lock, flags);
return 0;
}
@@ -155,6 +165,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
unsigned long flags;
int i;
+ BUG_ON(!xbus);
if(!xpd) {
#if 0
int xpd_num = XPD_NUM(pack->content.addr);
@@ -177,7 +188,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
}
/* Copy PCM and put each channel in its index */
- for (i = 0; i < CHANNELS_PERXPD; i++) {
+ for_each_line(xpd, i) {
if(IS_SET(lines, i)) {
memcpy((u_char *)r, pcm, ZT_CHUNKSIZE);
//memset((u_char *)r, 0x5A, ZT_CHUNKSIZE); // DEBUG
@@ -195,12 +206,19 @@ HANDLER_DEF(GLOBAL, PCM_READ)
HANDLER_DEF(GLOBAL, SYNC_REPLY)
{
+ byte mask = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, mask);
+ bool setit = mask & 0x01;
+
+ BUG_ON(!xbus);
if(!xpd) {
int xpd_num = XPD_NUM(pack->content.addr);
NOTICE("%s: received %s for non-existing xpd: %d\n", __FUNCTION__, cmd->name, xpd_num);
return -EPROTO;
}
- DBG("SYNC_REPLY: 0x%X\n", RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, mask));
+ DBG("%s/%s: SYNC_REPLY: 0x%X %s\n", xpd->xbus->busname, xpd->xpdname,
+ mask, (setit) ? "SET SYNC MASTER" : "");
+ if(setit)
+ sync_master_is(xpd);
return 0;
}
@@ -208,6 +226,7 @@ HANDLER_DEF(GLOBAL, SYNC_REPLY)
xproto_table_t PROTO_TABLE(GLOBAL) = {
.entries = {
/* Card Opcode */
+ XENTRY( GLOBAL, NULL_REPLY ),
XENTRY( GLOBAL, DEV_DESC ),
XENTRY( GLOBAL, PCM_READ ),
XENTRY( GLOBAL, SYNC_REPLY ),
@@ -239,7 +258,7 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
BUG_ON(!pack);
BUG_ON(pack->content.opcode != XPROTO_NAME(GLOBAL, PCM_READ));
- for (i = 0; i < CHANNELS_PERXPD; i++)
+ for_each_line(xpd, i)
if(IS_SET(lines, i))
count++;
if(pack->datalen != (sizeof(xpp_line_t) + count * 8)) {