Commit 96d1d039 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Make array of drivers private to isdn_common.c

Currently, we need to provide a couple of helper functions to avoid
breaking isdn_tty with this change, as that gets cleaned up, the need
for those helpers should vanish as well.
parent 13c12068
...@@ -564,8 +564,7 @@ isdn_audio_eval_dtmf(modem_info * info) ...@@ -564,8 +564,7 @@ isdn_audio_eval_dtmf(modem_info * info)
cli(); cli();
di = isdn_slot_driver(info->isdn_slot); di = isdn_slot_driver(info->isdn_slot);
ch = isdn_slot_channel(info->isdn_slot); ch = isdn_slot_channel(info->isdn_slot);
__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); isdn_drv_queue_tail(di, ch, skb, 2);
dev->drv[di]->rcvcount[ch] += 2;
restore_flags(flags); restore_flags(flags);
/* Schedule dequeuing */ /* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched)) if ((dev->modempoll) && (info->rcvsched))
...@@ -684,8 +683,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code) ...@@ -684,8 +683,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
cli(); cli();
di = isdn_slot_driver(info->isdn_slot); di = isdn_slot_driver(info->isdn_slot);
ch = isdn_slot_channel(info->isdn_slot); ch = isdn_slot_channel(info->isdn_slot);
__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); isdn_drv_queue_tail(di, ch, skb, 2);
dev->drv[di]->rcvcount[ch] += 2;
restore_flags(flags); restore_flags(flags);
/* Schedule dequeuing */ /* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched)) if ((dev->modempoll) && (info->rcvsched))
......
...@@ -49,6 +49,69 @@ struct isdn_slot { ...@@ -49,6 +49,69 @@ struct isdn_slot {
static struct isdn_slot slot[ISDN_MAX_CHANNELS]; static struct isdn_slot slot[ISDN_MAX_CHANNELS];
/* ====================================================================== */
#define DRV_FLAG_RUNNING 1
#define DRV_FLAG_REJBUS 2
#define DRV_FLAG_LOADED 4
/* Description of hardware-level-driver */
struct isdn_driver {
unsigned long online; /* Channel Online flags */
unsigned long flags; /* Misc driver Flags */
int locks; /* Number of locks */
int channels; /* Number of channels */
wait_queue_head_t st_waitq; /* Wait-Queue for status-reads */
int maxbufsize; /* Maximum Buffersize supported*/
int stavail; /* Chars avail on Status-device*/
isdn_if *interface; /* Interface to driver */
int *rcverr; /* Error-counters for B rx */
int *rcvcount; /* Byte-counters for B rx */
#ifdef CONFIG_ISDN_AUDIO
unsigned long DLEflag; /* Insert DLE at next read */
#endif
struct sk_buff_head *rpqueue; /* Pointers to rx queue */
char msn2eaz[10][ISDN_MSNLEN]; /* MSN->EAZ */
struct fsm_inst fi;
} driver;
struct isdn_driver *drivers[ISDN_MAX_DRIVERS];
int
isdn_drv_queue_empty(int di, int ch)
{
return skb_queue_empty(&drivers[di]->rpqueue[ch]);
}
void
isdn_drv_queue_tail(int di, int ch, struct sk_buff *skb, int len)
{
__skb_queue_tail(&drivers[di]->rpqueue[ch], skb);
drivers[di]->rcvcount[ch] += len;
}
int
isdn_drv_maxbufsize(int di)
{
return drivers[di]->maxbufsize;
}
int
isdn_drv_writebuf_skb(int di, int ch, int x, struct sk_buff *skb)
{
return drivers[di]->interface->writebuf_skb(di, ch, 1, skb);
}
int
isdn_drv_hdrlen(int di)
{
return drivers[di]->interface->hl_hdrlen;
}
static int isdn_add_channels(struct isdn_driver *, int, int, int);
/* ====================================================================== */
#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE) #if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
static isdn_divert_if *divert_if; /* = NULL */ static isdn_divert_if *divert_if; /* = NULL */
#else #else
...@@ -75,7 +138,7 @@ isdn_lock_drivers(void) ...@@ -75,7 +138,7 @@ isdn_lock_drivers(void)
cmd.arg = 0; cmd.arg = 0;
cmd.command = ISDN_CMD_LOCK; cmd.command = ISDN_CMD_LOCK;
isdn_command(&cmd); isdn_command(&cmd);
dev->drv[i]->locks++; drivers[i]->locks++;
} }
} }
...@@ -92,14 +155,14 @@ isdn_unlock_drivers(void) ...@@ -92,14 +155,14 @@ isdn_unlock_drivers(void)
int i; int i;
for (i = 0; i < dev->drivers; i++) for (i = 0; i < dev->drivers; i++)
if (dev->drv[i]->locks > 0) { if (drivers[i]->locks > 0) {
isdn_ctrl cmd; isdn_ctrl cmd;
cmd.driver = i; cmd.driver = i;
cmd.arg = 0; cmd.arg = 0;
cmd.command = ISDN_CMD_UNLOCK; cmd.command = ISDN_CMD_UNLOCK;
isdn_command(&cmd); isdn_command(&cmd);
dev->drv[i]->locks--; drivers[i]->locks--;
} }
} }
...@@ -342,7 +405,7 @@ isdn_command(isdn_ctrl *cmd) ...@@ -342,7 +405,7 @@ isdn_command(isdn_ctrl *cmd)
} }
if (cmd->command == ISDN_CMD_SETL2) { if (cmd->command == ISDN_CMD_SETL2) {
unsigned long l2prot = (cmd->arg >> 8) & 255; unsigned long l2prot = (cmd->arg >> 8) & 255;
unsigned long features = (dev->drv[cmd->driver]->interface->features unsigned long features = (drivers[cmd->driver]->interface->features
>> ISDN_FEATURE_L2_SHIFT) & >> ISDN_FEATURE_L2_SHIFT) &
ISDN_FEATURE_L2_MASK; ISDN_FEATURE_L2_MASK;
unsigned long l2_feature = (1 << l2prot); unsigned long l2_feature = (1 << l2prot);
...@@ -389,7 +452,7 @@ isdn_command(isdn_ctrl *cmd) ...@@ -389,7 +452,7 @@ isdn_command(isdn_ctrl *cmd)
printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, cmd->command); printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, cmd->command);
} }
#endif #endif
return dev->drv[cmd->driver]->interface->command(cmd); return drivers[cmd->driver]->interface->command(cmd);
} }
/* /*
...@@ -441,19 +504,19 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -441,19 +504,19 @@ isdn_status_callback(isdn_ctrl * c)
break; break;
case ISDN_STAT_STAVAIL: case ISDN_STAT_STAVAIL:
spin_lock_irqsave(&stat_lock, flags); spin_lock_irqsave(&stat_lock, flags);
dev->drv[di]->stavail += c->arg; drivers[di]->stavail += c->arg;
spin_unlock_irqrestore(&stat_lock, flags); spin_unlock_irqrestore(&stat_lock, flags);
wake_up_interruptible(&dev->drv[di]->st_waitq); wake_up_interruptible(&drivers[di]->st_waitq);
break; break;
case ISDN_STAT_RUN: case ISDN_STAT_RUN:
dev->drv[di]->flags |= DRV_FLAG_RUNNING; drivers[di]->flags |= DRV_FLAG_RUNNING;
for (i = 0; i < ISDN_MAX_CHANNELS; i++) for (i = 0; i < ISDN_MAX_CHANNELS; i++)
if (slot[i].di == di) if (slot[i].di == di)
isdn_slot_all_eaz(i); isdn_slot_all_eaz(i);
set_global_features(); set_global_features();
break; break;
case ISDN_STAT_STOP: case ISDN_STAT_STOP:
dev->drv[di]->flags &= ~DRV_FLAG_RUNNING; drivers[di]->flags &= ~DRV_FLAG_RUNNING;
break; break;
case ISDN_STAT_ICALL: case ISDN_STAT_ICALL:
if (i < 0) if (i < 0)
...@@ -476,7 +539,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -476,7 +539,7 @@ isdn_status_callback(isdn_ctrl * c)
if (divert_if) if (divert_if)
if ((retval = divert_if->stat_callback(c))) if ((retval = divert_if->stat_callback(c)))
return(retval); /* processed */ return(retval); /* processed */
if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) { if ((!retval) && (drivers[di]->flags & DRV_FLAG_REJBUS)) {
/* No tty responding */ /* No tty responding */
cmd.driver = di; cmd.driver = di;
cmd.arg = c->arg; cmd.arg = c->arg;
...@@ -565,7 +628,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -565,7 +628,7 @@ isdn_status_callback(isdn_ctrl * c)
if (i < 0) if (i < 0)
return -1; return -1;
dbg_statcallb("DHUP: %d\n", i); dbg_statcallb("DHUP: %d\n", i);
dev->drv[di]->online &= ~(1 << (c->arg)); drivers[di]->online &= ~(1 << (c->arg));
isdn_info_update(); isdn_info_update();
/* Signal hangup to network-devices */ /* Signal hangup to network-devices */
if (isdn_net_stat_callback(i, c)) if (isdn_net_stat_callback(i, c))
...@@ -581,7 +644,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -581,7 +644,7 @@ isdn_status_callback(isdn_ctrl * c)
return -1; return -1;
dbg_statcallb("BCONN: %ld\n", c->arg); dbg_statcallb("BCONN: %ld\n", c->arg);
/* Signal B-channel-connect to network-devices */ /* Signal B-channel-connect to network-devices */
dev->drv[di]->online |= (1 << (c->arg)); drivers[di]->online |= (1 << (c->arg));
isdn_info_update(); isdn_info_update();
if (isdn_net_stat_callback(i, c)) if (isdn_net_stat_callback(i, c))
break; break;
...@@ -593,7 +656,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -593,7 +656,7 @@ isdn_status_callback(isdn_ctrl * c)
if (i < 0) if (i < 0)
return -1; return -1;
dbg_statcallb("BHUP: %d\n", i); dbg_statcallb("BHUP: %d\n", i);
dev->drv[di]->online &= ~(1 << (c->arg)); drivers[di]->online &= ~(1 << (c->arg));
isdn_info_update(); isdn_info_update();
/* Signal hangup to network-devices */ /* Signal hangup to network-devices */
if (isdn_net_stat_callback(i, c)) if (isdn_net_stat_callback(i, c))
...@@ -612,7 +675,7 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -612,7 +675,7 @@ isdn_status_callback(isdn_ctrl * c)
break; break;
break; break;
case ISDN_STAT_ADDCH: case ISDN_STAT_ADDCH:
if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) if (isdn_add_channels(drivers[di], di, c->arg, 1))
return -1; return -1;
isdn_info_update(); isdn_info_update();
break; break;
...@@ -633,13 +696,13 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -633,13 +696,13 @@ isdn_status_callback(isdn_ctrl * c)
restore_flags(flags); restore_flags(flags);
break; break;
case ISDN_STAT_UNLOAD: case ISDN_STAT_UNLOAD:
while (dev->drv[di]->locks > 0) { while (drivers[di]->locks > 0) {
isdn_ctrl cmd; isdn_ctrl cmd;
cmd.driver = di; cmd.driver = di;
cmd.arg = 0; cmd.arg = 0;
cmd.command = ISDN_CMD_UNLOCK; cmd.command = ISDN_CMD_UNLOCK;
isdn_command(&cmd); isdn_command(&cmd);
dev->drv[di]->locks--; drivers[di]->locks--;
} }
save_flags(flags); save_flags(flags);
cli(); cli();
...@@ -652,14 +715,14 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -652,14 +715,14 @@ isdn_status_callback(isdn_ctrl * c)
isdn_unregister_devfs(i); isdn_unregister_devfs(i);
} }
dev->drivers--; dev->drivers--;
dev->channels -= dev->drv[di]->channels; dev->channels -= drivers[di]->channels;
kfree(dev->drv[di]->rcverr); kfree(drivers[di]->rcverr);
kfree(dev->drv[di]->rcvcount); kfree(drivers[di]->rcvcount);
for (i = 0; i < dev->drv[di]->channels; i++) for (i = 0; i < drivers[di]->channels; i++)
skb_queue_purge(&dev->drv[di]->rpqueue[i]); skb_queue_purge(&drivers[di]->rpqueue[i]);
kfree(dev->drv[di]->rpqueue); kfree(drivers[di]->rpqueue);
kfree(dev->drv[di]); kfree(drivers[di]);
dev->drv[di] = NULL; drivers[di] = NULL;
dev->drvid[di][0] = '\0'; dev->drvid[di][0] = '\0';
isdn_info_update(); isdn_info_update();
set_global_features(); set_global_features();
...@@ -720,23 +783,23 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len) ...@@ -720,23 +783,23 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len)
struct sk_buff *skb; struct sk_buff *skb;
u_char *cp; u_char *cp;
if (!dev->drv[di]) if (!drivers[di])
return 0; return 0;
if (skb_queue_empty(&dev->drv[di]->rpqueue[ch])) if (skb_queue_empty(&drivers[di]->rpqueue[ch]))
return 0; return 0;
if (len > dev->drv[di]->rcvcount[ch]) if (len > drivers[di]->rcvcount[ch])
len = dev->drv[di]->rcvcount[ch]; len = drivers[di]->rcvcount[ch];
cp = buf; cp = buf;
count = 0; count = 0;
while (len) { while (len) {
if (!(skb = skb_peek(&dev->drv[di]->rpqueue[ch]))) if (!(skb = skb_peek(&drivers[di]->rpqueue[ch])))
break; break;
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
if (ISDN_AUDIO_SKB_LOCK(skb)) if (ISDN_AUDIO_SKB_LOCK(skb))
break; break;
ISDN_AUDIO_SKB_LOCK(skb) = 1; ISDN_AUDIO_SKB_LOCK(skb) = 1;
if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << ch))) { if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (drivers[di]->DLEflag & (1 << ch))) {
char *p = skb->data; char *p = skb->data;
unsigned long DLEmask = (1 << ch); unsigned long DLEmask = (1 << ch);
...@@ -744,13 +807,13 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len) ...@@ -744,13 +807,13 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len)
count_pull = count_put = 0; count_pull = count_put = 0;
while ((count_pull < skb->len) && (len > 0)) { while ((count_pull < skb->len) && (len > 0)) {
len--; len--;
if (dev->drv[di]->DLEflag & DLEmask) { if (drivers[di]->DLEflag & DLEmask) {
*cp++ = DLE; *cp++ = DLE;
dev->drv[di]->DLEflag &= ~DLEmask; drivers[di]->DLEflag &= ~DLEmask;
} else { } else {
*cp++ = *p; *cp++ = *p;
if (*p == DLE) { if (*p == DLE) {
dev->drv[di]->DLEflag |= DLEmask; drivers[di]->DLEflag |= DLEmask;
(ISDN_AUDIO_SKB_DLECOUNT(skb))--; (ISDN_AUDIO_SKB_DLECOUNT(skb))--;
} }
p++; p++;
...@@ -789,7 +852,7 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len) ...@@ -789,7 +852,7 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len)
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
ISDN_AUDIO_SKB_LOCK(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif #endif
skb = skb_dequeue(&dev->drv[di]->rpqueue[ch]); skb = skb_dequeue(&drivers[di]->rpqueue[ch]);
dev_kfree_skb(skb); dev_kfree_skb(skb);
} else { } else {
/* Not yet emptied this buff, so it /* Not yet emptied this buff, so it
...@@ -801,7 +864,7 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len) ...@@ -801,7 +864,7 @@ isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len)
ISDN_AUDIO_SKB_LOCK(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif #endif
} }
dev->drv[di]->rcvcount[ch] -= count_put; drivers[di]->rcvcount[ch] -= count_put;
} }
return count; return count;
} }
...@@ -852,8 +915,8 @@ isdn_statstr(void) ...@@ -852,8 +915,8 @@ isdn_statstr(void)
sprintf(p, "\nflags:\t"); sprintf(p, "\nflags:\t");
p = istatbuf + strlen(istatbuf); p = istatbuf + strlen(istatbuf);
for (i = 0; i < ISDN_MAX_DRIVERS; i++) { for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
if (dev->drv[i]) { if (drivers[i]) {
sprintf(p, "%ld ", dev->drv[i]->online); sprintf(p, "%ld ", drivers[i]->online);
p = istatbuf + strlen(istatbuf); p = istatbuf + strlen(istatbuf);
} else { } else {
sprintf(p, "? "); sprintf(p, "? ");
...@@ -1090,14 +1153,14 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off) ...@@ -1090,14 +1153,14 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off)
isdn_BUG(); isdn_BUG();
return -ENODEV; return -ENODEV;
} }
if (!dev->drv[drvidx]->interface->readstat) { if (!drivers[drvidx]->interface->readstat) {
isdn_BUG(); isdn_BUG();
return 0; return 0;
} }
add_wait_queue(&dev->drv[drvidx]->st_waitq, &wait); add_wait_queue(&drivers[drvidx]->st_waitq, &wait);
for (;;) { for (;;) {
spin_lock_irqsave(&stat_lock, flags); spin_lock_irqsave(&stat_lock, flags);
len = dev->drv[drvidx]->stavail; len = drivers[drvidx]->stavail;
spin_unlock_irqrestore(&stat_lock, flags); spin_unlock_irqrestore(&stat_lock, flags);
if (len > 0) if (len > 0)
break; break;
...@@ -1112,7 +1175,7 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off) ...@@ -1112,7 +1175,7 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off)
schedule(); schedule();
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->drv[drvidx]->st_waitq, &wait); remove_wait_queue(&drivers[drvidx]->st_waitq, &wait);
if (len < 0) if (len < 0)
return len; return len;
...@@ -1120,15 +1183,15 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off) ...@@ -1120,15 +1183,15 @@ isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off)
if (count > len) if (count > len)
count = len; count = len;
len = dev->drv[drvidx]->interface->readstat(buf, count, 1, drvidx, len = drivers[drvidx]->interface->readstat(buf, count, 1, drvidx,
isdn_minor2chan(minor)); isdn_minor2chan(minor));
spin_lock_irqsave(&stat_lock, flags); spin_lock_irqsave(&stat_lock, flags);
if (len) { if (len) {
dev->drv[drvidx]->stavail -= len; drivers[drvidx]->stavail -= len;
} else { } else {
isdn_BUG(); isdn_BUG();
dev->drv[drvidx]->stavail = 0; drivers[drvidx]->stavail = 0;
} }
spin_unlock_irqrestore(&stat_lock, flags); spin_unlock_irqrestore(&stat_lock, flags);
...@@ -1151,11 +1214,11 @@ isdn_ctrl_write(struct file *file, const char *buf, size_t count, loff_t *off) ...@@ -1151,11 +1214,11 @@ isdn_ctrl_write(struct file *file, const char *buf, size_t count, loff_t *off)
retval = -ENODEV; retval = -ENODEV;
goto out; goto out;
} }
if (!dev->drv[drvidx]->interface->writecmd) { if (!drivers[drvidx]->interface->writecmd) {
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
} }
retval = dev->drv[drvidx]->interface-> retval = drivers[drvidx]->interface->
writecmd(buf, count, 1, drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL)); writecmd(buf, count, 1, drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL));
out: out:
...@@ -1174,9 +1237,9 @@ isdn_ctrl_poll(struct file *file, poll_table *wait) ...@@ -1174,9 +1237,9 @@ isdn_ctrl_poll(struct file *file, poll_table *wait)
/* driver deregistered while file open */ /* driver deregistered while file open */
return POLLHUP; return POLLHUP;
poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait); poll_wait(file, &drivers[drvidx]->st_waitq, wait);
mask = POLLOUT | POLLWRNORM; mask = POLLOUT | POLLWRNORM;
if (dev->drv[drvidx]->stavail) if (drivers[drvidx]->stavail)
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
return mask; return mask;
...@@ -1255,9 +1318,9 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1255,9 +1318,9 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
if (drvidx == -1) if (drvidx == -1)
return -ENODEV; return -ENODEV;
if (iocts.arg) if (iocts.arg)
dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS; drivers[drvidx]->flags |= DRV_FLAG_REJBUS;
else else
dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS; drivers[drvidx]->flags &= ~DRV_FLAG_REJBUS;
return 0; return 0;
case IIOCSIGPRF: case IIOCSIGPRF:
dev->profd = current; dev->profd = current;
...@@ -1355,7 +1418,7 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1355,7 +1418,7 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
/* Fall through */ /* Fall through */
case ',': case ',':
bname[j] = '\0'; bname[j] = '\0';
strcpy(dev->drv[drvidx]->msn2eaz[i], bname); strcpy(drivers[drvidx]->msn2eaz[i], bname);
j = ISDN_MSNLEN; j = ISDN_MSNLEN;
break; break;
default: default:
...@@ -1371,8 +1434,8 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -1371,8 +1434,8 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
p = (char *) iocts.arg; p = (char *) iocts.arg;
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
sprintf(bname, "%s%s", sprintf(bname, "%s%s",
strlen(dev->drv[drvidx]->msn2eaz[i]) ? strlen(drivers[drvidx]->msn2eaz[i]) ?
dev->drv[drvidx]->msn2eaz[i] : "_", drivers[drvidx]->msn2eaz[i] : "_",
(i < 9) ? "," : "\0"); (i < 9) ? "," : "\0");
if (copy_to_user(p, bname, strlen(bname) + 1)) if (copy_to_user(p, bname, strlen(bname) + 1))
return -EFAULT; return -EFAULT;
...@@ -1494,7 +1557,7 @@ static struct file_operations isdn_fops = ...@@ -1494,7 +1557,7 @@ static struct file_operations isdn_fops =
char * char *
isdn_map_eaz2msn(char *msn, int di) isdn_map_eaz2msn(char *msn, int di)
{ {
driver *this = dev->drv[di]; struct isdn_driver *this = drivers[di];
int i; int i;
if (strlen(msn) == 1) { if (strlen(msn) == 1) {
...@@ -1538,11 +1601,11 @@ isdn_get_free_slot(int usage, int l2_proto, int l3_proto, ...@@ -1538,11 +1601,11 @@ isdn_get_free_slot(int usage, int l2_proto, int l3_proto,
continue; continue;
if (slot[i].usage & ISDN_USAGE_DISABLED) if (slot[i].usage & ISDN_USAGE_DISABLED)
continue; /* usage not allowed */ continue; /* usage not allowed */
if (!dev->drv[d]->flags & DRV_FLAG_RUNNING) if (!drivers[d]->flags & DRV_FLAG_RUNNING)
continue; continue;
if (((dev->drv[d]->interface->features & features) == features) || if (((drivers[d]->interface->features & features) == features) ||
(((dev->drv[d]->interface->features & vfeatures) == vfeatures) && (((drivers[d]->interface->features & vfeatures) == vfeatures) &&
(dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) { (drivers[d]->interface->features & ISDN_FEATURE_L2_TRANS))) {
if (pre_dev < 0 || pre_chan < 0 || if (pre_dev < 0 || pre_chan < 0 ||
(pre_dev == d && pre_chan == slot[i].ch)) { (pre_dev == d && pre_chan == slot[i].ch)) {
isdn_slot_set_usage(i, usage); isdn_slot_set_usage(i, usage);
...@@ -1584,7 +1647,7 @@ isdn_slot_free(int sl) ...@@ -1584,7 +1647,7 @@ isdn_slot_free(int sl)
slot[sl].iv110.v110 = NULL; slot[sl].iv110.v110 = NULL;
// 20.10.99 JIM, try to reinitialize v110 ! // 20.10.99 JIM, try to reinitialize v110 !
isdn_slot_set_usage(sl, ISDN_USAGE_NONE); isdn_slot_set_usage(sl, ISDN_USAGE_NONE);
skb_queue_purge(&dev->drv[isdn_slot_driver(sl)]->rpqueue[isdn_slot_channel(sl)]); skb_queue_purge(&drivers[isdn_slot_driver(sl)]->rpqueue[isdn_slot_channel(sl)]);
restore_flags(flags); restore_flags(flags);
} }
...@@ -1615,7 +1678,7 @@ isdn_slot_write(int sl, struct sk_buff *skb) ...@@ -1615,7 +1678,7 @@ isdn_slot_write(int sl, struct sk_buff *skb)
return v110_ret; return v110_ret;
} }
/* V.110 must always be acknowledged */ /* V.110 must always be acknowledged */
ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, nskb); ret = drivers[di]->interface->writebuf_skb(di, ch, 1, nskb);
} else { } else {
int hl = isdn_slot_hdrlen(sl); int hl = isdn_slot_hdrlen(sl);
...@@ -1633,14 +1696,14 @@ isdn_slot_write(int sl, struct sk_buff *skb) ...@@ -1633,14 +1696,14 @@ isdn_slot_write(int sl, struct sk_buff *skb)
skb_tmp = skb_realloc_headroom(skb, hl); skb_tmp = skb_realloc_headroom(skb, hl);
printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed"); printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed");
if (!skb_tmp) return -ENOMEM; /* 0 better? */ if (!skb_tmp) return -ENOMEM; /* 0 better? */
ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb_tmp); ret = drivers[di]->interface->writebuf_skb(di, ch, 1, skb_tmp);
if( ret > 0 ){ if( ret > 0 ){
dev_kfree_skb(skb); dev_kfree_skb(skb);
} else { } else {
dev_kfree_skb(skb_tmp); dev_kfree_skb(skb_tmp);
} }
} else { } else {
ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb); ret = drivers[di]->interface->writebuf_skb(di, ch, 1, skb);
} }
} }
if (ret > 0) { if (ret > 0) {
...@@ -1662,8 +1725,8 @@ isdn_slot_write(int sl, struct sk_buff *skb) ...@@ -1662,8 +1725,8 @@ isdn_slot_write(int sl, struct sk_buff *skb)
return ret; return ret;
} }
int static int
isdn_add_channels(driver *d, int drvidx, int n, int adding) isdn_add_channels(struct isdn_driver *d, int drvidx, int n, int adding)
{ {
int j, k, m; int j, k, m;
ulong flags; ulong flags;
...@@ -1742,10 +1805,10 @@ set_global_features(void) ...@@ -1742,10 +1805,10 @@ set_global_features(void)
dev->global_features = 0; dev->global_features = 0;
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
if (!dev->drv[drvidx]) if (!drivers[drvidx])
continue; continue;
if (dev->drv[drvidx]->interface) if (drivers[drvidx]->interface)
dev->global_features |= dev->drv[drvidx]->interface->features; dev->global_features |= drivers[drvidx]->interface->features;
} }
} }
...@@ -1810,7 +1873,7 @@ EXPORT_SYMBOL(isdn_ppp_unregister_compressor); ...@@ -1810,7 +1873,7 @@ EXPORT_SYMBOL(isdn_ppp_unregister_compressor);
int int
register_isdn(isdn_if * i) register_isdn(isdn_if * i)
{ {
driver *d; struct isdn_driver *d;
int j; int j;
ulong flags; ulong flags;
int drvidx; int drvidx;
...@@ -1831,14 +1894,13 @@ register_isdn(isdn_if * i) ...@@ -1831,14 +1894,13 @@ register_isdn(isdn_if * i)
memset((char *) d, 0, sizeof(driver)); memset((char *) d, 0, sizeof(driver));
d->maxbufsize = i->maxbufsize; d->maxbufsize = i->maxbufsize;
d->pktcount = 0;
d->stavail = 0; d->stavail = 0;
d->flags = DRV_FLAG_LOADED; d->flags = DRV_FLAG_LOADED;
d->online = 0; d->online = 0;
d->interface = i; d->interface = i;
d->channels = 0; d->channels = 0;
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
if (!dev->drv[drvidx]) if (!drivers[drvidx])
break; break;
if (isdn_add_channels(d, drvidx, i->channels, 0)) { if (isdn_add_channels(d, drvidx, i->channels, 0)) {
kfree(d); kfree(d);
...@@ -1854,7 +1916,7 @@ register_isdn(isdn_if * i) ...@@ -1854,7 +1916,7 @@ register_isdn(isdn_if * i)
for (j = 0; j < drvidx; j++) for (j = 0; j < drvidx; j++)
if (!strcmp(i->id, dev->drvid[j])) if (!strcmp(i->id, dev->drvid[j]))
sprintf(i->id, "line%d", drvidx); sprintf(i->id, "line%d", drvidx);
dev->drv[drvidx] = d; drivers[drvidx] = d;
strcpy(dev->drvid[drvidx], i->id); strcpy(dev->drvid[drvidx], i->id);
isdn_info_update(); isdn_info_update();
dev->drivers++; dev->drivers++;
...@@ -1884,7 +1946,7 @@ isdn_slot_hdrlen(int sl) ...@@ -1884,7 +1946,7 @@ isdn_slot_hdrlen(int sl)
{ {
int di = isdn_slot_driver(sl); int di = isdn_slot_driver(sl);
return dev->drv[di]->interface->hl_hdrlen; return drivers[di]->interface->hl_hdrlen;
} }
char * char *
...@@ -2041,9 +2103,9 @@ isdn_hard_header_len(void) ...@@ -2041,9 +2103,9 @@ isdn_hard_header_len(void)
int max = 0; int max = 0;
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
if (dev->drv[drvidx] && if (drivers[drvidx] &&
max < dev->drv[drvidx]->interface->hl_hdrlen) { max < drivers[drvidx]->interface->hl_hdrlen) {
max = dev->drv[drvidx]->interface->hl_hdrlen; max = drivers[drvidx]->interface->hl_hdrlen;
} }
} }
return max; return max;
......
...@@ -63,7 +63,6 @@ extern char *isdn_map_eaz2msn(char *msn, int di); ...@@ -63,7 +63,6 @@ extern char *isdn_map_eaz2msn(char *msn, int di);
extern void isdn_timer_ctrl(int tf, int onoff); extern void isdn_timer_ctrl(int tf, int onoff);
extern int isdn_getnum(char **); extern int isdn_getnum(char **);
extern int isdn_msncmp( const char *, const char *); extern int isdn_msncmp( const char *, const char *);
extern int isdn_add_channels(driver *, int, int, int);
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
extern void isdn_dumppkt(char *, u_char *, int, int); extern void isdn_dumppkt(char *, u_char *, int, int);
#else #else
...@@ -99,3 +98,9 @@ extern void isdn_slot_set_m_idx(int slot, int midx); ...@@ -99,3 +98,9 @@ extern void isdn_slot_set_m_idx(int slot, int midx);
extern void isdn_slot_set_priv(int sl, void *); extern void isdn_slot_set_priv(int sl, void *);
extern void *isdn_slot_priv(int sl); extern void *isdn_slot_priv(int sl);
extern int isdn_hard_header_len(void); extern int isdn_hard_header_len(void);
int isdn_drv_queue_empty(int di, int ch);
void isdn_drv_queue_tail(int di, int ch, struct sk_buff *skb, int len);
int isdn_drv_maxbufsize(int di);
int isdn_drv_writebuf_skb(int di, int ch, int x, struct sk_buff *skb);
int isdn_drv_hdrlen(int di);
...@@ -264,7 +264,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) ...@@ -264,7 +264,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
/* Try to deliver directly via tty-flip-buf if queue is empty */ /* Try to deliver directly via tty-flip-buf if queue is empty */
save_flags(flags); save_flags(flags);
cli(); cli();
if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) if (isdn_drv_queue_empty(di, channel))
if (isdn_tty_try_read(info, skb)) { if (isdn_tty_try_read(info, skb)) {
restore_flags(flags); restore_flags(flags);
return 1; return 1;
...@@ -272,9 +272,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) ...@@ -272,9 +272,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
/* Direct deliver failed or queue wasn't empty. /* Direct deliver failed or queue wasn't empty.
* Queue up for later dequeueing via timer-irq. * Queue up for later dequeueing via timer-irq.
*/ */
__skb_queue_tail(&dev->drv[di]->rpqueue[channel], skb); isdn_drv_queue_tail(di, channel, skb, skb->len
dev->drv[di]->rcvcount[channel] +=
(skb->len
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
+ ISDN_AUDIO_SKB_DLECOUNT(skb) + ISDN_AUDIO_SKB_DLECOUNT(skb)
#endif #endif
...@@ -1109,8 +1107,8 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co ...@@ -1109,8 +1107,8 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
if (c > info->xmit_size - info->xmit_count) if (c > info->xmit_size - info->xmit_count)
c = info->xmit_size - info->xmit_count; c = info->xmit_size - info->xmit_count;
di = isdn_slot_driver(info->isdn_slot); di = isdn_slot_driver(info->isdn_slot);
if (di >= 0 && c > dev->drv[di]->maxbufsize) if (di >= 0 && c > isdn_drv_maxbufsize(di))
c = dev->drv[di]->maxbufsize; c = isdn_drv_maxbufsize(di);
if (c <= 0) if (c <= 0)
break; break;
if ((info->online > 1) if ((info->online > 1)
...@@ -2211,7 +2209,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) ...@@ -2211,7 +2209,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
} }
restore_flags(flags); restore_flags(flags);
printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz, printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz,
((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2))? "rejected" : "ignored"); (wret != 2)? "rejected" : "ignored");
return (wret == 2)?3:0; return (wret == 2)?3:0;
} }
...@@ -2441,7 +2439,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) ...@@ -2441,7 +2439,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
/* data is in queue or flip buffer is full */ /* data is in queue or flip buffer is full */
di = isdn_slot_driver(info->isdn_slot); ch = isdn_slot_channel(info->isdn_slot); di = isdn_slot_driver(info->isdn_slot); ch = isdn_slot_channel(info->isdn_slot);
if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) ||
(!skb_queue_empty(&dev->drv[di]->rpqueue[ch])))) { (!isdn_drv_queue_empty(di, ch)))) {
skb = alloc_skb(strlen(msg) skb = alloc_skb(strlen(msg)
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
+ sizeof(isdn_audio_skb) + sizeof(isdn_audio_skb)
...@@ -2484,8 +2482,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) ...@@ -2484,8 +2482,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
} }
} }
if (skb) { if (skb) {
__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); isdn_drv_queue_tail(di, ch, skb, skb->len);
dev->drv[di]->rcvcount[ch] += skb->len;
restore_flags(flags); restore_flags(flags);
/* Schedule dequeuing */ /* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched)) if ((dev->modempoll) && (info->rcvsched))
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/isdn.h> #include <linux/isdn.h>
#include "isdn_v110.h" #include "isdn_v110.h"
#include "isdn_common.h"
#undef ISDN_V110_DEBUG #undef ISDN_V110_DEBUG
...@@ -542,7 +543,7 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c) ...@@ -542,7 +543,7 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c)
else else
skb = isdn_v110_idle(v); skb = isdn_v110_idle(v);
if (skb) { if (skb) {
if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) { if (isdn_drv_writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
break; break;
} else { } else {
...@@ -569,8 +570,8 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c) ...@@ -569,8 +570,8 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c)
break; break;
case ISDN_STAT_BCONN: case ISDN_STAT_BCONN:
if (iv110->v110emu && (iv110->v110 == NULL)) { if (iv110->v110emu && (iv110->v110 == NULL)) {
int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen; int hdrlen = isdn_drv_hdrlen(c->driver);
int maxsize = dev->drv[c->driver]->interface->maxbufsize; int maxsize = isdn_drv_maxbufsize(c->driver);
atomic_inc(&iv110->v110use); atomic_inc(&iv110->v110use);
switch (iv110->v110emu) { switch (iv110->v110emu) {
case ISDN_PROTO_L2_V11096: case ISDN_PROTO_L2_V11096:
...@@ -587,7 +588,7 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c) ...@@ -587,7 +588,7 @@ isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c)
if ((v = iv110->v110)) { if ((v = iv110->v110)) {
while (v->SyncInit) { while (v->SyncInit) {
struct sk_buff *skb = isdn_v110_sync(v); struct sk_buff *skb = isdn_v110_sync(v);
if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) { if (isdn_drv_writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
/* Unable to send, try later */ /* Unable to send, try later */
break; break;
......
...@@ -413,30 +413,6 @@ typedef struct { ...@@ -413,30 +413,6 @@ typedef struct {
char *private; char *private;
} infostruct; } infostruct;
#define DRV_FLAG_RUNNING 1
#define DRV_FLAG_REJBUS 2
#define DRV_FLAG_LOADED 4
/* Description of hardware-level-driver */
typedef struct {
ulong online; /* Channel-Online flags */
ulong flags; /* Misc driver Flags */
int locks; /* Number of locks for this driver */
int channels; /* Number of channels */
wait_queue_head_t st_waitq; /* Wait-Queue for status-read's */
int maxbufsize; /* Maximum Buffersize supported */
unsigned long pktcount; /* Until now: unused */
int stavail; /* Chars avail on Status-device */
isdn_if *interface; /* Interface to driver */
int *rcverr; /* Error-counters for B-Ch.-receive */
int *rcvcount; /* Byte-counters for B-Ch.-receive */
#ifdef CONFIG_ISDN_AUDIO
unsigned long DLEflag; /* Flags: Insert DLE at next read */
#endif
struct sk_buff_head *rpqueue; /* Pointers to start of Rcv-Queue */
char msn2eaz[10][ISDN_MSNLEN]; /* Mapping-Table MSN->EAZ */
} driver;
/* Main driver-data */ /* Main driver-data */
typedef struct isdn_devt { typedef struct isdn_devt {
unsigned short flags; /* Bitmapped Flags: */ unsigned short flags; /* Bitmapped Flags: */
...@@ -451,7 +427,6 @@ typedef struct isdn_devt { ...@@ -451,7 +427,6 @@ typedef struct isdn_devt {
infostruct *infochain; /* List of open info-devs. */ infostruct *infochain; /* List of open info-devs. */
wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */ wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */
struct timer_list timer; /* Misc.-function Timer */ struct timer_list timer; /* Misc.-function Timer */
driver *drv[ISDN_MAX_DRIVERS]; /* Array of drivers */
char drvid[ISDN_MAX_DRIVERS][20];/* Driver-ID */ char drvid[ISDN_MAX_DRIVERS][20];/* Driver-ID */
struct task_struct *profd; /* For iprofd */ struct task_struct *profd; /* For iprofd */
modem mdm; /* tty-driver-data */ modem mdm; /* tty-driver-data */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment