summaryrefslogtreecommitdiff
path: root/xpp/xbus-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/xbus-core.c')
-rw-r--r--xpp/xbus-core.c87
1 files changed, 60 insertions, 27 deletions
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c
index d06356e..6daa3ff 100644
--- a/xpp/xbus-core.c
+++ b/xpp/xbus-core.c
@@ -46,7 +46,6 @@
static const char rcsid[] = "$Id$";
/* Defines */
-#define POLL_TIMEOUT (2*MAX_XPDS) /* in jiffies */
#define INITIALIZATION_TIMEOUT (60*HZ) /* in jiffies */
#define PROC_XBUSES "xbuses"
#define PROC_XBUS_SUMMARY "summary"
@@ -59,7 +58,7 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
/* Command line parameters */
extern int print_dbg;
-DEF_PARM(uint, poll_timeout, POLL_TIMEOUT, 0644, "Timeout (in jiffies) waiting for units to reply");
+DEF_PARM(uint, poll_timeout, 1000, 0644, "Timeout (in jiffies) waiting for units to reply");
static int xbus_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count, int *eof, void *data);
@@ -288,7 +287,7 @@ static void do_hexdump(const char msg[], byte *data, uint16_t len)
int print_dbg = 1;
for(i = 0; i < len; i++)
- DBG(GENERAL, "%s: %3d> %02X\n", msg, i, data[i]);
+ DBG(ANY, "%s: %3d> %02X\n", msg, i, data[i]);
}
void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe)
@@ -345,12 +344,19 @@ void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe)
if((print_dbg & DBG_PCM) && ((rate_limit % 1003) == 0))
do_print = 1;
if(do_print) {
- if(num == 1)
- XBUS_DBG(GENERAL, xbus, "%s: frame_len=%d.\n",
- msg, frame_len);
- XBUS_DBG(GENERAL, xbus, " %3d. DATALEN=%d OP=0x%02X XPD-%d%d (pos=%d)\n",
- num, XPACKET_LEN(pack), XPACKET_OP(pack),
- XPACKET_ADDR(pack).unit, XPACKET_ADDR(pack).subunit, pos);
+ if(num == 1) {
+ XBUS_DBG(ANY, xbus, "%s: frame_len=%d. %s\n",
+ msg, frame_len,
+ (XPACKET_IS_PCM(pack))
+ ? "(IS_PCM)"
+ : "");
+ }
+ XBUS_DBG(ANY, xbus, " %3d. DATALEN=%d pcm=%d slot=%d OP=0x%02X XPD-%d%d (pos=%d)\n",
+ num, XPACKET_LEN(pack),
+ XPACKET_IS_PCM(pack), XPACKET_PCMSLOT(pack),
+ XPACKET_OP(pack),
+ XPACKET_ADDR(pack).unit, XPACKET_ADDR(pack).subunit,
+ pos);
dump_packet(" ", pack, print_dbg);
}
num++;
@@ -497,7 +503,7 @@ out:
#define REV(x,y) (10 * (x) + (y))
static byte good_revs[] = {
- REV(2,8),
+ REV(2,9),
};
#undef REV
@@ -620,6 +626,7 @@ static void xbus_poll(void *data)
kfree(card_desc);
}
}
+ poller->is_polling = 0;
/*
* We set this *after* poll is finished, so wait_for_xpd_initialization can
* tell we already know how many units we have.
@@ -658,7 +665,7 @@ static void xbus_poll(void *data)
}
wake_up(&poller->wait_for_xpd_initialization);
out:
- poller->is_polling = 0;
+ poller->is_polling = 0; /* just for safety */
up_read(&xbus->in_use);
return;
}
@@ -917,6 +924,10 @@ xbus_t *xbus_new(xbus_ops_t *ops, size_t xframe_size)
xbus->min_rx_sync = INT_MAX;
xbus->num_xpds = 0;
+ /*
+ * Create poller before /proc/XBUS-?? so it already exists
+ * when somebody tries to read /proc/XBUS-??/waitfor_xpds
+ */
poller = poller_new(xbus);
if(!poller) {
ERR("Failed to allocate poller\n");
@@ -1055,9 +1066,10 @@ static int xbus_read_proc(char *page, char **start, off_t off, int count, int *e
spin_lock_irqsave(&xbus->lock, flags);
poller = xbus->poller;
- len += sprintf(page + len, "%s: CONNECTOR=%s STATUS=%s bus_type=%d\n",
+ len += sprintf(page + len, "%s: CONNECTOR=%s SERIAL=[%s] STATUS=%s bus_type=%d\n",
xbus->busname,
xbus->busdesc,
+ xbus->serialnum,
(xbus->hardware_exists) ? "connected" : "missing",
xbus->bus_type
);
@@ -1106,34 +1118,54 @@ out:
static int xbus_read_waitfor_xpds(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- int len = 0;
- unsigned long flags;
- xbus_t *xbus = data;
+ int len = 0;
+ unsigned long flags;
+ xbus_t *xbus = data;
struct xbus_poller *poller;
- int ret;
+ int ret;
if(!xbus)
goto out;
+ /* first handle special cases */
+ if(!count || off)
+ goto out;
+ /*
+ * poller is created before /proc/XBUS-??
+ * So by now it exists and initialized.
+ */
poller = xbus->poller;
- XBUS_DBG(GENERAL, xbus, "Waiting for card initialization of %d XPD's max %d seconds\n", MAX_XPDS, INITIALIZATION_TIMEOUT/HZ);
+ BUG_ON(!poller);
+ XBUS_DBG(GENERAL, xbus,
+ "Waiting for card initialization of %d XPD's max %d seconds\n",
+ atomic_read(&poller->count_xpds_to_initialize), INITIALIZATION_TIMEOUT/HZ);
/*
- * xbus_poll sets count_xpds_to_initialize only when polling is finished.
- * To prevent race conditions we test both:
- * - It is none zero -- meaning we already have the poll results.
- * - And all units have finished initialization.
+ * when polling is finished xbus_poll():
+ * - Unset poller->is_polling
+ * - Sets poller->count_xpds_to_initialize.
+ * So we wait until polling is finished (is_polling == 0) and:
+ * - No poll answers from Astribank (e.g: defective firmware).
+ * - Or no units to initialize (e.g: mini-AB with only main card).
+ * - Or we finished initializing all existing units.
+ * - Or A timeout passed.
*/
ret = wait_event_interruptible_timeout(poller->wait_for_xpd_initialization,
- atomic_read(&poller->count_poll_answers) &&
- atomic_read(&poller->count_xpds_initialized) >= atomic_read(&poller->count_xpds_to_initialize),
- INITIALIZATION_TIMEOUT);
+ !poller->is_polling && (
+ atomic_read(&poller->count_poll_answers) == 0 ||
+ atomic_read(&poller->count_xpds_to_initialize) == 0 ||
+ atomic_read(&poller->count_xpds_initialized) >=
+ atomic_read(&poller->count_xpds_to_initialize)),
+ INITIALIZATION_TIMEOUT);
if(ret == 0) {
XBUS_ERR(xbus, "Card Initialization Timeout\n");
return ret;
} else if(ret < 0) {
XBUS_ERR(xbus, "Card Initialization Interrupted %d\n", ret);
return ret;
- }
- XBUS_DBG(GENERAL, xbus, "Finished initialization of %d XPD's in %d seconds.\n", MAX_XPDS, (INITIALIZATION_TIMEOUT - ret)/HZ);
+ } else
+ XBUS_DBG(GENERAL, xbus,
+ "Finished initialization of %d XPD's in %d seconds.\n",
+ atomic_read(&poller->count_xpds_initialized),
+ (INITIALIZATION_TIMEOUT - ret)/HZ);
spin_lock_irqsave(&xbus->lock, flags);
len += sprintf(page + len, "XPDS_READY: %s: %d/%d\n",
xbus->busname,
@@ -1224,9 +1256,10 @@ static int read_proc_xbuses(char *page, char **start, off_t off, int count, int
xbus_t *xbus = xbus_of(i);
if(xbus) {
- len += sprintf(page + len, "%s: CONNECTOR=%s STATUS=%s bus_type=%d\n",
+ len += sprintf(page + len, "%s: CONNECTOR=%s SERIAL=[%s] STATUS=%s bus_type=%d\n",
xbus->busname,
xbus->busdesc,
+ xbus->serialnum,
(xbus->hardware_exists) ? "connected" : "missing",
xbus->bus_type
);