struct ipw_network { /* Hardware context, used for calls to hardware layer. */ struct ipw_hardware *hardware; /* Context for kernel 'generic_ppp' functionality */ struct ppp_channel *ppp_channel; /* tty context connected with IPW console */ struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS]; /* True if ppp needs waking up once we're ready to xmit */ int ppp_blocked; /* Number of packets queued up in hardware module. */ int outgoing_packets_queued; /* Spinlock to avoid interrupts during shutdown */
spinlock_t lock; struct mutex close_lock;
/* PPP ioctl data, not actually used anywere */ unsignedint flags; unsignedint rbits;
u32 xaccm[8];
u32 raccm; int mru;
/* *Ifwehavetherequestedamountofheadroomintheskbwe *werehanded,thenwecanaddtheheaderefficiently.
*/ if (skb_headroom(skb) >= 2) {
memcpy(skb_push(skb, 2), header, 2);
ret = ipwireless_send_packet(network->hardware,
IPW_CHANNEL_RAS, skb->data,
skb->len,
notify_packet_sent,
network); if (ret < 0) {
skb_pull(skb, 2); return0;
}
} else { /* Otherwise (rarely) we do it inefficiently. */
buf = kmalloc(skb->len + 2, GFP_ATOMIC); if (!buf) return0;
memcpy(buf + 2, skb->data, skb->len);
memcpy(buf, header, 2);
ret = ipwireless_send_packet(network->hardware,
IPW_CHANNEL_RAS, buf,
skb->len + 2,
notify_packet_sent,
network);
kfree(buf); if (ret < 0) return0;
}
kfree_skb(skb); return1;
} else { /* *Otherwiserejectthepacket,andflagthatthepppsystem *needstobeunblockedoncewearereadytosend.
*/
network->ppp_blocked = 1;
spin_unlock_irqrestore(&network->lock, flags); if (ipwireless_debug)
printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); return0;
}
}
/* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */ staticint ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel, unsignedint cmd, unsignedlong arg)
{ struct ipw_network *network = ppp_channel->private; int err, val;
u32 accm[8]; int __user *user_arg = (int __user *) arg;
err = -EFAULT; switch (cmd) { case PPPIOCGFLAGS:
val = network->flags | network->rbits; if (put_user(val, user_arg)) break;
err = 0; break;
case PPPIOCSFLAGS: if (get_user(val, user_arg)) break;
network->flags = val & ~SC_RCV_BITS;
network->rbits = val & SC_RCV_BITS;
err = 0; break;
case PPPIOCGASYNCMAP: if (put_user(network->xaccm[0], user_arg)) break;
err = 0; break;
case PPPIOCSASYNCMAP: if (get_user(network->xaccm[0], user_arg)) break;
err = 0; break;
case PPPIOCGRASYNCMAP: if (put_user(network->raccm, user_arg)) break;
err = 0; break;
case PPPIOCSRASYNCMAP: if (get_user(network->raccm, user_arg)) break;
err = 0; break;
case PPPIOCGXASYNCMAP: if (copy_to_user((void __user *) arg, network->xaccm, sizeof(network->xaccm))) break;
err = 0; break;
/* Send the data to the ppp_generic module. */
skb = ipw_packet_received_skb(data, length); if (skb)
ppp_input(network->ppp_channel, skb);
} else
spin_unlock_irqrestore(&network->lock,
flags);
mutex_unlock(&network->close_lock);
} /* Otherwise we send it out the tty. */ else
ipwireless_tty_received(tty, data, length);
}
}
for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) if (network->associated_ttys[channel_idx][i] == NULL) {
network->associated_ttys[channel_idx][i] = tty; break;
}
}
void ipwireless_disassociate_network_ttys(struct ipw_network *network, unsignedint channel_idx)
{ int i;
for (i = 0; i < MAX_ASSOCIATED_TTYS; i++)
network->associated_ttys[channel_idx][i] = NULL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.