1127 lines
36 KiB
Diff
Executable File
1127 lines
36 KiB
Diff
Executable File
--- ref/drivers/atm/ambassador.c Thu Jul 6 19:11:52 2000
|
|
+++ work/drivers/atm/ambassador.c Thu Jul 6 18:38:29 2000
|
|
@@ -373,15 +373,15 @@
|
|
static inline void dump_registers (const amb_dev * dev) {
|
|
#ifdef DEBUG_AMBASSADOR
|
|
if (debug & DBG_REGS) {
|
|
- u32 * i;
|
|
+ size_t i;
|
|
PRINTD (DBG_REGS, "reading PLX control: ");
|
|
- for (i = (u32 *) 0x00; i < (u32 *) 0x30; ++i)
|
|
+ for (i = 0x00; i < 0x30; i += sizeof(u32))
|
|
rd_mem (dev, i);
|
|
PRINTD (DBG_REGS, "reading mailboxes: ");
|
|
- for (i = (u32 *) 0x40; i < (u32 *) 0x60; ++i)
|
|
+ for (i = 0x40; i < 0x60; i += sizeof(u32))
|
|
rd_mem (dev, i);
|
|
PRINTD (DBG_REGS, "reading doorb irqev irqen reset:");
|
|
- for (i = (u32 *) 0x60; i < (u32 *) 0x70; ++i)
|
|
+ for (i = 0x60; i < 0x70; i += sizeof(u32))
|
|
rd_mem (dev, i);
|
|
}
|
|
#else
|
|
--- ref/drivers/atm/eni.c Thu Jul 6 19:11:52 2000
|
|
+++ work/drivers/atm/eni.c Thu Jul 6 18:38:51 2000
|
|
@@ -1187,14 +1187,12 @@
|
|
if (tx->send)
|
|
while ((skb = skb_dequeue(&tx->backlog))) {
|
|
res = do_tx(skb);
|
|
- if (res == enq_ok) atomic_dec(&tx->backlog_len);
|
|
- else {
|
|
- DPRINTK("re-queuing TX PDU\n");
|
|
- skb_queue_head(&tx->backlog,skb);
|
|
+ if (res == enq_ok) continue;
|
|
+ DPRINTK("re-queuing TX PDU\n");
|
|
+ skb_queue_head(&tx->backlog,skb);
|
|
requeued++;
|
|
- if (res == enq_jam) return;
|
|
- else break;
|
|
- }
|
|
+ if (res == enq_jam) return;
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
@@ -1326,7 +1324,6 @@
|
|
tx->send = mem;
|
|
tx->words = size >> 2;
|
|
skb_queue_head_init(&tx->backlog);
|
|
- atomic_set(&tx->backlog_len,0);
|
|
for (order = 0; size > (1 << (order+10)); order++);
|
|
eni_out((order << MID_SIZE_SHIFT) |
|
|
((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)),
|
|
@@ -2064,6 +2061,8 @@
|
|
|
|
static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
|
|
{
|
|
+ enum enq_res res;
|
|
+
|
|
DPRINTK(">eni_send\n");
|
|
if (!ENI_VCC(vcc)->tx) {
|
|
if (vcc->pop) vcc->pop(vcc,skb);
|
|
@@ -2085,8 +2084,11 @@
|
|
}
|
|
submitted++;
|
|
ATM_SKB(skb)->vcc = vcc;
|
|
+ tasklet_disable(&ENI_DEV(vcc->dev)->task);
|
|
+ res = do_tx(skb);
|
|
+ tasklet_enable(&ENI_DEV(vcc->dev)->task);
|
|
+ if (res == enq_ok) return 0;
|
|
skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb);
|
|
- atomic_inc(&ENI_VCC(vcc)->tx->backlog_len);
|
|
backlogged++;
|
|
tasklet_schedule(&ENI_DEV(vcc->dev)->task);
|
|
return 0;
|
|
@@ -2186,8 +2188,8 @@
|
|
tx == eni_dev->ubr ? " (UBR)" : "");
|
|
}
|
|
if (--left) continue;
|
|
- return sprintf(page,"%10sbacklog %d bytes\n","",
|
|
- atomic_read(&tx->backlog_len));
|
|
+ return sprintf(page,"%10sbacklog %u packets\n","",
|
|
+ skb_queue_len(&tx->backlog));
|
|
}
|
|
for (vcc = dev->vccs; vcc; vcc = vcc->next) {
|
|
struct eni_vcc *eni_vcc = ENI_VCC(vcc);
|
|
--- ref/drivers/atm/eni.h Fri Apr 14 18:37:10 2000
|
|
+++ work/drivers/atm/eni.h Thu Jul 6 18:45:07 2000
|
|
@@ -47,7 +47,6 @@
|
|
int reserved; /* reserved peak cell rate */
|
|
int shaping; /* shaped peak cell rate */
|
|
struct sk_buff_head backlog; /* queue of waiting TX buffers */
|
|
- atomic_t backlog_len; /* length of backlog in bytes */
|
|
};
|
|
|
|
struct eni_vcc {
|
|
--- ref/drivers/atm/fore200e.c Thu Jul 6 19:12:43 2000
|
|
+++ work/drivers/atm/fore200e.c Thu Jul 6 18:38:29 2000
|
|
@@ -2599,9 +2599,7 @@
|
|
|
|
printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION "\n");
|
|
|
|
-#if 0 /* XXX uncomment this to forbid module unloading */
|
|
MOD_INC_USE_COUNT;
|
|
-#endif
|
|
|
|
/* for each configured bus interface */
|
|
for (link = 0, bus = fore200e_bus; bus->model_name; bus++) {
|
|
@@ -2628,10 +2626,8 @@
|
|
}
|
|
}
|
|
|
|
-#if 0 /* XXX uncomment this to forbid module unloading */
|
|
if (link <= 0)
|
|
MOD_DEC_USE_COUNT;
|
|
-#endif
|
|
|
|
return link;
|
|
}
|
|
--- ref/drivers/atm/horizon.c Sat Apr 29 08:00:04 2000
|
|
+++ work/drivers/atm/horizon.c Thu Jul 6 18:38:29 2000
|
|
@@ -603,7 +603,8 @@
|
|
|
|
// note: rounding the rate down means rounding 'p' up
|
|
|
|
- const unsigned long br = test_bit (ultra, &dev->flags) ? BR_ULT : BR_HRZ;
|
|
+ const unsigned long br = test_bit (ultra, (hrz_flags *) &dev->flags) ?
|
|
+ BR_ULT : BR_HRZ;
|
|
|
|
u32 div = CR_MIND;
|
|
u32 pre;
|
|
--- ref/drivers/atm/idt77105.c Thu Jul 6 19:11:52 2000
|
|
+++ work/drivers/atm/idt77105.c Thu Jul 6 18:38:29 2000
|
|
@@ -48,10 +48,12 @@
|
|
static void idt77105_restart_timer_func(unsigned long);
|
|
|
|
|
|
-static struct timer_list stats_timer = { NULL, NULL, 0L, 0L,
|
|
- &idt77105_stats_timer_func };
|
|
-static struct timer_list restart_timer = { NULL, NULL, 0L, 0L,
|
|
- &idt77105_restart_timer_func };
|
|
+static struct timer_list stats_timer = {
|
|
+ function: &idt77105_stats_timer_func
|
|
+};
|
|
+static struct timer_list restart_timer = {
|
|
+ function: &idt77105_restart_timer_func
|
|
+};
|
|
static int start_timer = 1;
|
|
static struct idt77105_priv *idt77105_all = NULL;
|
|
|
|
--- ref/drivers/atm/iphase.c Thu Jul 6 19:11:52 2000
|
|
+++ work/drivers/atm/iphase.c Thu Jul 6 18:38:29 2000
|
|
@@ -2303,7 +2303,7 @@
|
|
dev->number,error);
|
|
return -EINVAL;
|
|
}
|
|
- IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%x,irq=%d\n",
|
|
+ IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%lx,irq=%d\n",
|
|
dev->number, revision, real_base, iadev->irq);)
|
|
|
|
/* find mapping size of board */
|
|
@@ -2342,7 +2342,7 @@
|
|
dev->number);
|
|
return error;
|
|
}
|
|
- IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=0x%x,irq=%d\n",
|
|
+ IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=0x%lx,irq=%d\n",
|
|
dev->number, revision, base, iadev->irq);)
|
|
|
|
/* filling the iphase dev structure */
|
|
--- ref/drivers/atm/nicstar.c Thu Jul 6 19:11:52 2000
|
|
+++ work/drivers/atm/nicstar.c Thu Jul 6 18:38:29 2000
|
|
@@ -21,6 +21,18 @@
|
|
******************************************************************************/
|
|
|
|
|
|
+/**** IMPORTANT INFORMATION ***************************************************
|
|
+ *
|
|
+ * There are currently three types of spinlocks:
|
|
+ *
|
|
+ * 1 - Per card interrupt spinlock (to protect structures and such)
|
|
+ * 2 - Per SCQ scq spinlock
|
|
+ * 3 - Per card resource spinlock (to access registers, etc.)
|
|
+ *
|
|
+ * These must NEVER be grabbed in reverse order.
|
|
+ *
|
|
+ ******************************************************************************/
|
|
+
|
|
/* Header files ***************************************************************/
|
|
|
|
#include <linux/module.h>
|
|
@@ -115,6 +127,85 @@
|
|
#define ATM_SKB(s) (&(s)->atm)
|
|
#endif
|
|
|
|
+ /* Spinlock debugging stuff */
|
|
+#ifdef NS_DEBUG_SPINLOCKS /* See nicstar.h */
|
|
+#define ns_grab_int_lock(card,flags) \
|
|
+ do { \
|
|
+ unsigned long nsdsf, nsdsf2; \
|
|
+ local_irq_save(flags); \
|
|
+ save_flags(nsdsf); cli();\
|
|
+ if (nsdsf & (1<<9)) printk ("nicstar.c: ints %sabled -> enabled.\n", \
|
|
+ (flags)&(1<<9)?"en":"dis"); \
|
|
+ if (spin_is_locked(&(card)->int_lock) && \
|
|
+ (card)->cpu_int == smp_processor_id()) { \
|
|
+ printk("nicstar.c: line %d (cpu %d) int_lock already locked at line %d (cpu %d)\n", \
|
|
+ __LINE__, smp_processor_id(), (card)->has_int_lock, \
|
|
+ (card)->cpu_int); \
|
|
+ printk("nicstar.c: ints were %sabled.\n", ((flags)&(1<<9)?"en":"dis")); \
|
|
+ } \
|
|
+ if (spin_is_locked(&(card)->res_lock) && \
|
|
+ (card)->cpu_res == smp_processor_id()) { \
|
|
+ printk("nicstar.c: line %d (cpu %d) res_lock locked at line %d (cpu %d)(trying int)\n", \
|
|
+ __LINE__, smp_processor_id(), (card)->has_res_lock, \
|
|
+ (card)->cpu_res); \
|
|
+ printk("nicstar.c: ints were %sabled.\n", ((flags)&(1<<9)?"en":"dis")); \
|
|
+ } \
|
|
+ spin_lock_irq(&(card)->int_lock); \
|
|
+ (card)->has_int_lock = __LINE__; \
|
|
+ (card)->cpu_int = smp_processor_id(); \
|
|
+ restore_flags(nsdsf); } while (0)
|
|
+#define ns_grab_res_lock(card,flags) \
|
|
+ do { \
|
|
+ unsigned long nsdsf, nsdsf2; \
|
|
+ local_irq_save(flags); \
|
|
+ save_flags(nsdsf); cli();\
|
|
+ if (nsdsf & (1<<9)) printk ("nicstar.c: ints %sabled -> enabled.\n", \
|
|
+ (flags)&(1<<9)?"en":"dis"); \
|
|
+ if (spin_is_locked(&(card)->res_lock) && \
|
|
+ (card)->cpu_res == smp_processor_id()) { \
|
|
+ printk("nicstar.c: line %d (cpu %d) res_lock already locked at line %d (cpu %d)\n", \
|
|
+ __LINE__, smp_processor_id(), (card)->has_res_lock, \
|
|
+ (card)->cpu_res); \
|
|
+ printk("nicstar.c: ints were %sabled.\n", ((flags)&(1<<9)?"en":"dis")); \
|
|
+ } \
|
|
+ spin_lock_irq(&(card)->res_lock); \
|
|
+ (card)->has_res_lock = __LINE__; \
|
|
+ (card)->cpu_res = smp_processor_id(); \
|
|
+ restore_flags(nsdsf); } while (0)
|
|
+#define ns_grab_scq_lock(card,scq,flags) \
|
|
+ do { \
|
|
+ unsigned long nsdsf, nsdsf2; \
|
|
+ local_irq_save(flags); \
|
|
+ save_flags(nsdsf); cli();\
|
|
+ if (nsdsf & (1<<9)) printk ("nicstar.c: ints %sabled -> enabled.\n", \
|
|
+ (flags)&(1<<9)?"en":"dis"); \
|
|
+ if (spin_is_locked(&(scq)->lock) && \
|
|
+ (scq)->cpu_lock == smp_processor_id()) { \
|
|
+ printk("nicstar.c: line %d (cpu %d) this scq_lock already locked at line %d (cpu %d)\n", \
|
|
+ __LINE__, smp_processor_id(), (scq)->has_lock, \
|
|
+ (scq)->cpu_lock); \
|
|
+ printk("nicstar.c: ints were %sabled.\n", ((flags)&(1<<9)?"en":"dis")); \
|
|
+ } \
|
|
+ if (spin_is_locked(&(card)->res_lock) && \
|
|
+ (card)->cpu_res == smp_processor_id()) { \
|
|
+ printk("nicstar.c: line %d (cpu %d) res_lock locked at line %d (cpu %d)(trying scq)\n", \
|
|
+ __LINE__, smp_processor_id(), (card)->has_res_lock, \
|
|
+ (card)->cpu_res); \
|
|
+ printk("nicstar.c: ints were %sabled.\n", ((flags)&(1<<9)?"en":"dis")); \
|
|
+ } \
|
|
+ spin_lock_irq(&(scq)->lock); \
|
|
+ (scq)->has_lock = __LINE__; \
|
|
+ (scq)->cpu_lock = smp_processor_id(); \
|
|
+ restore_flags(nsdsf); } while (0)
|
|
+#else /* !NS_DEBUG_SPINLOCKS */
|
|
+#define ns_grab_int_lock(card,flags) \
|
|
+ spin_lock_irqsave(&(card)->int_lock,(flags))
|
|
+#define ns_grab_res_lock(card,flags) \
|
|
+ spin_lock_irqsave(&(card)->res_lock,(flags))
|
|
+#define ns_grab_scq_lock(card,scq,flags) \
|
|
+ spin_lock_irqsave(&(scq)->lock,flags)
|
|
+#endif /* NS_DEBUG_SPINLOCKS */
|
|
+
|
|
|
|
/* Version definition *********************************************************/
|
|
/*
|
|
@@ -406,12 +497,12 @@
|
|
sram_address <<= 2;
|
|
sram_address &= 0x0007FFFC; /* address must be dword aligned */
|
|
sram_address |= 0x50000000; /* SRAM read command */
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
while (CMD_BUSY(card));
|
|
writel(sram_address, card->membase + CMD);
|
|
while (CMD_BUSY(card));
|
|
data = readl(card->membase + DR0);
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
return data;
|
|
}
|
|
|
|
@@ -424,7 +515,7 @@
|
|
count--; /* count range now is 0..3 instead of 1..4 */
|
|
c = count;
|
|
c <<= 2; /* to use increments of 4 */
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
while (CMD_BUSY(card));
|
|
for (i = 0; i <= c; i += 4)
|
|
writel(*(value++), card->membase + i);
|
|
@@ -434,14 +525,14 @@
|
|
sram_address &= 0x0007FFFC;
|
|
sram_address |= (0x40000000 | count);
|
|
writel(sram_address, card->membase + CMD);
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
}
|
|
|
|
|
|
static int ns_init_card(int i, struct pci_dev *pcidev)
|
|
{
|
|
int j;
|
|
- struct ns_dev *card;
|
|
+ struct ns_dev *card = NULL;
|
|
unsigned short pci_command;
|
|
unsigned char pci_latency;
|
|
unsigned error;
|
|
@@ -468,6 +559,8 @@
|
|
return error;
|
|
}
|
|
cards[i] = card;
|
|
+ spin_lock_init(&card->int_lock);
|
|
+ spin_lock_init(&card->res_lock);
|
|
|
|
card->index = i;
|
|
card->atmdev = NULL;
|
|
@@ -853,9 +946,6 @@
|
|
card->iovpool.count++;
|
|
}
|
|
|
|
-
|
|
- card->in_handler = 0;
|
|
- card->in_poll = 0;
|
|
card->intcnt = 0;
|
|
|
|
/* Configure NICStAR */
|
|
@@ -1025,6 +1115,7 @@
|
|
scq->tbd_count = 0;
|
|
init_waitqueue_head(&scq->scqfull_waitq);
|
|
scq->full = 0;
|
|
+ spin_lock_init(&scq->lock);
|
|
|
|
for (i = 0; i < scq->num_entries; i++)
|
|
scq->skb[i] = NULL;
|
|
@@ -1161,7 +1252,7 @@
|
|
card->lbfqc += 2;
|
|
}
|
|
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
|
|
while (CMD_BUSY(card));
|
|
writel(addr2, card->membase + DR3);
|
|
@@ -1170,7 +1261,7 @@
|
|
writel(handle1, card->membase + DR0);
|
|
writel(NS_CMD_WRITE_FREEBUFQ | (u32) type, card->membase + CMD);
|
|
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
|
|
XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index,
|
|
(type == BUF_SM ? "small" : "large"), addr1, addr2);
|
|
@@ -1193,6 +1284,7 @@
|
|
u32 stat_r;
|
|
ns_dev *card;
|
|
struct atm_dev *dev;
|
|
+ unsigned long flags;
|
|
|
|
card = (ns_dev *) dev_id;
|
|
dev = card->atmdev;
|
|
@@ -1200,19 +1292,7 @@
|
|
|
|
PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index);
|
|
|
|
- if (card->in_handler)
|
|
- {
|
|
- printk("nicstar%d: Re-entering ns_irq_handler()???\n", card->index);
|
|
- return;
|
|
- }
|
|
- card->in_handler = 1;
|
|
- if (card->in_poll)
|
|
- {
|
|
- card->in_handler = 0;
|
|
- printk("nicstar%d: Called irq handler while in ns_poll()!?\n",
|
|
- card->index);
|
|
- return;
|
|
- }
|
|
+ ns_grab_int_lock(card, flags);
|
|
|
|
stat_r = readl(card->membase + STAT);
|
|
|
|
@@ -1377,7 +1457,7 @@
|
|
process_rsq(card);
|
|
}
|
|
|
|
- card->in_handler = 0;
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
PRINTK("nicstar%d: end of interrupt service\n", card->index);
|
|
}
|
|
|
|
@@ -1595,10 +1675,10 @@
|
|
unsigned long flags;
|
|
|
|
addr = NS_RCT + (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
while(CMD_BUSY(card));
|
|
writel(NS_CMD_CLOSE_CONNECTION | addr << 2, card->membase + CMD);
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
|
|
vc->rx = 0;
|
|
if (vc->rx_iov != NULL)
|
|
@@ -1617,9 +1697,9 @@
|
|
ATM_SKB(iovb)->iovcnt);
|
|
ATM_SKB(iovb)->iovcnt = 0;
|
|
ATM_SKB(iovb)->vcc = NULL;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_int_lock(card, flags);
|
|
recycle_iov_buf(card, iovb);
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
vc->rx_iov = NULL;
|
|
}
|
|
}
|
|
@@ -1639,7 +1719,7 @@
|
|
|
|
for (;;)
|
|
{
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_scq_lock(card, scq, flags);
|
|
scqep = scq->next;
|
|
if (scqep == scq->base)
|
|
scqep = scq->last;
|
|
@@ -1647,7 +1727,7 @@
|
|
scqep--;
|
|
if (scqep == scq->tail)
|
|
{
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
break;
|
|
}
|
|
/* If the last entry is not a TSR, place one in the SCQ in order to
|
|
@@ -1675,8 +1755,8 @@
|
|
data = (u32) virt_to_bus(scq->next);
|
|
ns_write_sram(card, scq->scd, &data, 1);
|
|
}
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
schedule();
|
|
- restore_flags(flags);
|
|
}
|
|
|
|
/* Free all TST entries */
|
|
@@ -1884,19 +1964,22 @@
|
|
u32 data;
|
|
int index;
|
|
|
|
- if (scq->tail == scq->next)
|
|
+ ns_grab_scq_lock(card, scq, flags);
|
|
+ while (scq->tail == scq->next)
|
|
{
|
|
if (in_interrupt()) {
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
printk("nicstar%d: Error pushing TBD.\n", card->index);
|
|
return 1;
|
|
}
|
|
|
|
- save_flags(flags); cli();
|
|
scq->full = 1;
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
interruptible_sleep_on_timeout(&scq->scqfull_waitq, SCQFULL_TIMEOUT);
|
|
- restore_flags(flags);
|
|
+ ns_grab_scq_lock(card, scq, flags);
|
|
|
|
if (scq->full) {
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
printk("nicstar%d: Timeout pushing TBD.\n", card->index);
|
|
return 1;
|
|
}
|
|
@@ -1926,19 +2009,23 @@
|
|
|
|
if (vc->tbd_count >= MAX_TBD_PER_VC || scq->tbd_count >= MAX_TBD_PER_SCQ)
|
|
{
|
|
- if (scq->tail == scq->next)
|
|
+ int has_run = 0;
|
|
+
|
|
+ while (scq->tail == scq->next)
|
|
{
|
|
if (in_interrupt()) {
|
|
data = (u32) virt_to_bus(scq->next);
|
|
ns_write_sram(card, scq->scd, &data, 1);
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
printk("nicstar%d: Error pushing TSR.\n", card->index);
|
|
return 0;
|
|
}
|
|
|
|
- save_flags(flags); cli();
|
|
scq->full = 1;
|
|
+ if (has_run++) break;
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
interruptible_sleep_on_timeout(&scq->scqfull_waitq, SCQFULL_TIMEOUT);
|
|
- restore_flags(flags);
|
|
+ ns_grab_scq_lock(card, scq, flags);
|
|
}
|
|
|
|
if (!scq->full)
|
|
@@ -1970,10 +2057,11 @@
|
|
else
|
|
PRINTK("nicstar%d: Timeout pushing TSR.\n", card->index);
|
|
}
|
|
-
|
|
data = (u32) virt_to_bus(scq->next);
|
|
ns_write_sram(card, scq->scd, &data, 1);
|
|
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -2064,6 +2152,7 @@
|
|
struct atm_vcc *vcc;
|
|
struct sk_buff *skb;
|
|
int i;
|
|
+ unsigned long flags;
|
|
|
|
XPRINTK("nicstar%d: drain_scq() called, scq at 0x%x, pos %d.\n",
|
|
card->index, (u32) scq, pos);
|
|
@@ -2073,6 +2162,7 @@
|
|
return;
|
|
}
|
|
|
|
+ ns_grab_scq_lock(card, scq, flags);
|
|
i = (int) (scq->tail - scq->base);
|
|
if (++i == scq->num_entries)
|
|
i = 0;
|
|
@@ -2084,16 +2174,18 @@
|
|
if (skb != NULL)
|
|
{
|
|
vcc = ATM_SKB(skb)->vcc;
|
|
- if (vcc->pop != NULL)
|
|
+ if (vcc->pop != NULL) {
|
|
vcc->pop(vcc, skb);
|
|
- else
|
|
- dev_kfree_skb_any(skb);
|
|
+ } else {
|
|
+ dev_kfree_skb_irq(skb);
|
|
+ }
|
|
scq->skb[i] = NULL;
|
|
}
|
|
if (++i == scq->num_entries)
|
|
i = 0;
|
|
}
|
|
scq->tail = scq->base + pos;
|
|
+ spin_unlock_irqrestore(&scq->lock, flags);
|
|
}
|
|
|
|
|
|
@@ -2890,10 +2982,10 @@
|
|
{
|
|
struct sk_buff *hb;
|
|
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_int_lock(card, flags);
|
|
hb = skb_dequeue(&card->hbpool.queue);
|
|
card->hbpool.count--;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
if (hb == NULL)
|
|
printk("nicstar%d: huge buffer count inconsistent.\n",
|
|
card->index);
|
|
@@ -2908,10 +3000,10 @@
|
|
hb = alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
|
|
if (hb == NULL)
|
|
return -ENOMEM;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_int_lock(card, flags);
|
|
skb_queue_tail(&card->hbpool.queue, hb);
|
|
card->hbpool.count++;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
}
|
|
break;
|
|
|
|
@@ -2920,10 +3012,10 @@
|
|
{
|
|
struct sk_buff *iovb;
|
|
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_int_lock(card, flags);
|
|
iovb = skb_dequeue(&card->iovpool.queue);
|
|
card->iovpool.count--;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
if (iovb == NULL)
|
|
printk("nicstar%d: iovec buffer count inconsistent.\n",
|
|
card->index);
|
|
@@ -2938,10 +3030,10 @@
|
|
iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
|
|
if (iovb == NULL)
|
|
return -ENOMEM;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_int_lock(card, flags);
|
|
skb_queue_tail(&card->iovpool.queue, iovb);
|
|
card->iovpool.count++;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
}
|
|
break;
|
|
|
|
@@ -2986,22 +3078,11 @@
|
|
for (i = 0; i < num_cards; i++)
|
|
{
|
|
card = cards[i];
|
|
- save_flags(flags); cli();
|
|
- if (card->in_poll)
|
|
- {
|
|
- printk("nicstar: Re-entering ns_poll()???\n");
|
|
- restore_flags(flags);
|
|
- continue;
|
|
- }
|
|
- card->in_poll = 1;
|
|
- if (card->in_handler)
|
|
- {
|
|
- card->in_poll = 0;
|
|
- printk("nicstar%d: ns_poll called while in interrupt handler!?\n",
|
|
- card->index);
|
|
- restore_flags(flags);
|
|
+ if (spin_is_locked(&card->int_lock)) {
|
|
+ /* Probably it isn't worth spinning */
|
|
continue;
|
|
}
|
|
+ ns_grab_int_lock(card, flags);
|
|
|
|
stat_w = 0;
|
|
stat_r = readl(card->membase + STAT);
|
|
@@ -3014,8 +3095,7 @@
|
|
process_rsq(card);
|
|
|
|
writel(stat_w, card->membase + STAT);
|
|
- card->in_poll = 0;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->int_lock, flags);
|
|
}
|
|
mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD);
|
|
PRINTK("nicstar: Leaving ns_poll().\n");
|
|
@@ -3069,12 +3149,12 @@
|
|
unsigned long flags;
|
|
|
|
card = dev->dev_data;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
while(CMD_BUSY(card));
|
|
writel((unsigned long) value, card->membase + DR0);
|
|
writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF),
|
|
card->membase + CMD);
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
}
|
|
|
|
|
|
@@ -3086,12 +3166,12 @@
|
|
unsigned long data;
|
|
|
|
card = dev->dev_data;
|
|
- save_flags(flags); cli();
|
|
+ ns_grab_res_lock(card, flags);
|
|
while(CMD_BUSY(card));
|
|
writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF),
|
|
card->membase + CMD);
|
|
while(CMD_BUSY(card));
|
|
data = readl(card->membase + DR0) & 0x000000FF;
|
|
- restore_flags(flags);
|
|
+ spin_unlock_irqrestore(&card->res_lock, flags);
|
|
return (unsigned char) data;
|
|
}
|
|
--- ref/drivers/atm/nicstar.h Wed Mar 22 08:38:26 2000
|
|
+++ work/drivers/atm/nicstar.h Thu Jul 6 18:45:17 2000
|
|
@@ -28,6 +28,8 @@
|
|
|
|
/* Options ********************************************************************/
|
|
|
|
+#undef NS_DEBUG_SPINLOCKS
|
|
+
|
|
#define NS_MAX_CARDS 4 /* Maximum number of NICStAR based cards
|
|
controlled by the device driver. Must
|
|
be <= 5 */
|
|
@@ -705,6 +707,11 @@
|
|
int tbd_count; /* Only meaningful on variable rate */
|
|
wait_queue_head_t scqfull_waitq;
|
|
volatile char full; /* SCQ full indicator */
|
|
+ spinlock_t lock; /* SCQ spinlock */
|
|
+#ifdef NS_DEBUG_SPINLOCKS
|
|
+ volatile long has_lock;
|
|
+ volatile int cpu_lock;
|
|
+#endif /* NS_DEBUG_SPINLOCKS */
|
|
} scq_info;
|
|
|
|
|
|
@@ -779,8 +786,14 @@
|
|
struct sk_buff *rcbuf; /* Current raw cell buffer */
|
|
u32 rawch; /* Raw cell queue head */
|
|
unsigned intcnt; /* Interrupt counter */
|
|
- volatile int in_handler: 1;
|
|
- volatile int in_poll: 1;
|
|
+ spinlock_t int_lock; /* Interrupt lock */
|
|
+ spinlock_t res_lock; /* Card resource lock */
|
|
+#ifdef NS_DEBUG_SPINLOCKS
|
|
+ volatile long has_int_lock;
|
|
+ volatile int cpu_int;
|
|
+ volatile long has_res_lock;
|
|
+ volatile int cpu_res;
|
|
+#endif /* NS_DEBUG_SPINLOCKS */
|
|
} ns_dev;
|
|
|
|
|
|
--- ref/net/atm/Makefile Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/Makefile Thu Jul 6 18:38:29 2000
|
|
@@ -25,7 +25,7 @@
|
|
NEED_IPCOM = ipcommon.o
|
|
endif
|
|
|
|
-O_OBJS += $(NEED_IPCOM)
|
|
+OX_OBJS += $(NEED_IPCOM)
|
|
|
|
ifeq ($(CONFIG_PROC_FS),y)
|
|
OX_OBJS += proc.o
|
|
--- ref/net/atm/clip.c Tue May 2 21:41:00 2000
|
|
+++ work/net/atm/clip.c Thu Jul 6 18:38:29 2000
|
|
@@ -274,14 +274,14 @@
|
|
|
|
|
|
static struct neigh_ops clip_neigh_ops = {
|
|
- AF_INET, /* family */
|
|
- clip_neigh_destroy, /* destructor */
|
|
- clip_neigh_solicit, /* solicit */
|
|
- clip_neigh_error, /* error_report */
|
|
- dev_queue_xmit, /* output */
|
|
- dev_queue_xmit, /* connected_output */
|
|
- dev_queue_xmit, /* hh_output */
|
|
- dev_queue_xmit /* queue_xmit */
|
|
+ family: AF_INET,
|
|
+ destructor: clip_neigh_destroy,
|
|
+ solicit: clip_neigh_solicit,
|
|
+ error_report: clip_neigh_error,
|
|
+ output: dev_queue_xmit,
|
|
+ connected_output: dev_queue_xmit,
|
|
+ hh_output: dev_queue_xmit,
|
|
+ queue_xmit: dev_queue_xmit,
|
|
};
|
|
|
|
|
|
@@ -384,6 +384,7 @@
|
|
if (!skb->dst) {
|
|
printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
|
|
dev_kfree_skb(skb);
|
|
+ clip_priv->stats.tx_dropped++;
|
|
return 0;
|
|
}
|
|
if (!skb->dst->neighbour) {
|
|
@@ -395,8 +396,10 @@
|
|
return 0;
|
|
}
|
|
#endif
|
|
-printk("clip_start_xmit: NO NEIGHBOUR !\n");
|
|
-return 0;
|
|
+ printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n");
|
|
+ dev_kfree_skb(skb);
|
|
+ clip_priv->stats.tx_dropped++;
|
|
+ return 0;
|
|
}
|
|
entry = NEIGH2ENTRY(skb->dst->neighbour);
|
|
if (!entry->vccs) {
|
|
@@ -440,7 +443,6 @@
|
|
entry->vccs->xoff = 0;
|
|
return 0;
|
|
}
|
|
- if (old) return 0;
|
|
spin_lock_irqsave(&clip_priv->xoff_lock,flags);
|
|
netif_stop_queue(dev); /* XOFF -> throttle immediately */
|
|
barrier();
|
|
@@ -482,6 +484,7 @@
|
|
clip_vcc->old_pop = vcc->pop;
|
|
vcc->push = clip_push;
|
|
vcc->pop = clip_pop;
|
|
+ skb_queue_head_init(©);
|
|
skb_migrate(&vcc->recvq,©);
|
|
/* re-process everything received between connection setup and MKIP */
|
|
while ((skb = skb_dequeue(©)))
|
|
@@ -622,7 +625,7 @@
|
|
DPRINTK("clip_device_event NETDEV_UP\n");
|
|
(void) to_atmarpd(act_up,PRIV(dev)->number,0);
|
|
break;
|
|
- case NETDEV_DOWN:
|
|
+ case NETDEV_GOING_DOWN:
|
|
DPRINTK("clip_device_event NETDEV_DOWN\n");
|
|
(void) to_atmarpd(act_down,PRIV(dev)->number,0);
|
|
break;
|
|
@@ -633,6 +636,7 @@
|
|
break;
|
|
case NETDEV_REBOOT:
|
|
case NETDEV_REGISTER:
|
|
+ case NETDEV_DOWN:
|
|
DPRINTK("clip_device_event %ld\n",event);
|
|
/* ignore */
|
|
break;
|
|
--- ref/net/atm/common.c Fri Apr 14 18:37:20 2000
|
|
+++ work/net/atm/common.c Thu Jul 6 18:38:29 2000
|
|
@@ -105,6 +105,7 @@
|
|
vcc->callback = NULL;
|
|
memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
|
|
memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
|
|
+ vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
|
|
atomic_set(&vcc->tx_inuse,0);
|
|
atomic_set(&vcc->rx_inuse,0);
|
|
vcc->push = NULL;
|
|
@@ -116,6 +117,7 @@
|
|
init_waitqueue_head(&vcc->sleep);
|
|
skb_queue_head_init(&vcc->recvq);
|
|
skb_queue_head_init(&vcc->listenq);
|
|
+ sk->sleep = &vcc->sleep;
|
|
sock->sk = sk;
|
|
return 0;
|
|
}
|
|
@@ -409,6 +411,7 @@
|
|
return vcc->reply;
|
|
if (!test_bit(ATM_VF_READY,&vcc->flags)) return -EPIPE;
|
|
if (!size) return 0;
|
|
+ if (size < 0 || size > vcc->qos.txtp.max_sdu) return -EMSGSIZE;
|
|
/* verify_area is done by net/socket.c */
|
|
eff = (size+3) & ~3; /* align to word boundary */
|
|
add_wait_queue(&vcc->sleep,&wait);
|
|
@@ -750,8 +753,10 @@
|
|
}
|
|
|
|
|
|
-int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
|
|
+static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
|
|
{
|
|
+ int error;
|
|
+
|
|
/*
|
|
* Don't let the QoS change the already connected AAL type nor the
|
|
* traffic class.
|
|
@@ -760,6 +765,9 @@
|
|
qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
|
|
qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
|
|
return -EINVAL;
|
|
+ error = adjust_tp(&qos->txtp,qos->aal);
|
|
+ if (!error) error = adjust_tp(&qos->rxtp,qos->aal);
|
|
+ if (error) return error;
|
|
if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP;
|
|
if (vcc->family == AF_ATMPVC)
|
|
return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET);
|
|
--- ref/net/atm/common.h Fri Apr 14 18:37:20 2000
|
|
+++ work/net/atm/common.h Thu Jul 6 18:52:02 2000
|
|
@@ -26,7 +26,6 @@
|
|
|
|
int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci);
|
|
void atm_release_vcc_sk(struct sock *sk,int free_sk);
|
|
-int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos);
|
|
void atm_shutdown_dev(struct atm_dev *dev);
|
|
|
|
int atm_proc_init(void);
|
|
--- ref/net/atm/ipcommon.c Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/ipcommon.c Thu Jul 6 18:38:29 2000
|
|
@@ -3,6 +3,7 @@
|
|
/* Written 1996-2000 by Werner Almesberger, EPFL LRC/ICA */
|
|
|
|
|
|
+#include <linux/module.h>
|
|
#include <linux/string.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/netdevice.h>
|
|
@@ -31,7 +32,11 @@
|
|
|
|
|
|
/*
|
|
- * skb_migrate moves the list at FROM to TO, emptying FROM in the process.
|
|
+ * skb_migrate appends the list at "from" to "to", emptying "from" in the
|
|
+ * process. skb_migrate is atomic with respect to all other skb operations on
|
|
+ * "from" and "to". Note that it locks both lists at the same time, so beware
|
|
+ * of potential deadlocks.
|
|
+ *
|
|
* This function should live in skbuff.c or skbuff.h.
|
|
*/
|
|
|
|
@@ -40,18 +45,26 @@
|
|
{
|
|
struct sk_buff *skb;
|
|
unsigned long flags;
|
|
+ struct sk_buff *skb_from = (struct sk_buff *) from;
|
|
+ struct sk_buff *skb_to = (struct sk_buff *) to;
|
|
+ struct sk_buff *prev;
|
|
|
|
spin_lock_irqsave(&from->lock,flags);
|
|
- *to = *from;
|
|
- from->prev = (struct sk_buff *) from;
|
|
- from->next = (struct sk_buff *) from;
|
|
+ spin_lock(&to->lock);
|
|
+ prev = from->prev;
|
|
+ from->next->prev = to->prev;
|
|
+ prev->next = skb_to;
|
|
+ to->prev->next = from->next;
|
|
+ to->prev = from->prev;
|
|
+ for (skb = from->next; skb != skb_to; skb = skb->next)
|
|
+ skb->list = to;
|
|
+ to->qlen += from->qlen;
|
|
+ spin_unlock(&to->lock);
|
|
+ from->prev = skb_from;
|
|
+ from->next = skb_from;
|
|
from->qlen = 0;
|
|
spin_unlock_irqrestore(&from->lock,flags);
|
|
- spin_lock_init(&to->lock);
|
|
- for (skb = ((struct sk_buff *) to)->next;
|
|
- skb != (struct sk_buff *) from; skb = skb->next) skb->list = to;
|
|
- if (to->next == (struct sk_buff *) from)
|
|
- to->next = (struct sk_buff *) to;
|
|
- to->next->prev = (struct sk_buff *) to;
|
|
- to->prev->next = (struct sk_buff *) to;
|
|
}
|
|
+
|
|
+
|
|
+EXPORT_SYMBOL(skb_migrate);
|
|
--- ref/net/atm/ipcommon.h Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/ipcommon.h Thu Jul 6 18:52:10 2000
|
|
@@ -16,8 +16,8 @@
|
|
extern struct net_device *clip_devs;
|
|
|
|
/*
|
|
- * Moves all skbs from "from" to "to". The operation is atomic for "from", but
|
|
- * not for "to". "to" may only be accessed after skb_migrate finishes.
|
|
+ * Appends all skbs from "from" to "to". The operation is atomic with respect
|
|
+ * to all other skb operations on "from" or "to".
|
|
*/
|
|
|
|
void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to);
|
|
--- ref/net/atm/lec.c Wed May 3 10:48:03 2000
|
|
+++ work/net/atm/lec.c Thu Jul 6 18:38:29 2000
|
|
@@ -332,23 +332,33 @@
|
|
lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2],
|
|
lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]);
|
|
ATM_SKB(skb2)->vcc = send_vcc;
|
|
- atomic_add(skb2->truesize, &send_vcc->tx_inuse);
|
|
ATM_SKB(skb2)->iovcnt = 0;
|
|
ATM_SKB(skb2)->atm_options = send_vcc->atm_options;
|
|
DPRINTK("%s:sending to vpi:%d vci:%d\n", dev->name,
|
|
send_vcc->vpi, send_vcc->vci);
|
|
- priv->stats.tx_packets++;
|
|
- priv->stats.tx_bytes += skb2->len;
|
|
- send_vcc->send(send_vcc, skb2);
|
|
+ if (atm_may_send(send_vcc, skb2->len)) {
|
|
+ atomic_add(skb2->truesize, &send_vcc->tx_inuse);
|
|
+ priv->stats.tx_packets++;
|
|
+ priv->stats.tx_bytes += skb2->len;
|
|
+ send_vcc->send(send_vcc, skb2);
|
|
+ } else {
|
|
+ priv->stats.tx_dropped++;
|
|
+ dev_kfree_skb(skb2);
|
|
+ }
|
|
}
|
|
|
|
ATM_SKB(skb)->vcc = send_vcc;
|
|
- atomic_add(skb->truesize, &send_vcc->tx_inuse);
|
|
ATM_SKB(skb)->iovcnt = 0;
|
|
ATM_SKB(skb)->atm_options = send_vcc->atm_options;
|
|
- priv->stats.tx_packets++;
|
|
- priv->stats.tx_bytes += skb->len;
|
|
- send_vcc->send(send_vcc, skb);
|
|
+ if (atm_may_send(send_vcc, skb->len)) {
|
|
+ atomic_add(skb->truesize, &send_vcc->tx_inuse);
|
|
+ priv->stats.tx_packets++;
|
|
+ priv->stats.tx_bytes += skb->len;
|
|
+ send_vcc->send(send_vcc, skb);
|
|
+ } else {
|
|
+ priv->stats.tx_dropped++;
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
|
|
#if 0
|
|
/* Should we wait for card's device driver to notify us? */
|
|
--- ref/net/atm/mpc.c Fri Apr 14 18:43:49 2000
|
|
+++ work/net/atm/mpc.c Thu Jul 6 18:38:29 2000
|
|
@@ -239,7 +239,7 @@
|
|
while (qos != NULL) {
|
|
ip = (unsigned char *)&qos->ipaddr;
|
|
sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(ip));
|
|
- *len += sprintf(page + *len, "%%u.%u.%u.%u\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n",
|
|
+ *len += sprintf(page + *len, "%u.%u.%u.%u\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n",
|
|
NIPQUAD(ipaddr),
|
|
qos->qos.txtp.max_pcr, qos->qos.txtp.pcr, qos->qos.txtp.min_pcr, qos->qos.txtp.max_cdv, qos->qos.txtp.max_sdu,
|
|
qos->qos.rxtp.max_pcr, qos->qos.rxtp.pcr, qos->qos.rxtp.min_pcr, qos->qos.rxtp.max_cdv, qos->qos.rxtp.max_sdu);
|
|
--- ref/net/atm/proc.c Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/proc.c Thu Jul 6 18:38:29 2000
|
|
@@ -104,7 +104,7 @@
|
|
strcpy(buf,addr->sas_addr.pub);
|
|
len = strlen(addr->sas_addr.pub);
|
|
buf += len;
|
|
- if (*addr->sas_addr.pub) {
|
|
+ if (*addr->sas_addr.prv) {
|
|
*buf++ = '+';
|
|
len++;
|
|
}
|
|
@@ -233,9 +233,10 @@
|
|
int i;
|
|
|
|
if (!vcc->dev)
|
|
- sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%6s" : "N/A@%p%2s",
|
|
+ sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s",
|
|
vcc,"");
|
|
- else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,vcc->vci);
|
|
+ else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi,
|
|
+ vcc->vci);
|
|
here = strchr(buf,0);
|
|
here += sprintf(here,"%-10s ",vcc_state(vcc));
|
|
here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub,
|
|
@@ -376,7 +377,7 @@
|
|
int left;
|
|
|
|
if (!pos)
|
|
- return sprintf(buf,"Itf VPI VCI State Remote\n");
|
|
+ return sprintf(buf,"Itf VPI VCI State Remote\n");
|
|
left = pos-1;
|
|
for (dev = atm_devs; dev; dev = dev->next)
|
|
for (vcc = dev->vccs; vcc; vcc = vcc->next)
|
|
--- ref/net/atm/signaling.c Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/signaling.c Thu Jul 6 18:38:29 2000
|
|
@@ -158,9 +158,9 @@
|
|
}
|
|
|
|
|
|
-void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
|
|
+void sigd_enq2(struct atm_vcc *vcc,enum atmsvc_msg_type type,
|
|
struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc,
|
|
- const struct sockaddr_atmsvc *svc)
|
|
+ const struct sockaddr_atmsvc *svc,const struct atm_qos *qos,int reply)
|
|
{
|
|
struct sk_buff *skb;
|
|
struct atmsvc_msg *msg;
|
|
@@ -173,18 +173,23 @@
|
|
msg->type = type;
|
|
*(struct atm_vcc **) &msg->vcc = vcc;
|
|
*(struct atm_vcc **) &msg->listen_vcc = listen_vcc;
|
|
- msg->reply = 0; /* other ISP applications may use this field */
|
|
- if (vcc) {
|
|
- msg->qos = vcc->qos;
|
|
- msg->sap = vcc->sap;
|
|
- }
|
|
- if (!svc) msg->svc.sas_family = 0;
|
|
- else msg->svc = *svc;
|
|
+ msg->reply = reply;
|
|
+ if (qos) msg->qos = *qos;
|
|
+ if (vcc) msg->sap = vcc->sap;
|
|
+ if (svc) msg->svc = *svc;
|
|
if (vcc) msg->local = vcc->local;
|
|
- if (!pvc) memset(&msg->pvc,0,sizeof(msg->pvc));
|
|
- else msg->pvc = *pvc;
|
|
+ if (pvc) msg->pvc = *pvc;
|
|
sigd_put_skb(skb);
|
|
if (vcc) set_bit(ATM_VF_REGIS,&vcc->flags);
|
|
+}
|
|
+
|
|
+
|
|
+void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
|
|
+ struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc,
|
|
+ const struct sockaddr_atmsvc *svc)
|
|
+{
|
|
+ sigd_enq2(vcc,type,listen_vcc,pvc,svc,vcc ? &vcc->qos : NULL,0);
|
|
+ /* other ISP applications may use "reply" */
|
|
}
|
|
|
|
|
|
--- ref/net/atm/signaling.h Wed Mar 22 08:38:26 2000
|
|
+++ work/net/atm/signaling.h Thu Jul 6 18:52:02 2000
|
|
@@ -17,6 +17,14 @@
|
|
extern struct atm_vcc *sigd; /* needed in svc_release */
|
|
|
|
|
|
+/*
|
|
+ * sigd_enq is a wrapper for sigd_enq2, covering the more common cases, and
|
|
+ * avoiding huge lists of null values.
|
|
+ */
|
|
+
|
|
+void sigd_enq2(struct atm_vcc *vcc,enum atmsvc_msg_type type,
|
|
+ struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc,
|
|
+ const struct sockaddr_atmsvc *svc,const struct atm_qos *qos,int reply);
|
|
void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
|
|
struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc,
|
|
const struct sockaddr_atmsvc *svc);
|
|
--- ref/net/atm/svc.c Mon Apr 24 22:43:04 2000
|
|
+++ work/net/atm/svc.c Thu Jul 6 18:38:29 2000
|
|
@@ -77,8 +77,7 @@
|
|
as_indicate has been answered */
|
|
while ((skb = skb_dequeue(&vcc->listenq))) {
|
|
DPRINTK("LISTEN REL\n");
|
|
- sigd_enq(NULL,as_reject,vcc,NULL,NULL); /* @@@ should include
|
|
- the reason */
|
|
+ sigd_enq2(NULL,as_reject,vcc,NULL,NULL,&vcc->qos,0);
|
|
dev_kfree_skb(skb);
|
|
}
|
|
clear_bit(ATM_VF_REGIS,&vcc->flags);
|
|
@@ -310,8 +309,8 @@
|
|
dev_kfree_skb(skb);
|
|
old_vcc->backlog_quota++;
|
|
if (error) {
|
|
- sigd_enq(NULL,as_reject,old_vcc,NULL,NULL);
|
|
- /* @@@ should include the reason */
|
|
+ sigd_enq2(NULL,as_reject,old_vcc,NULL,NULL,
|
|
+ &old_vcc->qos,error);
|
|
return error == -EAGAIN ? -EBUSY : error;
|
|
}
|
|
/* wait should be short, so we ignore the non-blocking flag */
|
|
@@ -348,13 +347,9 @@
|
|
int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
|
|
{
|
|
DECLARE_WAITQUEUE(wait,current);
|
|
- struct atm_qos save_qos;
|
|
|
|
vcc->reply = WAITING;
|
|
- save_qos = vcc->qos; /* @@@ really gross hack ... */
|
|
- vcc->qos = *qos;
|
|
- sigd_enq(vcc,as_modify,NULL,NULL,&vcc->local);
|
|
- vcc->qos = save_qos;
|
|
+ sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
|
|
add_wait_queue(&vcc->sleep,&wait);
|
|
while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
|
|
&& sigd) {
|