diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-29 18:29:16 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-29 18:29:16 -0800 |
| commit | 9df2d392815da06f0cbb18a60975abe3e0120245 (patch) | |
| tree | c227129606bbb15e8c7c8c02acd7f16d30f7db0d | |
| parent | ba9558cddc654c117acacccf2713ed101b0fc891 (diff) | |
| parent | 4445b58eb2f5e5b20d21c4cf440a5b0f91037e3e (diff) | |
Merge home.transmeta.com:/home/torvalds/v2.5/kconfig
into home.transmeta.com:/home/torvalds/v2.5/newconfig
182 files changed, 4807 insertions, 4918 deletions
diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl index 98d689b33529..8d971b0120fb 100644 --- a/Documentation/DocBook/writing_usb_driver.tmpl +++ b/Documentation/DocBook/writing_usb_driver.tmpl @@ -307,7 +307,7 @@ if (result) { </programlisting> <para> When the write urb is filled up with the proper information using the - FILL_BULK_URB function, we point the urb's completion callback to call our + usb_fill_bulk_urb function, we point the urb's completion callback to call our own skel_write_bulk_callback function. This function is called when the urb is finished by the USB subsystem. The callback function is called in interrupt context, so caution must be taken not to do very much processing diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt index 5df880cb3ce3..d25d24614e36 100644 --- a/Documentation/usb/URB.txt +++ b/Documentation/usb/URB.txt @@ -109,7 +109,7 @@ Take a look at the some existing drivers to see how they're used. Flags: For ISO there are two startup behaviors: Specified start_frame or ASAP. -For ASAP set USB_ISO_ASAP in transfer_flags. +For ASAP set URB_ISO_ASAP in transfer_flags. If short packets should NOT be tolerated, set URB_SHORT_NOT_OK in transfer_flags. @@ -156,7 +156,7 @@ usb_unlink_urb() returns with that status code, you can free the URB with usb_free_urb(). There is also an asynchronous unlink mode. To use this, set the -the USB_ASYNC_UNLINK flag in urb->transfer flags before calling +the URB_ASYNC_UNLINK flag in urb->transfer flags before calling usb_unlink_urb(). When using async unlinking, the URB will not normally be unlinked when usb_unlink_urb() returns. Instead, wait for the completion handler to be called. diff --git a/MAINTAINERS b/MAINTAINERS index ead85eecc260..c5c34d24595b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1210,6 +1210,12 @@ M: zwane@commfireservices.com L: linux-sound@vger.kernel.org S: Maintained +OPROFILE +P: John Levon +M: levon@movementarian.org +L: oprofile-list@lists.sf.net +S: Maintained + ORINOCO DRIVER P: David Gibson M: hermes@gibson.dropbear.id.au diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 25e06e88334b..eeaf539e2256 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -22,24 +22,26 @@ LDFLAGS_vmlinux := -e stext CFLAGS += -pipe +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + # prevent gcc from keeping the stack 16 byte aligned -CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi) +CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,) cflags-$(CONFIG_M386) += -march=i386 cflags-$(CONFIG_M486) += -march=i486 cflags-$(CONFIG_M586) += -march=i586 cflags-$(CONFIG_M586TSC) += -march=i586 -cflags-$(CONFIG_M586MMX) += $(shell if $(CC) -march=pentium-mmx -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=pentium-mmx"; else echo "-march=i586"; fi) +cflags-$(CONFIG_M586MMX) += $(call check_gcc,-march=pentium-mmx,-march=i586) cflags-$(CONFIG_M686) += -march=i686 -cflags-$(CONFIG_MPENTIUMIII) += $(shell if $(CC) -march=pentium3 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=pentium3"; else echo "-march=i686"; fi) -cflags-$(CONFIG_MPENTIUM4) += $(shell if $(CC) -march=pentium4 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=pentium4"; else echo "-march=i686"; fi) -cflags-$(CONFIG_MK6) += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi) -cflags-$(CONFIG_MK7) += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else echo "-march=i686 -malign-functions=4"; fi) +cflags-$(CONFIG_MPENTIUMIII) += $(call check_gcc,-march=pentium3,-march=i686) +cflags-$(CONFIG_MPENTIUM4) += $(call check_gcc,-march=pentium4,-march=i686) +cflags-$(CONFIG_MK6) += $(call check_gcc,-march=k6,-march=i586) +cflags-$(CONFIG_MK7) += $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4) cflags-$(CONFIG_MCRUSOE) += -march=i686 -malign-functions=0 -malign-jumps=0 -malign-loops=0 -cflags-$(CONFIG_MWINCHIPC6) += -march=i586 -cflags-$(CONFIG_MWINCHIP2) += -march=i586 +cflags-$(CONFIG_MWINCHIPC6) += $(call check_gcc,-march=winchip-c6,-march=i586) +cflags-$(CONFIG_MWINCHIP2) += $(call check_gcc,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += -march=i586 -cflags-$(CONFIG_MCYRIXIII) += -march=i586 +cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,-march=c3,-march=i586) CFLAGS += $(cflags-y) diff --git a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c index 9d0b71c3d047..b4aabede5531 100644 --- a/arch/i386/oprofile/op_model_athlon.c +++ b/arch/i386/oprofile/op_model_athlon.c @@ -95,17 +95,16 @@ static int athlon_check_ctrs(unsigned int const cpu, struct pt_regs * const regs) { unsigned int low, high; - int handled = 0; int i; for (i = 0 ; i < NUM_COUNTERS; ++i) { CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs->eip, i, cpu); CTR_WRITE(reset_value[i], msrs, i); - handled = 1; + return 1; } } - return handled; + return 0; } diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c index 9252e01bef1e..0f00c4d1e924 100644 --- a/arch/i386/oprofile/op_model_ppro.c +++ b/arch/i386/oprofile/op_model_ppro.c @@ -90,17 +90,16 @@ static int ppro_check_ctrs(unsigned int const cpu, { unsigned int low, high; int i; - int handled = 0; for (i = 0 ; i < NUM_COUNTERS; ++i) { CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs->eip, i, cpu); CTR_WRITE(reset_value[i], msrs, i); - handled = 1; + return 1; } } - return handled; + return 0; } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c5a437f0f823..605fd37e14ee 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -437,7 +437,7 @@ static int loop_end_io_transfer(struct bio *bio, unsigned int bytes_done, int er if (bio->bi_size) return 1; - if (!err || bio_rw(bio) == WRITE) { + if (err || bio_rw(bio) == WRITE) { bio_endio(rbh, rbh->bi_size, err); if (atomic_dec_and_test(&lo->lo_pending)) up(&lo->lo_bh_mutex); @@ -688,7 +688,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, if (!aops->prepare_write || !aops->commit_write) lo_flags |= LO_FLAGS_READ_ONLY; - lo_blocksize = inode->i_blocksize; + lo_blocksize = inode->i_blksize; lo_flags |= LO_FLAGS_DO_BMAP; error = 0; } else diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index ce6f9da59efc..90e92871dfe1 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -67,8 +67,8 @@ #endif #ifndef CONFIG_BT_USB_ZERO_PACKET -#undef USB_ZERO_PACKET -#define USB_ZERO_PACKET 0 +#undef URB_ZERO_PACKET +#define URB_ZERO_PACKET 0 #endif static struct usb_driver hci_usb_driver; @@ -131,7 +131,7 @@ static int hci_usb_enable_intr(struct hci_usb *husb) pipe = usb_rcvintpipe(husb->udev, husb->intr_ep); size = usb_maxpacket(husb->udev, pipe, usb_pipeout(pipe)); - FILL_INT_URB(urb, husb->udev, pipe, buf, size, + usb_fill_int_urb(urb, husb->udev, pipe, buf, size, hci_usb_interrupt, husb, husb->intr_interval); return usb_submit_urb(urb, GFP_KERNEL); @@ -182,7 +182,7 @@ static int hci_usb_rx_submit(struct hci_usb *husb, struct urb *urb) pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep); - FILL_BULK_URB(urb, husb->udev, pipe, skb->data, size, hci_usb_rx_complete, skb); + usb_fill_bulk_urb(urb, husb->udev, pipe, skb->data, size, hci_usb_rx_complete, skb); skb_queue_tail(&husb->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); @@ -299,7 +299,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb) cr->wValue = 0; cr->wLength = __cpu_to_le16(skb->len); - FILL_CONTROL_URB(urb, husb->udev, pipe, (void *) cr, + usb_fill_control_urb(urb, husb->udev, pipe, (void *) cr, skb->data, skb->len, hci_usb_tx_complete, skb); BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len); @@ -328,9 +328,9 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb) pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep); - FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len, + usb_fill_bulk_urb(urb, husb->udev, pipe, skb->data, skb->len, hci_usb_tx_complete, skb); - urb->transfer_flags = USB_ZERO_PACKET; + urb->transfer_flags = URB_ZERO_PACKET; BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len); @@ -629,13 +629,13 @@ static void hci_usb_destruct(struct hci_dev *hdev) int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); - struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM]; - struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM]; - struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM]; - struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM]; - struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM]; - struct usb_interface_descriptor *uif; - struct usb_endpoint_descriptor *ep; + struct usb_host_endpoint *bulk_out_ep[HCI_MAX_IFACE_NUM]; + struct usb_host_endpoint *isoc_out_ep[HCI_MAX_IFACE_NUM]; + struct usb_host_endpoint *bulk_in_ep[HCI_MAX_IFACE_NUM]; + struct usb_host_endpoint *isoc_in_ep[HCI_MAX_IFACE_NUM]; + struct usb_host_endpoint *intr_in_ep[HCI_MAX_IFACE_NUM]; + struct usb_host_interface *uif; + struct usb_host_endpoint *ep; struct usb_interface *iface, *isoc_iface; struct hci_usb *husb; struct hci_dev *hdev; @@ -648,7 +648,7 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return -EIO; /* Check number of endpoints */ - if (intf->altsetting[0].bNumEndpoints < 3) + if (intf->altsetting[0].desc.bNumEndpoints < 3) return -EIO; memset(bulk_out_ep, 0, sizeof(bulk_out_ep)); @@ -663,37 +663,37 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Find endpoints that we need */ - ifn = min_t(unsigned int, udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM); + ifn = min_t(unsigned int, udev->actconfig->desc.bNumInterfaces, HCI_MAX_IFACE_NUM); for (i = 0; i < ifn; i++) { iface = &udev->actconfig->interface[i]; for (a = 0; a < iface->num_altsetting; a++) { uif = &iface->altsetting[a]; - for (e = 0; e < uif->bNumEndpoints; e++) { + for (e = 0; e < uif->desc.bNumEndpoints; e++) { ep = &uif->endpoint[e]; - switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_INT: - if (ep->bEndpointAddress & USB_DIR_IN) + if (ep->desc.bEndpointAddress & USB_DIR_IN) intr_in_ep[i] = ep; break; case USB_ENDPOINT_XFER_BULK: - if (ep->bEndpointAddress & USB_DIR_IN) + if (ep->desc.bEndpointAddress & USB_DIR_IN) bulk_in_ep[i] = ep; else bulk_out_ep[i] = ep; break; case USB_ENDPOINT_XFER_ISOC: - if (ep->wMaxPacketSize < size) + if (ep->desc.wMaxPacketSize < size) break; - size = ep->wMaxPacketSize; + size = ep->desc.wMaxPacketSize; isoc_iface = iface; isoc_alts = a; isoc_ifnum = i; - if (ep->bEndpointAddress & USB_DIR_IN) + if (ep->desc.bEndpointAddress & USB_DIR_IN) isoc_in_ep[i] = ep; else isoc_out_ep[i] = ep; @@ -721,11 +721,11 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) memset(husb, 0, sizeof(struct hci_usb)); husb->udev = udev; - husb->bulk_out_ep = bulk_out_ep[0]->bEndpointAddress; - husb->bulk_in_ep = bulk_in_ep[0]->bEndpointAddress; + husb->bulk_out_ep = bulk_out_ep[0]->desc.bEndpointAddress; + husb->bulk_in_ep = bulk_in_ep[0]->desc.bEndpointAddress; - husb->intr_ep = intr_in_ep[0]->bEndpointAddress; - husb->intr_interval = intr_in_ep[0]->bInterval; + husb->intr_ep = intr_in_ep[0]->desc.bEndpointAddress; + husb->intr_interval = intr_in_ep[0]->desc.bInterval; if (isoc_iface) { if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) { @@ -735,8 +735,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb); husb->isoc_iface = isoc_iface; - husb->isoc_in_ep = isoc_in_ep[1]->bEndpointAddress; - husb->isoc_out_ep = isoc_in_ep[1]->bEndpointAddress; + husb->isoc_in_ep = isoc_in_ep[1]->desc.bEndpointAddress; + husb->isoc_out_ep = isoc_in_ep[1]->desc.bEndpointAddress; } husb->completion_lock = RW_LOCK_UNLOCKED; diff --git a/drivers/isdn/hisax/amd7930.c b/drivers/isdn/hisax/amd7930.c index 5040215aa4ff..9826d7b4b21a 100644 --- a/drivers/isdn/hisax/amd7930.c +++ b/drivers/isdn/hisax/amd7930.c @@ -106,8 +106,9 @@ static const char *amd7930_revision = "$Revision: 1.5.6.4 $"; static void Bchan_fill_fifo(struct BCState *, struct sk_buff *); static void -Bchan_xmt_bh(struct BCState *bcs) +Bchan_xmt_bh(void *data) { + struct BCState *bcs = data; struct sk_buff *skb; if (bcs->hw.amd7930.tx_skb != NULL) { @@ -120,14 +121,14 @@ Bchan_xmt_bh(struct BCState *bcs) } else { clear_bit(BC_FLG_BUSY, &bcs->Flag); bcs->event |= 1 << B_XMTBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } } static void Bchan_xmit_callback(struct BCState *bcs) { - schedule_work(&bcs->hw.amd7930.tq_xmt); + schedule_work(&bcs->hw.amd7930.xmt_work); } /* B channel transmission: two modes (three, if you count L1_MODE_NULL) @@ -259,12 +260,13 @@ Bchan_recv_callback(struct BCState *bcs) (void *) &Bchan_recv_callback, (void *) bcs); } - schedule_work(&hw->tq_rcv); + schedule_work(&hw->rcv_work); } static void -Bchan_rcv_bh(struct BCState *bcs) +Bchan_rcv_bh(void *data) { + struct BCState *bcs = data; struct IsdnCardState *cs = bcs->cs; struct amd7930_hw *hw = &bcs->hw.amd7930; struct sk_buff *skb; @@ -305,7 +307,7 @@ Bchan_rcv_bh(struct BCState *bcs) skb_queue_tail(&bcs->rqueue, hw->rv_skb); hw->rv_skb = skb; bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } } else if (len > 0) { /* Small packet received */ @@ -316,7 +318,7 @@ Bchan_rcv_bh(struct BCState *bcs) memcpy(skb_put(skb, len), hw->rv_skb->tail, len); skb_queue_tail(&bcs->rqueue, skb); bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } } else { /* Reception Error */ @@ -332,7 +334,7 @@ Bchan_rcv_bh(struct BCState *bcs) RCV_BUFSIZE/RCV_BUFBLKS); skb_queue_tail(&bcs->rqueue, skb); bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } } @@ -416,12 +418,8 @@ Bchan_init(struct BCState *bcs) return; } - bcs->hw.amd7930.tq_rcv.sync = 0; - INIT_WORK(&bcs->hw.amd7930.tq_rcv, (void (*)(void *)) &Bchan_rcv_bh, - (void *) bcs); - - INIT_WORK(&bcs->hw.amd7930.tq_xmt, (void (*)(void *)) &Bchan_xmt_bh, - (void *) bcs); + INIT_WORK(&bcs->hw.amd7930.rcv_work, &Bchan_rcv_bh, bcs); + INIT_WORK(&bcs->hw.amd7930.xmt_work, &Bchan_xmt_bh, bcs); } static void diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index 02fbf3d54b5f..369a81f0d050 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c @@ -232,9 +232,9 @@ Amd7930_new_ph(struct IsdnCardState *cs) static void -Amd7930_bh(struct IsdnCardState *cs) +Amd7930_bh(void *data) { - + struct IsdnCardState *cs = data; struct PStack *stptr; if (!cs) @@ -277,7 +277,7 @@ Amd7930_sched_event(struct IsdnCardState *cs, int event) // ok } test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } static void @@ -790,7 +790,7 @@ Amd7930_init(struct IsdnCardState *cs) cs->dc.amd7930.old_state = 0; cs->dc.amd7930.lmr1 = 0x40; cs->dc.amd7930.ph_command = Amd7930_ph_command; - INIT_WORK(&cs->tqueue, (void *) (void *) Amd7930_bh, NULL); + INIT_WORK(&cs->work, Amd7930_bh, cs); cs->setstack_d = setstack_Amd7930; cs->DC_Close = DC_Close_Amd7930; cs->dbusytimer.function = (void *) dbusy_timer_handler; diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index 637418d514b8..cf943f1bddc4 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c @@ -24,6 +24,7 @@ extern const char *CardType[]; const char *Asuscom_revision = "$Revision: 1.11.6.3 $"; +static spinlock_t asuscom_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -46,13 +47,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&asuscom_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&asuscom_lock, flags); return (ret); } @@ -69,13 +69,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&asuscom_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&asuscom_lock, flags); } static inline void @@ -263,14 +262,10 @@ release_io_asuscom(struct IsdnCardState *cs) static void reset_asuscom(struct IsdnCardState *cs) { - long flags; - if (cs->subtyp == ASUS_IPAC) writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x20); else byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */ - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); if (cs->subtyp == ASUS_IPAC) @@ -286,7 +281,6 @@ reset_asuscom(struct IsdnCardState *cs) writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_MASK, 0xc0); writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_PCFG, 0x12); } - restore_flags(flags); } static int diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c index 38a741a888a9..a87cfd0796d0 100644 --- a/drivers/isdn/hisax/avm_a1.c +++ b/drivers/isdn/hisax/avm_a1.c @@ -179,7 +179,6 @@ setup_avm_a1(struct IsdnCard *card) { u_char val; struct IsdnCardState *cs = card->cs; - long flags; char tmp[64]; strcpy(tmp, avm_revision); @@ -254,9 +253,7 @@ setup_avm_a1(struct IsdnCard *card) release_ioregs(cs, 0x1f); return (0); } - save_flags(flags); byteout(cs->hw.avm.cfg_reg, 0x0); - sti(); HZDELAY(HZ / 5 + 1); byteout(cs->hw.avm.cfg_reg, 0x1); HZDELAY(HZ / 5 + 1); @@ -269,7 +266,6 @@ setup_avm_a1(struct IsdnCard *card) HZDELAY(HZ / 5 + 1); byteout(cs->hw.avm.cfg_reg, 0x0); HZDELAY(HZ / 5 + 1); - restore_flags(flags); val = bytein(cs->hw.avm.cfg_reg); printk(KERN_INFO "AVM A1: Byte at %x is %x\n", diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c index d5d8d07ed24f..2f3f377400d6 100644 --- a/drivers/isdn/hisax/avm_a1p.c +++ b/drivers/isdn/hisax/avm_a1p.c @@ -57,116 +57,109 @@ #define bytein(addr) inb(addr) static const char *avm_revision = "$Revision: 2.7.6.2 $"; +static spinlock_t avm_a1p_lock = SPIN_LOCK_UNLOCKED; static inline u_char ReadISAC(struct IsdnCardState *cs, u_char offset) { - long flags; + unsigned long flags; u_char ret; offset -= 0x20; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset); ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); return ret; } static inline void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) { - long flags; + unsigned long flags; offset -= 0x20; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset); byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } static inline void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET); insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } static inline void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET); outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } static inline u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) { u_char ret; - long flags; + unsigned long flags; offset -= 0x20; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET, HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset); ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); return ret; } static inline void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) { - long flags; + unsigned long flags; offset -= 0x20; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET, HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset); byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } static inline void ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET, HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF); insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } static inline void WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_a1p_lock, flags); byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET, HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF); outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size); - restore_flags(flags); + spin_unlock_irqrestore(&avm_a1p_lock, flags); } /* @@ -253,7 +246,6 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) { u_char model, vers; struct IsdnCardState *cs = card->cs; - long flags; char tmp[64]; @@ -267,9 +259,7 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) cs->irq = card->para[0]; - save_flags(flags); outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0); - sti(); byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00); HZDELAY(HZ / 5 + 1); @@ -279,8 +269,6 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET, ASL0_W_TDISABLE|ASL0_W_TRESET); - restore_flags(flags); - model = bytein(cs->hw.avm.cfg_reg+MODREG_OFFSET); vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET); diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index a0681c24148e..7a5a885926e4 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -23,6 +23,7 @@ extern const char *CardType[]; static const char *avm_pci_rev = "$Revision: 1.22.6.6 $"; +static spinlock_t avm_pci_lock = SPIN_LOCK_UNLOCKED; #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 @@ -80,13 +81,12 @@ ReadISAC(struct IsdnCardState *cs, u_char offset) { register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; register u_char val; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outb(idx, cs->hw.avm.cfg_reg + 4); val = inb(cs->hw.avm.isac + (offset & 0xf)); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); return (val); } @@ -94,13 +94,12 @@ static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) { register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outb(idx, cs->hw.avm.cfg_reg + 4); outb(value, cs->hw.avm.isac + (offset & 0xf)); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } static void @@ -122,13 +121,12 @@ ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset) { register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; register u_int val; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outl(idx, cs->hw.avm.cfg_reg + 4); val = inl(cs->hw.avm.isac + offset); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); return (val); } @@ -136,13 +134,12 @@ static inline void WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value) { register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outl(idx, cs->hw.avm.cfg_reg + 4); outl(value, cs->hw.avm.isac + offset); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } static inline u_char @@ -150,13 +147,12 @@ ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset) { register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; register u_char val; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outb(idx, cs->hw.avm.cfg_reg + 4); val = inb(cs->hw.avm.isac + offset); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); return (val); } @@ -164,13 +160,12 @@ static inline void WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value) { register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1; - register long flags; + register unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); outb(idx, cs->hw.avm.cfg_reg + 4); outb(value, cs->hw.avm.isac + offset); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } static u_char @@ -200,7 +195,7 @@ void inline hdlc_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } void @@ -390,11 +385,10 @@ hdlc_fill_fifo(struct BCState *bcs) static void fill_hdlc(struct BCState *bcs) { - long flags; - save_flags(flags); - cli(); + unsigned long flags; + spin_lock_irqsave(&avm_pci_lock, flags); hdlc_fill_fifo(bcs); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } static inline void @@ -493,8 +487,7 @@ HDLC_irq_main(struct IsdnCardState *cs) long flags; struct BCState *bcs; - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); if (cs->subtyp == AVM_FRITZ_PCI) { stat = ReadHDLCPCI(cs, 0, HDLC_STATUS); } else { @@ -523,27 +516,26 @@ HDLC_irq_main(struct IsdnCardState *cs) } else HDLC_irq(bcs, stat); } - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } void hdlc_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&avm_pci_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.hdlc.count = 0; - restore_flags(flags); + spin_unlock_irqrestore(&avm_pci_lock, flags); st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); } break; @@ -716,11 +708,7 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs) static void reset_avmpcipnp(struct IsdnCardState *cs) { - long flags; - printk(KERN_INFO "AVM PCI/PnP: reset\n"); - save_flags(flags); - sti(); outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c index 31173d211133..75f361e241be 100644 --- a/drivers/isdn/hisax/bkm_a4t.c +++ b/drivers/isdn/hisax/bkm_a4t.c @@ -21,6 +21,7 @@ #include "bkm_ax.h" extern const char *CardType[]; +static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED; const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $"; @@ -29,16 +30,15 @@ static inline u_char readreg(unsigned int ale, unsigned long adr, u_char off) { register u_int ret; - long flags; + unsigned long flags; unsigned int *po = (unsigned int *) adr; /* Postoffice */ - save_flags(flags); - cli(); + spin_lock_irqsave(&bkm_a4t_lock, flags); *po = (GCS_2 | PO_WRITE | off); __WAITI20__(po); *po = (ale | PO_READ); __WAITI20__(po); ret = *po; - restore_flags(flags); + spin_unlock_irqrestore(&bkm_a4t_lock, flags); return ((unsigned char) ret); } @@ -56,15 +56,14 @@ readfifo(unsigned int ale, unsigned long adr, u_char off, u_char * data, int siz static inline void writereg(unsigned int ale, unsigned long adr, u_char off, u_char data) { - long flags; + unsigned long flags; unsigned int *po = (unsigned int *) adr; /* Postoffice */ - save_flags(flags); - cli(); + spin_lock_irqsave(&bkm_a4t_lock, flags); *po = (GCS_2 | PO_WRITE | off); __WAITI20__(po); *po = (ale | PO_WRITE | data); __WAITI20__(po); - restore_flags(flags); + spin_unlock_irqrestore(&bkm_a4t_lock, flags); } @@ -197,12 +196,8 @@ enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) static void reset_bkm(struct IsdnCardState *cs) { - long flags; - if (cs->typ == ISDN_CTYPE_BKM_A4T) { I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - save_flags(flags); - sti(); /* Issue the I20 soft reset */ pI20_Regs->i20SysControl = 0xFF; /* all in */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -229,7 +224,6 @@ reset_bkm(struct IsdnCardState *cs) g_A4T_ISAR_RES); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); - restore_flags(flags); } } diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index c4d5e8ba2c44..a0b4282dae01 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -25,7 +25,7 @@ #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ extern const char *CardType[]; - +static spinlock_t bkm_a8_lock = SPIN_LOCK_UNLOCKED; const char sct_quadro_revision[] = "$Revision: 1.14.6.7 $"; static const char *sct_quadro_subtypes[] = @@ -45,12 +45,11 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; - save_flags(flags); - cli(); + unsigned long flags; + spin_lock_irqsave(&bkm_a8_lock, flags); wordout(ale, off); ret = wordin(adr) & 0xFF; - restore_flags(flags); + spin_unlock_irqrestore(&bkm_a8_lock, flags); return (ret); } @@ -68,12 +67,11 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; - save_flags(flags); - cli(); + unsigned long flags; + spin_lock_irqsave(&bkm_a8_lock, flags); wordout(ale, off); wordout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&bkm_a8_lock, flags); } static inline void @@ -223,19 +221,14 @@ enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) static void reset_bkm(struct IsdnCardState *cs) { - long flags; - if (cs->subtyp == SCT_1) { wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) & ~4)); - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove the soft reset */ wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) | 4)); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); - restore_flags(flags); } } diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 565d774e42b2..79f2ae84865e 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -37,6 +37,7 @@ static void release_b_st(struct Channel *chanp); static struct Fsm callcfsm; static int chancount; +static spinlock_t callc_lock = SPIN_LOCK_UNLOCKED; /* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */ #define ALERT_REJECT 0 @@ -1803,8 +1804,7 @@ HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb) return 0; } else if (chanp->debug & 0x800) link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt,MAX_DATA_MEM); - save_flags(flags); - cli(); + spin_lock_irqsave(&callc_lock, flags); nskb = skb_clone(skb, GFP_ATOMIC); if (nskb) { nskb->truesize = nskb->len; @@ -1819,7 +1819,7 @@ HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb) dev_kfree_skb(skb); } else len = 0; - restore_flags(flags); + spin_unlock_irqrestore(&callc_lock, flags); } return (len); } diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 8def6d6218ff..dffa55531a81 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -99,6 +99,7 @@ const char *CardType[] = { }; void HiSax_closecard(int cardnr); +static spinlock_t hisax_config_lock = SPIN_LOCK_UNLOCKED; #ifdef CONFIG_HISAX_ELSA #define DEFAULT_CARD ISDN_CTYPE_ELSA @@ -708,14 +709,13 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, { /* if head == NULL the fmt contains the full info */ - long flags; + unsigned long flags; int count, i; u_char *p; isdn_ctrl ic; int len; - save_flags(flags); - cli(); + spin_lock_irqsave(&hisax_config_lock, flags); p = tmpbuf; if (head) { p += jiftime(p, jiffies); @@ -732,13 +732,13 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, if (!cs) { printk(KERN_WARNING "HiSax: No CardStatus for message %s", p); - restore_flags(flags); + spin_unlock_irqrestore(&hisax_config_lock, flags); return; } if (len > HISAX_STATUS_BUFSIZE) { printk(KERN_WARNING "HiSax: status overflow %d/%d\n", len, HISAX_STATUS_BUFSIZE); - restore_flags(flags); + spin_unlock_irqrestore(&hisax_config_lock, flags); return; } count = len; @@ -767,7 +767,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, count++; } #endif - restore_flags(flags); + spin_unlock_irqrestore(&hisax_config_lock, flags); if (count) { ic.command = ISDN_STAT_STAVAIL; ic.driver = cs->myid; @@ -787,16 +787,12 @@ void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) int ll_run(struct IsdnCardState *cs, int addfeatures) { - long flags; isdn_ctrl ic; - save_flags(flags); - cli(); ic.driver = cs->myid; ic.command = ISDN_STAT_RUN; cs->iif.features |= addfeatures; cs->iif.statcallb(&ic); - restore_flags(flags); return 0; } @@ -857,28 +853,23 @@ static void closecard(int cardnr) static int __devinit init_card(struct IsdnCardState *cs) { int irq_cnt, cnt = 3; - long flags; if (!cs->irq) return cs->cardmsg(cs, CARD_INIT, NULL); - save_flags(flags); - cli(); + irq_cnt = kstat_irqs(cs->irq); printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], cs->irq, irq_cnt); if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) { printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", cs->irq); - restore_flags(flags); return 1; } while (cnt) { cs->cardmsg(cs, CARD_INIT, NULL); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); /* Timeout 10ms */ schedule_timeout((10 * HZ) / 1000); - restore_flags(flags); printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], cs->irq, kstat_irqs(cs->irq)); if (kstat_irqs(cs->irq) == irq_cnt) { @@ -897,19 +888,15 @@ static int __devinit init_card(struct IsdnCardState *cs) return 0; } } - restore_flags(flags); return 3; } static int __devinit checkcard(int cardnr, char *id, int *busy_flag) { - long flags; int ret = 0; struct IsdnCard *card = cards + cardnr; struct IsdnCardState *cs; - save_flags(flags); - cli(); cs = kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); if (!cs) { printk(KERN_WARNING @@ -1173,7 +1160,6 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag) cs->tx_skb = NULL; cs->tx_cnt = 0; cs->event = 0; - cs->tqueue.data = cs; skb_queue_head_init(&cs->rq); skb_queue_head_init(&cs->sq); @@ -1216,7 +1202,6 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag) kfree(cs); card->cs = NULL; out: - restore_flags(flags); return ret; } @@ -1542,10 +1527,7 @@ static int __init HiSax_init(void) static void __exit HiSax_exit(void) { int cardnr = nrcards - 1; - long flags; - save_flags(flags); - cli(); while (cardnr >= 0) HiSax_closecard(cardnr--); Isdnl1Free(); @@ -1553,7 +1535,6 @@ static void __exit HiSax_exit(void) Isdnl2Free(); Isdnl3Free(); CallcFree(); - restore_flags(flags); printk(KERN_INFO "HiSax module removed\n"); } @@ -1756,7 +1737,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg); static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); static void hisax_bc_close(struct BCState *bcs); -static void hisax_bh(struct IsdnCardState *cs); +static void hisax_bh(void *data); static void EChannel_proc_rcv(struct hisax_d_if *d_if); int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], @@ -1788,7 +1769,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], hisax_d_if->cs = cs; cs->hw.hisax_d_if = hisax_d_if; cs->cardmsg = hisax_cardmsg; - INIT_WORK(&cs->tqueue, (void *) (void *) hisax_bh, NULL); + INIT_WORK(&cs->work, hisax_bh, cs); cs->channel[0].d_st->l1.l2l1 = hisax_d_l2l1; for (i = 0; i < 2; i++) { cs->bcs[i].BC_SetStack = hisax_bc_setstack; @@ -1817,11 +1798,12 @@ void hisax_unregister(struct hisax_d_if *hisax_d_if) static void hisax_sched_event(struct IsdnCardState *cs, int event) { cs->event |= 1 << event; - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } -static void hisax_bh(struct IsdnCardState *cs) +static void hisax_bh(void *data) { + struct IsdnCardState *cs = data; struct PStack *st; int pr; @@ -1843,7 +1825,7 @@ static void hisax_bh(struct IsdnCardState *cs) static void hisax_b_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static inline void D_L2L1(struct hisax_d_if *d_if, int pr, void *arg) diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 6bebe3feac8f..20ca4c4c1c6b 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -29,6 +29,7 @@ extern const char *CardType[]; const char *Diva_revision = "$Revision: 1.25.6.5 $"; +static spinlock_t diva_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -85,13 +86,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&diva_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&diva_lock, flags); return (ret); } @@ -108,13 +108,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&diva_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&diva_lock, flags); } static inline void @@ -408,13 +407,12 @@ MemwaitforXFW(struct IsdnCardState *cs, int hscx) static inline void MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&diva_lock, flags); MemwaitforCEC(cs, hscx); MemWriteHSCX(cs, hscx, HSCX_CMDR, data); - restore_flags(flags); + spin_unlock_irqrestore(&diva_lock, flags); } static void @@ -422,7 +420,7 @@ Memhscx_empty_fifo(struct BCState *bcs, int count) { u_char *ptr; struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; int cnt; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) @@ -435,8 +433,7 @@ Memhscx_empty_fifo(struct BCState *bcs, int count) bcs->hw.hscx.rcvidx = 0; return; } - save_flags(flags); - cli(); + spin_lock_irqsave(&diva_lock, flags); ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; cnt = count; while (cnt--) @@ -444,7 +441,7 @@ Memhscx_empty_fifo(struct BCState *bcs, int count) MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; bcs->hw.hscx.rcvidx += count; - restore_flags(flags); + spin_unlock_irqrestore(&diva_lock, flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -462,7 +459,7 @@ Memhscx_fill_fifo(struct BCState *bcs) int more, count, cnt; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; u_char *ptr,*p; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) @@ -481,8 +478,7 @@ Memhscx_fill_fifo(struct BCState *bcs) count = bcs->tx_skb->len; cnt = count; MemwaitforXFW(cs, bcs->hw.hscx.hscx); - save_flags(flags); - cli(); + spin_lock_irqsave(&diva_lock, flags); p = ptr = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt -= count; @@ -491,7 +487,7 @@ Memhscx_fill_fifo(struct BCState *bcs) memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, *p++); MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); - restore_flags(flags); + spin_unlock_irqrestore(&diva_lock, flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -753,10 +749,6 @@ release_io_diva(struct IsdnCardState *cs) static void reset_diva(struct IsdnCardState *cs) { - long flags; - - save_flags(flags); - sti(); if (cs->subtyp == DIVA_IPAC_ISA) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); set_current_state(TASK_UNINTERRUPTIBLE); @@ -803,7 +795,6 @@ reset_diva(struct IsdnCardState *cs) } byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); } - restore_flags(flags); } #define DIVA_ASSIGN 1 diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 460b183b3af6..600c959a6a49 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -32,6 +32,7 @@ #include <linux/serial_reg.h> extern const char *CardType[]; +static spinlock_t elsa_lock = SPIN_LOCK_UNLOCKED; const char *Elsa_revision = "$Revision: 2.26.6.6 $"; const char *Elsa_Types[] = @@ -145,13 +146,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_lock, flags); return (ret); } @@ -168,13 +168,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_lock, flags); } static inline void @@ -253,26 +252,24 @@ static inline u_char readitac(struct IsdnCardState *cs, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_lock, flags); byteout(cs->hw.elsa.ale, off); ret = bytein(cs->hw.elsa.itac); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_lock, flags); return (ret); } static inline void writeitac(struct IsdnCardState *cs, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_lock, flags); byteout(cs->hw.elsa.ale, off); byteout(cs->hw.elsa.itac, data); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_lock, flags); } static inline int @@ -486,8 +483,6 @@ release_io_elsa(struct IsdnCardState *cs) static void reset_elsa(struct IsdnCardState *cs) { - long flags; - if (cs->hw.elsa.timer) { /* Wait 1 Timer */ byteout(cs->hw.elsa.timer, 0); @@ -507,8 +502,6 @@ reset_elsa(struct IsdnCardState *cs) byteout(cs->hw.elsa.trig, 0xff); } if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - save_flags(flags); - sti(); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x20); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ @@ -516,7 +509,6 @@ reset_elsa(struct IsdnCardState *cs) set_current_state(TASK_UNINTERRUPTIBLE); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xc0); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - restore_flags(flags); if (cs->subtyp != ELSA_PCMCIA_IPAC) { writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x0); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0x3c); @@ -677,7 +669,6 @@ static int Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) { int ret = 0; - long flags; switch (mt) { case CARD_RESET: @@ -706,16 +697,13 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg) } else if (cs->subtyp == ELSA_QS3000PCI) { ret = 0; } else { - save_flags(flags); cs->hw.elsa.counter = 0; - sti(); cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT; cs->hw.elsa.status |= ELSA_TIMER_AKTIV; byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); byteout(cs->hw.elsa.timer, 0); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((110*HZ)/1000); - restore_flags(flags); cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT; byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); cs->hw.elsa.status &= ~ELSA_TIMER_AKTIV; @@ -798,7 +786,6 @@ probe_elsa_adr(unsigned int adr, int typ) { int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0, pc_2 = 0, pfp_1 = 0, pfp_2 = 0; - long flags; /* In case of the elsa pcmcia card, this region is in use, reserved for us by the card manager. So we do not check it @@ -809,8 +796,6 @@ probe_elsa_adr(unsigned int adr, int typ) adr); return (0); } - save_flags(flags); - cli(); for (i = 0; i < 16; i++) { in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ @@ -823,7 +808,6 @@ probe_elsa_adr(unsigned int adr, int typ) pfp_1 += 0x40 & in1; pfp_2 += 0x40 & in2; } - restore_flags(flags); printk(KERN_INFO "Elsa: Probing IO 0x%x", adr); if (65 == ++p16_1 * ++p16_2) { printk(" PCC-16/PCF found\n"); @@ -878,7 +862,6 @@ static struct pci_bus *pnp_c __devinitdata = NULL; int __devinit setup_elsa(struct IsdnCard *card) { - long flags; int bytecnt; u_char val, pci_rev; struct IsdnCardState *cs = card->cs; @@ -1170,10 +1153,7 @@ setup_elsa(struct IsdnCard *card) return (0); } } - save_flags(flags); - sti(); HZDELAY(1); /* wait >=10 ms */ - restore_flags(flags); if (TimerRun(cs)) { printk(KERN_WARNING "Elsa: timer do not run down\n"); release_io_elsa(cs); diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index 6ef49f05b299..336e7078a7c9 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -30,6 +30,7 @@ static u_char deb[32]; const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"}; const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"}; #endif +static spinlock_t elsa_ser_lock = SPIN_LOCK_UNLOCKED; static char *MInit_1 = "AT&F&C1E0&D2\r\0"; static char *MInit_2 = "ATL2M1S64=13\r\0"; @@ -134,14 +135,13 @@ static void change_speed(struct IsdnCardState *cs, int baud) serial_outp(cs, UART_IER, cs->hw.elsa.IER); debugl1(cs,"modem quot=0x%x", quot); - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_ser_lock, flags); serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ serial_outp(cs, UART_DLL, quot & 0xff); /* LS of divisor */ serial_outp(cs, UART_DLM, quot >> 8); /* MS of divisor */ serial_outp(cs, UART_LCR, cval); /* reset DLAB */ serial_inp(cs, UART_RX); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); } static int mstartup(struct IsdnCardState *cs) @@ -150,7 +150,7 @@ static int mstartup(struct IsdnCardState *cs) int retval=0; - save_flags(flags); cli(); + spin_lock_irqsave(&elsa_ser_lock, flags); /* * Clear the FIFO buffers and disable them @@ -207,7 +207,7 @@ static int mstartup(struct IsdnCardState *cs) change_speed(cs, BASE_BAUD); cs->hw.elsa.MFlag = 1; errout: - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); return retval; } @@ -224,7 +224,7 @@ static void mshutdown(struct IsdnCardState *cs) printk(KERN_DEBUG"Shutting down serial ...."); #endif - save_flags(flags); cli(); /* Disable interrupts */ + spin_lock_irqsave(&elsa_ser_lock, flags); /* Disable interrupts */ /* * clear delta_msr_wait queue to avoid mem leaks: we may free the irq @@ -245,7 +245,7 @@ static void mshutdown(struct IsdnCardState *cs) serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT)); serial_inp(cs, UART_RX); /* read data port to reset things */ - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); #ifdef SERIAL_DEBUG_OPEN printk(" done\n"); #endif @@ -256,14 +256,13 @@ write_modem(struct BCState *bcs) { int ret=0; struct IsdnCardState *cs = bcs->cs; int count, len, fp; - long flags; + unsigned long flags; if (!bcs->tx_skb) return 0; if (bcs->tx_skb->len <= 0) return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_ser_lock, flags); len = bcs->tx_skb->len; if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt) len = MAX_MODEM_BUF - cs->hw.elsa.transcnt; @@ -289,7 +288,7 @@ write_modem(struct BCState *bcs) { cs->hw.elsa.IER |= UART_IER_THRI; serial_outp(cs, UART_IER, cs->hw.elsa.IER); } - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); return(ret); } @@ -460,14 +459,13 @@ void modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { int count, fp; u_char *msg = buf; - long flags; + unsigned long flags; if (!len) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_ser_lock, flags); if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) { - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); return; } fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp; @@ -488,17 +486,16 @@ modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { cs->hw.elsa.IER |= UART_IER_THRI; serial_outp(cs, UART_IER, cs->hw.elsa.IER); } - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); } void modem_set_init(struct IsdnCardState *cs) { - long flags; + unsigned long flags; int timeout; #define RCV_DELAY 20000 - save_flags(flags); - sti(); + spin_lock_irqsave(&elsa_ser_lock, flags); modem_write_cmd(cs, MInit_1, strlen(MInit_1)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) @@ -541,17 +538,16 @@ modem_set_init(struct IsdnCardState *cs) { udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); } void modem_set_dial(struct IsdnCardState *cs, int outgoing) { - long flags; + unsigned long flags; int timeout; #define RCV_DELAY 20000 - save_flags(flags); - sti(); + spin_lock_irqsave(&elsa_ser_lock, flags); modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800)); timeout = 1000; while(timeout-- && cs->hw.elsa.transcnt) @@ -567,26 +563,25 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) { udelay(1000); debugl1(cs, "msi tout=%d", timeout); udelay(RCV_DELAY); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); } void modem_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; if (pr == (PH_DATA | REQUEST)) { - save_flags(flags); - cli(); + spin_lock_irqsave(&elsa_ser_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.hscx.count = 0; - restore_flags(flags); + spin_unlock_irqrestore(&elsa_ser_lock, flags); write_modem(st->l1.bcs); } } else if (pr == (PH_ACTIVATE | REQUEST)) { diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c index c6c486c93612..143389debdcb 100644 --- a/drivers/isdn/hisax/enternow_pci.c +++ b/drivers/isdn/hisax/enternow_pci.c @@ -75,7 +75,7 @@ const char *enternow_pci_rev = "$Revision: 1.1.2.1 $"; - +static spinlock_t enternow_pci_lock = SPIN_LOCK_UNLOCKED; /* *************************** I/O-Interface functions ************************************* */ @@ -137,13 +137,9 @@ static void dummywr(struct IsdnCardState *cs, int chan, BYTE off, BYTE value) static void reset_enpci(struct IsdnCardState *cs) { - long flags; - if (cs->debug & L1_DEB_ISAC) debugl1(cs, "enter:now PCI: reset"); - save_flags(flags); - sti(); /* Reset on, (also for AMD) */ cs->hw.njet.ctrl_reg = 0x07; OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); @@ -156,13 +152,11 @@ reset_enpci(struct IsdnCardState *cs) set_current_state(TASK_UNINTERRUPTIBLE); /* 80ms delay */ schedule_timeout((80*HZ)/1000); - restore_flags(flags); cs->hw.njet.auxd = 0; // LED-status cs->hw.njet.dmactrl = 0; OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off - } @@ -237,7 +231,7 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; BYTE sval, ir; - long flags; + unsigned long flags; if (!cs) { @@ -257,8 +251,7 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) /* DMA-Interrupt: B-channel-stuff */ /* set bits in sval to indicate which page is free */ - save_flags(flags); - cli(); + spin_lock_irqsave(&enternow_pci_lock, flags); /* set bits in sval to indicate which page is free */ if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ)) @@ -275,11 +268,11 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */ { if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - restore_flags(flags); + spin_unlock_irqrestore(&enternow_pci_lock, flags); return; } cs->hw.njet.irqstat0 = sval; - restore_flags(flags); + spin_unlock_irqrestore(&enternow_pci_lock, flags); if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) /* we have a read dma int */ @@ -290,7 +283,7 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) write_tiger(cs); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else - restore_flags(flags); + spin_unlock_irqrestore(&enternow_pci_lock, flags); } @@ -303,7 +296,7 @@ setup_enternow_pci(struct IsdnCard *card) int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; - long flags; + unsigned long flags; #if CONFIG_PCI #ifdef __BIG_ENDIAN diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index 37cce53235dd..2ad414bee102 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c @@ -22,6 +22,7 @@ extern const char *CardType[]; const char *gazel_revision = "$Revision: 2.11.6.7 $"; +static spinlock_t gazel_lock = SPIN_LOCK_UNLOCKED; #define R647 1 #define R685 2 @@ -72,26 +73,24 @@ static inline u_char readreg_ipac(unsigned int adr, u_short off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&gazel_lock, flags); byteout(adr, off); ret = bytein(adr + 4); - restore_flags(flags); + spin_unlock_irqrestore(&gazel_lock, flags); return ret; } static inline void writereg_ipac(unsigned int adr, u_short off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&gazel_lock, flags); byteout(adr, off); byteout(adr + 4, data); - restore_flags(flags); + spin_unlock_irqrestore(&gazel_lock, flags); } @@ -357,18 +356,14 @@ release_io_gazel(struct IsdnCardState *cs) static int reset_gazel(struct IsdnCardState *cs) { - long flags; unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg; switch (cs->subtyp) { case R647: - save_flags(flags); - cli(); writereg(addr, 0, 0); HZDELAY(10); writereg(addr, 0, 1); HZDELAY(2); - restore_flags(flags); break; case R685: plxcntrl = inl(addr + PLX_CNTRL); diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index 65b9e22913ee..72bddf88bbff 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c @@ -202,7 +202,7 @@ static void hfc_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static struct sk_buff @@ -608,8 +608,9 @@ setstack_2b(struct PStack *st, struct BCState *bcs) } static void -hfcd_bh(struct IsdnCardState *cs) +hfcd_bh(void *data) { + struct IsdnCardState *cs = data; /* struct PStack *stptr; */ if (!cs) @@ -645,7 +646,7 @@ void sched_event_D(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } static @@ -1127,7 +1128,7 @@ init2bds0(struct IsdnCardState *cs) cs->dbusytimer.function = (void *) hfc_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); - INIT_WORK(&cs->tqueue, (void *) (void *) hfcd_bh, NULL); + INIT_WORK(&cs->work, hfcd_bh, cs); if (!cs->hw.hfcD.send) cs->hw.hfcD.send = init_send_hfcd(16); if (!cs->bcs[0].hw.hfc.send) diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index f6c39022701d..2605c29776d7 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -86,7 +86,7 @@ void hfc_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static void diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index e606de8c5bf1..eb1e71cd78ca 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -194,7 +194,7 @@ static void sched_event_D_pci(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } /*********************************/ @@ -204,7 +204,7 @@ static void hfcpci_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } /************************************************/ @@ -1535,8 +1535,9 @@ setstack_2b(struct PStack *st, struct BCState *bcs) /* handle L1 state changes */ /***************************/ static void -hfcpci_bh(struct IsdnCardState *cs) +hfcpci_bh(void *data) { + struct IsdnCardState *cs = data; unsigned long flags; /* struct PStack *stptr; */ @@ -1622,7 +1623,7 @@ inithfcpci(struct IsdnCardState *cs) cs->dbusytimer.function = (void *) hfcpci_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); - INIT_WORK(&cs->tqueue, (void *) (void *) hfcpci_bh, NULL); + INIT_WORK(&cs->work, hfcpci_bh, cs); cs->BC_Send_Data = &hfcpci_send_data; cs->bcs[0].BC_SetStack = setstack_2b; cs->bcs[1].BC_SetStack = setstack_2b; diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index dd8172c5443c..0a3c5901aa14 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -464,7 +464,7 @@ static void sched_event_D_sx(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } /*********************************/ @@ -474,7 +474,7 @@ static void hfcsx_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } /************************************************/ @@ -1323,8 +1323,9 @@ setstack_2b(struct PStack *st, struct BCState *bcs) /* handle L1 state changes */ /***************************/ static void -hfcsx_bh(struct IsdnCardState *cs) +hfcsx_bh(void *data) { + struct IsdnCardState *cs = data; unsigned long flags; /* struct PStack *stptr; */ @@ -1410,7 +1411,7 @@ inithfcsx(struct IsdnCardState *cs) cs->dbusytimer.function = (void *) hfcsx_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); - INIT_WORK(&cs->tqueue, (void *) (void *) hfcsx_bh, NULL); + INIT_WORK(&cs->work, hfcsx_bh, cs); cs->BC_Send_Data = &hfcsx_send_data; cs->bcs[0].BC_SetStack = setstack_2b; cs->bcs[1].BC_SetStack = setstack_2b; diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index ed9b26af61c4..a627304a72c1 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c @@ -64,15 +64,11 @@ release_io_hfcs(struct IsdnCardState *cs) static void reset_hfcs(struct IsdnCardState *cs) { - long flags; - printk(KERN_INFO "HFCS: resetting card\n"); cs->hw.hfcD.cirm = HFCD_RESET; if (cs->typ == ISDN_CTYPE_TELES3C) cs->hw.hfcD.cirm |= HFCD_MEM8K; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset On */ - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); cs->hw.hfcD.cirm = 0; @@ -103,14 +99,11 @@ reset_hfcs(struct IsdnCardState *cs) cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */ cs->hw.hfcD.sctrl = 0; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl); - restore_flags(flags); } static int hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) { - long flags; - if (cs->debug & L1_DEB_ISAC) debugl1(cs, "HFCS: card_msg %x", mt); switch (mt) { @@ -124,14 +117,11 @@ hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) cs->hw.hfcD.timer.expires = jiffies + 75; add_timer(&cs->hw.hfcD.timer); init2bds0(cs); - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((80*HZ)/1000); cs->hw.hfcD.ctmt |= HFCD_TIM800; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); - restore_flags(flags); return(0); case CARD_TEST: return(0); diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index dceac063b896..e692e6468aa4 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -453,8 +453,8 @@ struct amd7930_hw { int rv_buff_out; struct sk_buff *rv_skb; struct hdlc_state *hdlc_state; - struct work_struct tq_rcv; - struct work_struct tq_xmt; + struct work_struct rcv_work; + struct work_struct xmt_work; }; #define BC_FLG_INIT 1 @@ -495,7 +495,7 @@ struct BCState { u_char *blog; u_char *conmsg; struct timer_list transbusy; - struct work_struct tqueue; + struct work_struct work; unsigned long event; int (*BC_SetStack) (struct PStack *, struct BCState *); void (*BC_Close) (struct BCState *); @@ -954,7 +954,7 @@ struct IsdnCardState { struct sk_buff *tx_skb; int tx_cnt; long event; - struct work_struct tqueue; + struct work_struct work; struct timer_list dbusytimer; #ifdef ERROR_STATISTIC int err_crc; diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c index 0770479e41d0..174be03de2e1 100644 --- a/drivers/isdn/hisax/hscx.c +++ b/drivers/isdn/hisax/hscx.c @@ -95,7 +95,7 @@ void hscx_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } void diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index aee1cca364d2..e97d962155c5 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c @@ -23,6 +23,7 @@ #define DBUSY_TIMER_VALUE 80 #define ARCOFI_USE 0 +static spinlock_t icc_lock = SPIN_LOCK_UNLOCKED; static char *ICCVer[] __initdata = {"2070 A1/A3", "2070 B1", "2070 B2/B3", "2070 V2.4"}; @@ -77,8 +78,9 @@ icc_new_ph(struct IsdnCardState *cs) } static void -icc_bh(struct IsdnCardState *cs) +icc_bh(void *data) { + struct IsdnCardState *cs = data; struct PStack *stptr; if (!cs) @@ -112,7 +114,7 @@ void icc_empty_fifo(struct IsdnCardState *cs, int count) { u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "icc_empty_fifo"); @@ -127,11 +129,10 @@ icc_empty_fifo(struct IsdnCardState *cs, int count) } ptr = cs->rcvbuf + cs->rcvidx; cs->rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&icc_lock, flags); cs->readisacfifo(cs, ptr, count); cs->writeisac(cs, ICC_CMDR, 0x80); - restore_flags(flags); + spin_unlock_irqrestore(&icc_lock, flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -146,7 +147,7 @@ icc_fill_fifo(struct IsdnCardState *cs) { int count, more; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "icc_fill_fifo"); @@ -163,8 +164,7 @@ icc_fill_fifo(struct IsdnCardState *cs) more = !0; count = 32; } - save_flags(flags); - cli(); + spin_lock_irqsave(&icc_lock, flags); ptr = cs->tx_skb->data; skb_pull(cs->tx_skb, count); cs->tx_cnt += count; @@ -177,7 +177,7 @@ icc_fill_fifo(struct IsdnCardState *cs) init_timer(&cs->dbusytimer); cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&cs->dbusytimer); - restore_flags(flags); + spin_unlock_irqrestore(&icc_lock, flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -191,7 +191,7 @@ void icc_sched_event(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } void @@ -200,7 +200,7 @@ icc_interrupt(struct IsdnCardState *cs, u_char val) u_char exval, v1; struct sk_buff *skb; unsigned int count; - long flags; + unsigned long flags; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ICC interrupt %x", val); @@ -227,8 +227,7 @@ icc_interrupt(struct IsdnCardState *cs, u_char val) if (count == 0) count = 32; icc_empty_fifo(cs, count); - save_flags(flags); - cli(); + spin_lock_irqsave(&icc_lock, flags); if ((count = cs->rcvidx) > 0) { cs->rcvidx = 0; if (!(skb = alloc_skb(count, GFP_ATOMIC))) @@ -238,7 +237,7 @@ icc_interrupt(struct IsdnCardState *cs, u_char val) skb_queue_tail(&cs->rq, skb); } } - restore_flags(flags); + spin_unlock_irqrestore(&icc_lock, flags); } cs->rcvidx = 0; icc_sched_event(cs, D_RCVBUFREADY); @@ -624,7 +623,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) void __init initicc(struct IsdnCardState *cs) { - INIT_WORK(&cs->tqueue, (void *) (void *) icc_bh, NULL); + INIT_WORK(&cs->work, icc_bh, cs); cs->setstack_d = setstack_icc; cs->DC_Close = DC_Close_icc; cs->dc.icc.mon_tx = NULL; diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 57755ac9c919..f027466f23ad 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -23,7 +23,7 @@ #define MAX_DFRAME_LEN_L1 300 #define B_FIFO_SIZE 64 #define D_FIFO_SIZE 32 - +static spinlock_t ipacx_lock = SPIN_LOCK_UNLOCKED; // ipacx interrupt mask values #define _MASK_IMASK 0x2E // global mask @@ -38,7 +38,7 @@ static inline void cic_int(struct IsdnCardState *cs); static void dch_l2l1(struct PStack *st, int pr, void *arg); static void dbusy_timer_handler(struct IsdnCardState *cs); static void ipacx_new_ph(struct IsdnCardState *cs); -static void dch_bh(struct IsdnCardState *cs); +static void dch_bh(void *data); static void dch_sched_event(struct IsdnCardState *cs, int event); static void dch_empty_fifo(struct IsdnCardState *cs, int count); static void dch_fill_fifo(struct IsdnCardState *cs); @@ -272,8 +272,9 @@ ipacx_new_ph(struct IsdnCardState *cs) // bottom half handler for D channel //---------------------------------------------------------- static void -dch_bh(struct IsdnCardState *cs) +dch_bh(void *data) { + struct IsdnCardState *cs = data; struct PStack *st; if (!cs) return; @@ -305,7 +306,7 @@ static void dch_sched_event(struct IsdnCardState *cs, int event) { set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } //---------------------------------------------------------- @@ -314,7 +315,7 @@ dch_sched_event(struct IsdnCardState *cs, int event) static void dch_empty_fifo(struct IsdnCardState *cs, int count) { - long flags; + unsigned long flags; u_char *ptr; if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO)) @@ -332,11 +333,10 @@ dch_empty_fifo(struct IsdnCardState *cs, int count) ptr = cs->rcvbuf + cs->rcvidx; cs->rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); cs->readisacfifo(cs, ptr, count); cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); if (cs->debug &L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -353,7 +353,7 @@ dch_empty_fifo(struct IsdnCardState *cs, int count) static void dch_fill_fifo(struct IsdnCardState *cs) { - long flags; + unsigned long flags; int count; u_char cmd, *ptr; @@ -371,8 +371,7 @@ dch_fill_fifo(struct IsdnCardState *cs) cmd = 0x0A; // XTF | XME } - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); ptr = cs->tx_skb->data; skb_pull(cs->tx_skb, count); cs->tx_cnt += count; @@ -387,7 +386,7 @@ dch_fill_fifo(struct IsdnCardState *cs) init_timer(&cs->dbusytimer); cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&cs->dbusytimer); - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); if (cs->debug &L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -406,7 +405,7 @@ dch_int(struct IsdnCardState *cs) { struct sk_buff *skb; u_char istad, rstad; - long flags; + unsigned long flags; int count; istad = cs->readisac(cs, IPACX_ISTAD); @@ -430,8 +429,7 @@ dch_int(struct IsdnCardState *cs) count &= D_FIFO_SIZE-1; if (count == 0) count = D_FIFO_SIZE; dch_empty_fifo(cs, count); - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); if ((count = cs->rcvidx) > 0) { cs->rcvidx = 0; if (!(skb = dev_alloc_skb(count))) @@ -441,7 +439,7 @@ dch_int(struct IsdnCardState *cs) skb_queue_tail(&cs->rq, skb); } } - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); } cs->rcvidx = 0; dch_sched_event(cs, D_RCVBUFREADY); @@ -510,7 +508,7 @@ dch_init(struct IsdnCardState *cs) { printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n"); - INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs); + INIT_WORK(&cs->work, dch_bh, cs); cs->setstack_d = dch_setstack; cs->dbusytimer.function = (void *) dbusy_timer_handler; @@ -535,20 +533,19 @@ static void bch_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); } else { st->l1.bcs->tx_skb = skb; set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.hscx.count = 0; - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); bch_fill_fifo(st->l1.bcs); } break; @@ -593,7 +590,7 @@ static void bch_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } //---------------------------------------------------------- @@ -604,7 +601,7 @@ bch_empty_fifo(struct BCState *bcs, int count) { u_char *ptr, hscx; struct IsdnCardState *cs; - long flags; + unsigned long flags; int cnt; cs = bcs->cs; @@ -622,8 +619,7 @@ bch_empty_fifo(struct BCState *bcs, int count) } // Read data uninterruptible - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; cnt = count; while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB); @@ -631,7 +627,7 @@ bch_empty_fifo(struct BCState *bcs, int count) ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; bcs->hw.hscx.rcvidx += count; - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); if (cs->debug &L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -651,7 +647,7 @@ bch_fill_fifo(struct BCState *bcs) struct IsdnCardState *cs; int more, count, cnt; u_char *ptr, *p, hscx; - long flags; + unsigned long flags; cs = bcs->cs; if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO)) @@ -670,15 +666,14 @@ bch_fill_fifo(struct BCState *bcs) } cnt = count; - save_flags(flags); - cli(); + spin_lock_irqsave(&ipacx_lock, flags); p = ptr = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt -= count; bcs->hw.hscx.count += count; while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++); cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a)); - restore_flags(flags); + spin_unlock_irqrestore(&ipacx_lock, flags); if (cs->debug &L1_DEB_HSCX_FIFO) { char *t = bcs->blog; diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index f90ee9a78bd0..a23f1184d4f5 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -22,6 +22,7 @@ #define DBUSY_TIMER_VALUE 80 #define ARCOFI_USE 1 +static spinlock_t isac_lock = SPIN_LOCK_UNLOCKED; static char *ISACVer[] __devinitdata = {"2086/2186 V1.1", "2085 B1", "2085 B2", @@ -81,8 +82,9 @@ isac_new_ph(struct IsdnCardState *cs) } static void -isac_bh(struct IsdnCardState *cs) +isac_bh(void *data) { + struct IsdnCardState *cs = data; struct PStack *stptr; if (!cs) @@ -116,7 +118,7 @@ void isac_empty_fifo(struct IsdnCardState *cs, int count) { u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "isac_empty_fifo"); @@ -131,11 +133,10 @@ isac_empty_fifo(struct IsdnCardState *cs, int count) } ptr = cs->rcvbuf + cs->rcvidx; cs->rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&isac_lock, flags); cs->readisacfifo(cs, ptr, count); cs->writeisac(cs, ISAC_CMDR, 0x80); - restore_flags(flags); + spin_unlock_irqrestore(&isac_lock, flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -150,7 +151,7 @@ isac_fill_fifo(struct IsdnCardState *cs) { int count, more; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "isac_fill_fifo"); @@ -167,8 +168,7 @@ isac_fill_fifo(struct IsdnCardState *cs) more = !0; count = 32; } - save_flags(flags); - cli(); + spin_lock_irqsave(&isac_lock, flags); ptr = cs->tx_skb->data; skb_pull(cs->tx_skb, count); cs->tx_cnt += count; @@ -181,7 +181,7 @@ isac_fill_fifo(struct IsdnCardState *cs) init_timer(&cs->dbusytimer); cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&cs->dbusytimer); - restore_flags(flags); + spin_unlock_irqrestore(&isac_lock, flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -195,7 +195,7 @@ void isac_sched_event(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } void @@ -204,7 +204,7 @@ isac_interrupt(struct IsdnCardState *cs, u_char val) u_char exval, v1; struct sk_buff *skb; unsigned int count; - long flags; + unsigned long flags; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC interrupt %x", val); @@ -231,8 +231,7 @@ isac_interrupt(struct IsdnCardState *cs, u_char val) if (count == 0) count = 32; isac_empty_fifo(cs, count); - save_flags(flags); - cli(); + spin_lock_irqsave(&isac_lock, flags); if ((count = cs->rcvidx) > 0) { cs->rcvidx = 0; if (!(skb = alloc_skb(count, GFP_ATOMIC))) @@ -242,7 +241,7 @@ isac_interrupt(struct IsdnCardState *cs, u_char val) skb_queue_tail(&cs->rq, skb); } } - restore_flags(flags); + spin_unlock_irqrestore(&isac_lock, flags); } cs->rcvidx = 0; isac_sched_event(cs, D_RCVBUFREADY); @@ -626,7 +625,7 @@ dbusy_timer_handler(struct IsdnCardState *cs) void __devinit initisac(struct IsdnCardState *cs) { - INIT_WORK(&cs->tqueue, (void *) (void *) isac_bh, NULL); + INIT_WORK(&cs->work, isac_bh, cs); cs->setstack_d = setstack_isac; cs->DC_Close = DC_Close_isac; cs->dc.isac.mon_tx = NULL; diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 6eec59bc3207..ec5ec93c38f8 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -28,7 +28,7 @@ const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146}; void isar_setup(struct IsdnCardState *cs); static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para); static inline void ll_deliver_faxstat(struct BCState *bcs, u_char status); - +static spinlock_t isar_lock = SPIN_LOCK_UNLOCKED; static inline int waitforHIA(struct IsdnCardState *cs, int timeout) { @@ -47,7 +47,7 @@ int sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, u_char *msg) { - long flags; + unsigned long flags; int i; if (!waitforHIA(cs, 4000)) @@ -56,8 +56,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, if (cs->debug & L1_DEB_HSCX) debugl1(cs, "sendmsg(%02x,%02x,%d)", his, creg, len); #endif - save_flags(flags); - cli(); + spin_lock_irqsave(&isar_lock, flags); cs->BC_Write_Reg(cs, 0, ISAR_CTRL_H, creg); cs->BC_Write_Reg(cs, 0, ISAR_CTRL_L, len); cs->BC_Write_Reg(cs, 0, ISAR_WADR, 0); @@ -81,7 +80,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, #endif } cs->BC_Write_Reg(cs, 1, ISAR_HIS, his); - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); waitforHIA(cs, 10000); return(1); } @@ -134,7 +133,7 @@ waitrecmsg(struct IsdnCardState *cs, u_char *len, u_char *msg, int maxdelay) { int timeout = 0; - long flags; + unsigned long flags; struct isar_reg *ir = cs->bcs[0].hw.isar.reg; @@ -145,12 +144,11 @@ waitrecmsg(struct IsdnCardState *cs, u_char *len, printk(KERN_WARNING"isar recmsg IRQSTA timeout\n"); return(0); } - save_flags(flags); - cli(); + spin_lock_irqsave(&isar_lock, flags); get_irq_infos(cs, ir); rcv_mbox(cs, ir, msg); *len = ir->clsb; - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); return(1); } @@ -192,7 +190,7 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf) u_short sadr, left, *sp; u_char *p = buf; u_char *msg, *tmpmsg, *mp, tmp[64]; - long flags; + unsigned long flags; struct isar_reg *ireg = cs->bcs[0].hw.isar.reg; struct {u_short sadr; @@ -346,8 +344,7 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf) /* NORMAL mode entered */ /* Enable IRQs of ISAR */ cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, ISAR_IRQSTA); - save_flags(flags); - sti(); + spin_lock_irqsave(&isar_lock, flags); cnt = 1000; /* max 1s */ while ((!ireg->bstat) && cnt) { udelay(1000); @@ -415,7 +412,7 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf) isar_setup(cs); ret = 0; reterrflg: - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); reterror: cs->debug = debug; if (ret) @@ -432,8 +429,10 @@ extern void BChannel_bh(struct BCState *); #define B_LL_OK 10 static void -isar_bh(struct BCState *bcs) +isar_bh(void *data) { + struct BCState *bcs = data; + BChannel_bh(bcs); if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); @@ -447,7 +446,7 @@ static void isar_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static inline void @@ -669,7 +668,7 @@ isar_fill_fifo(struct BCState *bcs) int count; u_char msb; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "isar_fill_fifo"); @@ -687,8 +686,7 @@ isar_fill_fifo(struct BCState *bcs) count = bcs->tx_skb->len; msb = HDLC_FED; } - save_flags(flags); - cli(); + spin_lock_irqsave(&isar_lock, flags); ptr = bcs->tx_skb->data; if (!bcs->hw.isar.txcnt) { msb |= HDLC_FST; @@ -739,7 +737,7 @@ isar_fill_fifo(struct BCState *bcs) printk(KERN_ERR"isar_fill_fifo mode(%x) error\n", bcs->mode); break; } - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); } inline @@ -1163,12 +1161,11 @@ static char debbuf[128]; void isar_int_main(struct IsdnCardState *cs) { - long flags; + unsigned long flags; struct isar_reg *ireg = cs->bcs[0].hw.isar.reg; struct BCState *bcs; - save_flags(flags); - cli(); + spin_lock_irqsave(&isar_lock, flags); get_irq_infos(cs, ireg); switch (ireg->iis & ISAR_IIS_MSCMSD) { case ISAR_IIS_RDATA: @@ -1254,7 +1251,7 @@ isar_int_main(struct IsdnCardState *cs) ireg->iis, ireg->cmsb, ireg->clsb); break; } - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); } static void @@ -1560,7 +1557,7 @@ isar_setup(struct IsdnCardState *cs) cs->bcs[i].mode = 0; cs->bcs[i].hw.isar.dpath = i + 1; modeisar(&cs->bcs[i], 0, 0); - INIT_WORK(&cs->bcs[i].tqueue, (void *) (void *) isar_bh, NULL); + INIT_WORK(&cs->bcs[i].work, isar_bh, &cs->bcs[i]); } } @@ -1568,22 +1565,21 @@ void isar_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&isar_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); if (st->l1.bcs->cs->debug & L1_DEB_HSCX) debugl1(st->l1.bcs->cs, "DRQ set BC_FLG_BUSY"); st->l1.bcs->hw.isar.txcnt = 0; - restore_flags(flags); + spin_unlock_irqrestore(&isar_lock, flags); st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); } break; diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index 22643af00e4b..9ffdb7a423a7 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c @@ -299,10 +299,10 @@ BChannel_proc_rcv(struct BCState *bcs) } void -BChannel_bh(struct BCState *bcs) +BChannel_bh(void *data) { - if (!bcs) - return; + struct BCState *bcs = data; + if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event)) BChannel_proc_rcv(bcs); if (test_and_clear_bit(B_XMTBUFREADY, &bcs->event)) @@ -345,7 +345,7 @@ init_bcstate(struct IsdnCardState *cs, bcs->cs = cs; bcs->channel = bc; - INIT_WORK(&bcs->tqueue, (void *) (void *) BChannel_bh, bcs); + INIT_WORK(&bcs->work, BChannel_bh, bcs); bcs->BC_SetStack = NULL; bcs->BC_Close = NULL; bcs->Flag = 0; diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 87ead71602b7..a9df21b94d8a 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -20,7 +20,7 @@ #include "isdnl2.h" const char *l2_revision = "$Revision: 2.25.6.4 $"; - +static spinlock_t isdnl2_lock = SPIN_LOCK_UNLOCKED; static void l2m_debug(struct FsmInst *fi, char *fmt, ...); static struct Fsm l2fsm; @@ -1256,7 +1256,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) u_char header[MAX_HEADER_LEN]; int i; int unsigned p1; - long flags; + unsigned long flags; if (!cansend(st)) return; @@ -1265,8 +1265,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) if (!skb) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&isdnl2_lock, flags); if(test_bit(FLG_MOD128, &l2->flag)) p1 = (l2->vs - l2->va) % 128; else @@ -1289,7 +1288,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) header[i++] = (l2->vr << 5) | (l2->vs << 1); l2->vs = (l2->vs + 1) % 8; } - restore_flags(flags); + spin_unlock_irqrestore(&isdnl2_lock, flags); p1 = skb->data - skb->head; if (p1 >= i) diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index 7cb12d598cdc..59d506a5522a 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c @@ -134,19 +134,14 @@ release_io_isurf(struct IsdnCardState *cs) static void reset_isurf(struct IsdnCardState *cs, u_char chips) { - long flags; - printk(KERN_INFO "ISurf: resetting card\n"); byteout(cs->hw.isurf.reset, chips); /* Reset On */ - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); byteout(cs->hw.isurf.reset, ISURF_ISAR_EA); /* Reset Off */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); - restore_flags(flags); } static int diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index 314b84f89d9a..2cdeb86d44f7 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c @@ -26,6 +26,7 @@ extern const char *CardType[]; const char *ix1_revision = "$Revision: 2.10.6.2 $"; +static spinlock_t ix1_micro_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -43,13 +44,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&ix1_micro_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&ix1_micro_lock, flags); return (ret); } @@ -66,13 +66,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&ix1_micro_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&ix1_micro_lock, flags); } static inline void @@ -184,19 +183,15 @@ release_io_ix1micro(struct IsdnCardState *cs) static void ix1_reset(struct IsdnCardState *cs) { - long flags; int cnt; /* reset isac */ - save_flags(flags); cnt = 3 * (HZ / 10) + 1; - sti(); while (cnt--) { byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 1); HZDELAY(1); /* wait >=10 ms */ } byteout(cs->hw.ix1.cfg_reg + SPECIAL_PORT_OFFSET, 0); - restore_flags(flags); } static int diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index b3d75918e907..2fa2f12600fd 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -18,6 +18,7 @@ #include "isdnl1.h" #include <linux/interrupt.h> +static spinlock_t jade_lock = SPIN_LOCK_UNLOCKED; int __init JadeVersion(struct IsdnCardState *cs, char *s) @@ -50,10 +51,9 @@ static void jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value) { int to = 50; - long flags; + unsigned long flags; u_char ret; - save_flags(flags); - cli(); + spin_lock_irqsave(&jade_lock, flags); /* Write the data */ cs->BC_Write_Reg(cs, -1, COMM_JADE+1, value); /* Say JADE we wanna write indirect reg 'reg' */ @@ -68,12 +68,12 @@ jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value) /* Got acknowledge */ break; if (!to) { - restore_flags(flags); + spin_unlock_irqrestore(&jade_lock, flags); printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value); return; } } - restore_flags(flags); + spin_unlock_irqrestore(&jade_lock, flags); } @@ -138,27 +138,26 @@ void jade_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static void jade_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&jade_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&jade_lock, flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.hscx.count = 0; - restore_flags(flags); + spin_unlock_irqrestore(&jade_lock, flags); st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); } break; diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c index e81547acf36f..79a72d372d61 100644 --- a/drivers/isdn/hisax/jade_irq.c +++ b/drivers/isdn/hisax/jade_irq.c @@ -9,6 +9,7 @@ * of the GNU General Public License, incorporated herein by reference. * */ +static spinlock_t jade_irq_lock = SPIN_LOCK_UNLOCKED; static inline void waitforCEC(struct IsdnCardState *cs, int jade, int reg) @@ -33,13 +34,12 @@ waitforXFW(struct IsdnCardState *cs, int jade) static inline void WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&jade_irq_lock, flags); waitforCEC(cs, jade, reg); WRITEJADE(cs, jade, reg, data); - restore_flags(flags); + spin_unlock_irqrestore(&jade_irq_lock, flags); } @@ -49,7 +49,7 @@ jade_empty_fifo(struct BCState *bcs, int count) { u_char *ptr; struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "jade_empty_fifo"); @@ -63,11 +63,10 @@ jade_empty_fifo(struct BCState *bcs, int count) } ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; bcs->hw.hscx.rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&jade_irq_lock, flags); READJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC); - restore_flags(flags); + spin_unlock_irqrestore(&jade_irq_lock, flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -85,7 +84,7 @@ jade_fill_fifo(struct BCState *bcs) int more, count; int fifo_size = 32; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "jade_fill_fifo"); @@ -103,15 +102,14 @@ jade_fill_fifo(struct BCState *bcs) count = bcs->tx_skb->len; waitforXFW(cs, bcs->hw.hscx.hscx); - save_flags(flags); - cli(); + spin_lock_irqsave(&jade_irq_lock, flags); ptr = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt -= count; bcs->hw.hscx.count += count; WRITEJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, more ? jadeXCMD_XF : (jadeXCMD_XF|jadeXCMD_XME)); - restore_flags(flags); + spin_unlock_irqrestore(&jade_irq_lock, flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index c066e544c090..585e7ffe3992 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -27,6 +27,7 @@ extern char *HiSax_getrev(const char *revision); const char *dss1_revision = "$Revision: 2.30.6.2 $"; +static spinlock_t l3dss1_lock = SPIN_LOCK_UNLOCKED; #define EXT_BEARER_CAPS 1 @@ -53,8 +54,7 @@ static unsigned char new_invoke_id(struct PStack *p) i = 32; /* maximum search depth */ - save_flags(flags); - cli(); + spin_lock_irqsave(&l3dss1_lock, flags); retval = p->prot.dss1.last_invoke_id + 1; /* try new id */ while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) { @@ -68,7 +68,7 @@ static unsigned char new_invoke_id(struct PStack *p) retval = 0; p->prot.dss1.last_invoke_id = retval; p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7)); - restore_flags(flags); + spin_unlock_irqrestore(&l3dss1_lock, flags); return(retval); } /* new_invoke_id */ @@ -81,10 +81,9 @@ static void free_invoke_id(struct PStack *p, unsigned char id) if (!id) return; /* 0 = invalid value */ - save_flags(flags); - cli(); + spin_lock_irqsave(&l3dss1_lock, flags); p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7)); - restore_flags(flags); + spin_unlock_irqrestore(&l3dss1_lock, flags); } /* free_invoke_id */ diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 42fce1c65ab3..0b9332c9597b 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -25,6 +25,7 @@ extern char *HiSax_getrev(const char *revision); const char *ni1_revision = "$Revision: 2.5.6.3 $"; +static spinlock_t l3ni1_lock = SPIN_LOCK_UNLOCKED; #define EXT_BEARER_CAPS 1 @@ -51,8 +52,7 @@ static unsigned char new_invoke_id(struct PStack *p) i = 32; /* maximum search depth */ - save_flags(flags); - cli(); + spin_lock_irqsave(&l3ni1_lock, flags); retval = p->prot.ni1.last_invoke_id + 1; /* try new id */ while ((i) && (p->prot.ni1.invoke_used[retval >> 3] == 0xFF)) { @@ -66,7 +66,7 @@ static unsigned char new_invoke_id(struct PStack *p) retval = 0; p->prot.ni1.last_invoke_id = retval; p->prot.ni1.invoke_used[retval >> 3] |= (1 << (retval & 7)); - restore_flags(flags); + spin_unlock_irqrestore(&l3ni1_lock, flags); return(retval); } /* new_invoke_id */ @@ -79,10 +79,9 @@ static void free_invoke_id(struct PStack *p, unsigned char id) if (!id) return; /* 0 = invalid value */ - save_flags(flags); - cli(); + spin_lock_irqsave(&l3ni1_lock, flags); p->prot.ni1.invoke_used[id >> 3] &= ~(1 << (id & 7)); - restore_flags(flags); + spin_unlock_irqrestore(&l3ni1_lock, flags); } /* free_invoke_id */ diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c index 7e58a68138c1..97d94239927c 100644 --- a/drivers/isdn/hisax/mic.c +++ b/drivers/isdn/hisax/mic.c @@ -19,6 +19,7 @@ extern const char *CardType[]; const char *mic_revision = "$Revision: 1.10.6.2 $"; +static spinlock_t mic_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -34,13 +35,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&mic_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&mic_lock, flags); return (ret); } @@ -58,13 +58,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&mic_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&mic_lock, flags); } static inline void diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index 525cd6544e79..2fb306def1db 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -26,37 +26,36 @@ #include "netjet.h" const char *NETjet_revision = "$Revision: 1.24.6.6 $"; +static spinlock_t netjet_lock = SPIN_LOCK_UNLOCKED; /* Interface functions */ u_char NETjet_ReadIC(struct IsdnCardState *cs, u_char offset) { - long flags; + unsigned long flags; u_char ret; - save_flags(flags); - cli(); + spin_lock_irqsave(&netjet_lock, flags); cs->hw.njet.auxd &= 0xfc; cs->hw.njet.auxd |= (offset>>4) & 3; byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2)); - restore_flags(flags); + spin_unlock_irqrestore(&netjet_lock, flags); return(ret); } void NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&netjet_lock, flags); cs->hw.njet.auxd &= 0xfc; cs->hw.njet.auxd |= (offset>>4) & 3; byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value); - restore_flags(flags); + spin_unlock_irqrestore(&netjet_lock, flags); } void @@ -434,7 +433,7 @@ static void got_frame(struct BCState *bcs, int count) { skb_queue_tail(&bcs->rqueue, skb); } bcs->event |= 1 << B_RCVBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME) printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec"); @@ -790,7 +789,7 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { cnt - s_cnt); } bcs->event |= 1 << B_XMTBUFREADY; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } } } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { @@ -839,19 +838,18 @@ static void tiger_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&netjet_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&netjet_lock, flags); } else { st->l1.bcs->tx_skb = skb; st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); - restore_flags(flags); + spin_unlock_irqrestore(&netjet_lock, flags); } break; case (PH_PULL | INDICATION): @@ -859,11 +857,10 @@ tiger_l2l1(struct PStack *st, int pr, void *arg) printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n"); break; } - save_flags(flags); - cli(); + spin_lock_irqsave(&netjet_lock, flags); st->l1.bcs->tx_skb = skb; st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); - restore_flags(flags); + spin_unlock_irqrestore(&netjet_lock, flags); break; case (PH_PULL | REQUEST): if (!st->l1.bcs->tx_skb) { diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index a71c447b3ca2..6caaac80c54f 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -25,6 +25,7 @@ extern const char *CardType[]; const char *niccy_revision = "$Revision: 1.15.6.6 $"; +static spinlock_t niccy_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -50,13 +51,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&niccy_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&niccy_lock, flags); return (ret); } @@ -73,13 +73,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&niccy_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&niccy_lock, flags); } static inline void diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index 3d97c12f34f2..5a5600103366 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c @@ -16,6 +16,7 @@ #include "netjet.h" const char *NETjet_S_revision = "$Revision: 2.7.6.6 $"; +static spinlock_t nj_s_lock = SPIN_LOCK_UNLOCKED; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { @@ -31,7 +32,7 @@ netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; - long flags; + unsigned long flags; if (!cs) { printk(KERN_WARNING "NETjet-S: Spurious interrupt!\n"); @@ -48,8 +49,7 @@ netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs) NETjet_WriteIC(cs, ISAC_MASK, 0x0); } } - save_flags(flags); - cli(); + spin_lock_irqsave(&nj_s_lock, flags); /* start new code 13/07/00 GE */ /* set bits in sval to indicate which page is free */ if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < @@ -67,11 +67,11 @@ netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs) if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */ { if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - restore_flags(flags); + spin_unlock_irqrestore(&nj_s_lock, flags); return; } cs->hw.njet.irqstat0 = sval; - restore_flags(flags); + spin_unlock_irqrestore(&nj_s_lock, flags); if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) /* we have a read dma int */ @@ -83,7 +83,7 @@ netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs) /* end new code 13/07/00 GE */ test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else - restore_flags(flags); + spin_unlock_irqrestore(&nj_s_lock, flags); /* if (!testcnt--) { cs->hw.njet.dmactrl = 0; @@ -149,7 +149,7 @@ setup_netjet_s(struct IsdnCard *card) int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; - long flags; + unsigned long flags; #ifdef __BIG_ENDIAN #error "not running on big endian machines now" diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c index 0728a860a5cb..6d28c10e4d9f 100644 --- a/drivers/isdn/hisax/nj_u.c +++ b/drivers/isdn/hisax/nj_u.c @@ -16,6 +16,7 @@ #include "netjet.h" const char *NETjet_U_revision = "$Revision: 2.8.6.6 $"; +static spinlock_t nj_u_lock = SPIN_LOCK_UNLOCKED; static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) { @@ -31,7 +32,7 @@ netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; - long flags; + unsigned long flags; if (!cs) { printk(KERN_WARNING "NETspider-U: Spurious interrupt!\n"); @@ -48,8 +49,7 @@ netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs) NETjet_WriteIC(cs, ICC_MASK, 0x0); } } - save_flags(flags); - cli(); + spin_lock_irqsave(&nj_u_lock, flags); /* start new code 13/07/00 GE */ /* set bits in sval to indicate which page is free */ if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) < @@ -67,11 +67,11 @@ netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs) if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */ { if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { - restore_flags(flags); + spin_unlock_irqrestore(&nj_u_lock, flags); return; } cs->hw.njet.irqstat0 = sval; - restore_flags(flags); + spin_unlock_irqrestore(&nj_u_lock, flags); if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != (cs->hw.njet.last_is0 & NETJET_IRQM0_READ)) /* we have a read dma int */ @@ -83,7 +83,7 @@ netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs) /* end new code 13/07/00 GE */ test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); } else - restore_flags(flags); + spin_unlock_irqrestore(&nj_u_lock, flags); /* if (!testcnt--) { cs->hw.njet.dmactrl = 0; @@ -196,7 +196,6 @@ setup_netjet_u(struct IsdnCard *card) save_flags(flags); sti(); - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c index 4a9ea1ab9933..1e8d88da0884 100644 --- a/drivers/isdn/hisax/s0box.c +++ b/drivers/isdn/hisax/s0box.c @@ -18,13 +18,13 @@ extern const char *CardType[]; const char *s0box_revision = "$Revision: 2.4.6.2 $"; +static spinlock_t s0box_lock = SPIN_LOCK_UNLOCKED; static inline void writereg(unsigned int padr, signed int addr, u_char off, u_char val) { unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&s0box_lock, flags); outb_p(0x1c,padr+2); outb_p(0x14,padr+2); outb_p((addr+off)&0x7f,padr); @@ -33,7 +33,7 @@ writereg(unsigned int padr, signed int addr, u_char off, u_char val) { outb_p(0x17,padr+2); outb_p(0x14,padr+2); outb_p(0x1c,padr+2); - restore_flags(flags); + spin_unlock_irqrestore(&s0box_lock, flags); } static u_char nibtab[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf, @@ -45,8 +45,7 @@ readreg(unsigned int padr, signed int addr, u_char off) { register u_char n1, n2; unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&s0box_lock, flags); outb_p(0x1c,padr+2); outb_p(0x14,padr+2); outb_p((addr+off)|0x80,padr); @@ -57,7 +56,7 @@ readreg(unsigned int padr, signed int addr, u_char off) { n2 = (inb_p(padr+1) >> 3) & 0x17; outb_p(0x14,padr+2); outb_p(0x1c,padr+2); - restore_flags(flags); + spin_unlock_irqrestore(&s0box_lock, flags); return nibtab[n1] | (nibtab[n2] << 4); } diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c index 352392be38d2..4fbd2ee7bcd2 100644 --- a/drivers/isdn/hisax/saphir.c +++ b/drivers/isdn/hisax/saphir.c @@ -20,6 +20,7 @@ extern const char *CardType[]; static char *saphir_rev = "$Revision: 1.8.6.2 $"; +static spinlock_t saphir_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -35,13 +36,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&saphir_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&saphir_lock, flags); return (ret); } @@ -58,13 +58,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&saphir_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&saphir_lock, flags); } static inline void @@ -182,14 +181,9 @@ SaphirWatchDog(struct IsdnCardState *cs) void release_io_saphir(struct IsdnCardState *cs) { - long flags; - - save_flags(flags); - cli(); byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); - del_timer(&cs->hw.saphir.timer); + del_timer_sync(&cs->hw.saphir.timer); cs->hw.saphir.timer.function = NULL; - restore_flags(flags); if (cs->hw.saphir.cfg_reg) release_region(cs->hw.saphir.cfg_reg, 6); } @@ -197,7 +191,6 @@ release_io_saphir(struct IsdnCardState *cs) static int saphir_reset(struct IsdnCardState *cs) { - long flags; u_char irq_val; switch(cs->irq) { @@ -220,15 +213,12 @@ saphir_reset(struct IsdnCardState *cs) return (1); } byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); - save_flags(flags); - sti(); byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ - restore_flags(flags); byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02); return (0); diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index 48e0bbbc4bfe..694eb354c1cb 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c @@ -50,6 +50,7 @@ #include <linux/isapnp.h> extern const char *CardType[]; +static spinlock_t sedlbauer_lock = SPIN_LOCK_UNLOCKED; const char *Sedlbauer_revision = "$Revision: 1.25.6.6 $"; @@ -121,13 +122,12 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&sedlbauer_lock, flags); byteout(ale, off); ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&sedlbauer_lock, flags); return (ret); } @@ -144,13 +144,12 @@ readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size static inline void writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&sedlbauer_lock, flags); byteout(ale, off); byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&sedlbauer_lock, flags); } static inline void @@ -422,16 +421,12 @@ release_io_sedlbauer(struct IsdnCardState *cs) static void reset_sedlbauer(struct IsdnCardState *cs) { - long flags; - printk(KERN_INFO "Sedlbauer: resetting card\n"); if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) { if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20); - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0); @@ -442,28 +437,21 @@ reset_sedlbauer(struct IsdnCardState *cs) writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12); - restore_flags(flags); } else if ((cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) && (cs->hw.sedl.bus == SEDL_BUS_PCI)) { byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); - save_flags(flags); - sti(); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout((20*HZ)/1000); byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout((20*HZ)/1000); - restore_flags(flags); } else { byteout(cs->hw.sedl.reset_on, SEDL_RESET); /* Reset On */ - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); byteout(cs->hw.sedl.reset_off, 0); /* Reset Off */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); - restore_flags(flags); } } } @@ -552,7 +540,6 @@ setup_sedlbauer(struct IsdnCard *card) struct IsdnCardState *cs = card->cs; char tmp[64]; u16 sub_vendor_id, sub_id; - long flags; strcpy(tmp, Sedlbauer_revision); printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); @@ -685,12 +672,9 @@ setup_sedlbauer(struct IsdnCard *card) byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); - save_flags(flags); - sti(); current->state = TASK_UNINTERRUPTIBLE; schedule_timeout((10*HZ)/1000); byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); - restore_flags(flags); #else printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n"); return (0); diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c index b14044b93b7d..687cf8504c71 100644 --- a/drivers/isdn/hisax/sportster.c +++ b/drivers/isdn/hisax/sportster.c @@ -147,19 +147,14 @@ release_io_sportster(struct IsdnCardState *cs) void reset_sportster(struct IsdnCardState *cs) { - long flags; - cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */ byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */ byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); - restore_flags(flags); } static int diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 22576dfd14f0..9cfe28e94293 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -253,8 +253,8 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode) static int __devinit st5481_setup_b_out(struct st5481_bcs *bcs) { struct usb_device *dev = bcs->adapter->usb_dev; - struct usb_interface_descriptor *altsetting; - struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *altsetting; + struct usb_host_endpoint *endpoint; struct st5481_b_out *b_out = &bcs->b_out; DBG(4,""); @@ -265,11 +265,11 @@ static int __devinit st5481_setup_b_out(struct st5481_bcs *bcs) endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2]; DBG(4,"endpoint address=%02x,packet size=%d", - endpoint->bEndpointAddress,endpoint->wMaxPacketSize); + endpoint->desc.bEndpointAddress,endpoint->desc.wMaxPacketSize); // Allocate memory for 8000bytes/sec + extra bytes if underrun return st5481_setup_isocpipes(b_out->urb, dev, - usb_sndisocpipe(dev, endpoint->bEndpointAddress), + usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), NUM_ISO_PACKETS_B, SIZE_ISO_PACKETS_B_OUT, NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST, usb_b_out_complete, bcs); diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 17f670d864ee..02feec24fbb4 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -358,7 +358,7 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr) if (usb_submit_urb(urb, GFP_KERNEL) < 0) { // There is another URB queued up - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; SUBMIT_URB(urb, GFP_KERNEL); } } @@ -447,7 +447,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg) // Prepare the URB urb->dev = adapter->usb_dev; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; DBG_ISO_PACKET(0x20,urb); SUBMIT_URB(urb, GFP_KERNEL); @@ -652,8 +652,8 @@ static void ph_disconnect(struct st5481_adapter *adapter) static int __devinit st5481_setup_d_out(struct st5481_adapter *adapter) { struct usb_device *dev = adapter->usb_dev; - struct usb_interface_descriptor *altsetting; - struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *altsetting; + struct usb_host_endpoint *endpoint; struct st5481_d_out *d_out = &adapter->d_out; DBG(2,""); @@ -664,10 +664,10 @@ static int __devinit st5481_setup_d_out(struct st5481_adapter *adapter) endpoint = &altsetting->endpoint[EP_D_OUT-1]; DBG(2,"endpoint address=%02x,packet size=%d", - endpoint->bEndpointAddress,endpoint->wMaxPacketSize); + endpoint->desc.bEndpointAddress,endpoint->desc.wMaxPacketSize); return st5481_setup_isocpipes(d_out->urb, dev, - usb_sndisocpipe(dev, endpoint->bEndpointAddress), + usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT, NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT, usb_d_out_complete, adapter); diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index be2d213318b8..d7a326f06199 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -244,15 +244,15 @@ int __devinit st5481_setup_usb(struct st5481_adapter *adapter) struct usb_device *dev = adapter->usb_dev; struct st5481_ctrl *ctrl = &adapter->ctrl; struct st5481_intr *intr = &adapter->intr; - struct usb_interface_descriptor *altsetting; - struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *altsetting; + struct usb_host_endpoint *endpoint; int status; struct urb *urb; u_char *buf; DBG(1,""); - if ((status = usb_set_configuration (dev,dev->config[0].bConfigurationValue)) < 0) { + if ((status = usb_set_configuration (dev,dev->config[0].desc.bConfigurationValue)) < 0) { WARN("set_configuration failed,status=%d",status); return status; } @@ -261,14 +261,14 @@ int __devinit st5481_setup_usb(struct st5481_adapter *adapter) altsetting = &(dev->config->interface[0].altsetting[3]); // Check if the config is sane - if ( altsetting->bNumEndpoints != 7 ) { - WARN("expecting 7 got %d endpoints!", altsetting->bNumEndpoints); + if ( altsetting->desc.bNumEndpoints != 7 ) { + WARN("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints); return -EINVAL; } // The descriptor is wrong for some early samples of the ST5481 chip - altsetting->endpoint[3].wMaxPacketSize = 32; - altsetting->endpoint[4].wMaxPacketSize = 32; + altsetting->endpoint[3].desc.wMaxPacketSize = 32; + altsetting->endpoint[4].desc.wMaxPacketSize = 32; // Use alternative setting 3 on interface 0 to have 2B+D if ((status = usb_set_interface (dev, 0, 3)) < 0) { @@ -284,7 +284,7 @@ int __devinit st5481_setup_usb(struct st5481_adapter *adapter) ctrl->urb = urb; // Fill the control URB - FILL_CONTROL_URB (urb, dev, + usb_fill_control_urb (urb, dev, usb_sndctrlpipe(dev, 0), NULL, NULL, 0, usb_ctrl_complete, adapter); @@ -306,11 +306,11 @@ int __devinit st5481_setup_usb(struct st5481_adapter *adapter) endpoint = &altsetting->endpoint[EP_INT-1]; // Fill the interrupt URB - FILL_INT_URB(urb, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), + usb_fill_int_urb(urb, dev, + usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress), buf, INT_PKT_SIZE, usb_int_complete, adapter, - endpoint->bInterval); + endpoint->desc.bInterval); return 0; } @@ -409,7 +409,7 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, urb->actual_length = 0; urb->complete=complete; urb->context=context; - urb->transfer_flags=USB_ISO_ASAP; + urb->transfer_flags=URB_ISO_ASAP; for (k = 0; k < num_packets; k++) { urb->iso_frame_desc[k].offset = packet_size * k; urb->iso_frame_desc[k].length = packet_size; diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c index 167850af27f8..372f5ed34241 100644 --- a/drivers/isdn/hisax/teleint.c +++ b/drivers/isdn/hisax/teleint.c @@ -19,6 +19,7 @@ extern const char *CardType[]; const char *TeleInt_revision = "$Revision: 1.14.6.2 $"; +static spinlock_t teleint_lock = SPIN_LOCK_UNLOCKED; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -28,21 +29,20 @@ readreg(unsigned int ale, unsigned int adr, u_char off) { register u_char ret; int max_delay = 2000; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&teleint_lock, flags); byteout(ale, off); ret = HFC_BUSY & bytein(ale); while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { printk(KERN_WARNING "TeleInt Busy not inactive\n"); - restore_flags(flags); + spin_unlock_irqrestore(&teleint_lock, flags); return (0); } ret = bytein(adr); - restore_flags(flags); + spin_unlock_irqrestore(&teleint_lock, flags); return (ret); } @@ -72,21 +72,20 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) { register u_char ret; int max_delay = 2000; - long flags; + unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&teleint_lock, flags); byteout(ale, off); ret = HFC_BUSY & bytein(ale); while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { printk(KERN_WARNING "TeleInt Busy not inactive\n"); - restore_flags(flags); + spin_unlock_irqrestore(&teleint_lock, flags); return; } byteout(adr, data); - restore_flags(flags); + spin_unlock_irqrestore(&teleint_lock, flags); } static inline void @@ -220,20 +219,15 @@ release_io_TeleInt(struct IsdnCardState *cs) static void reset_TeleInt(struct IsdnCardState *cs) { - long flags; - printk(KERN_INFO "TeleInt: resetting card\n"); cs->hw.hfc.cirm |= HFC_RESET; byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset On */ - save_flags(flags); - sti(); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); cs->hw.hfc.cirm &= ~HFC_RESET; byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset Off */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); - restore_flags(flags); } static int diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c index 8dbbdd70baf0..dfe161baf900 100644 --- a/drivers/isdn/hisax/teles0.c +++ b/drivers/isdn/hisax/teles0.c @@ -196,10 +196,7 @@ static int reset_teles0(struct IsdnCardState *cs) { u_char cfval; - long flags; - save_flags(flags); - sti(); if (cs->hw.teles0.cfg_reg) { switch (cs->irq) { case 2: @@ -240,7 +237,6 @@ reset_teles0(struct IsdnCardState *cs) HZDELAY(HZ / 5 + 1); writeb(1, cs->hw.teles0.membase + 0x80); mb(); HZDELAY(HZ / 5 + 1); - restore_flags(flags); return(0); } diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index be444a8c2f88..02662ebae6cf 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c @@ -174,7 +174,6 @@ release_io_teles3(struct IsdnCardState *cs) static int reset_teles3(struct IsdnCardState *cs) { - long flags; u_char irqcfg; if (cs->typ != ISDN_CTYPE_TELESPCMCIA) { @@ -208,28 +207,21 @@ reset_teles3(struct IsdnCardState *cs) default: return(1); } - save_flags(flags); byteout(cs->hw.teles3.cfg_reg + 4, irqcfg); - sti(); HZDELAY(HZ / 10 + 1); byteout(cs->hw.teles3.cfg_reg + 4, irqcfg | 1); HZDELAY(HZ / 10 + 1); - restore_flags(flags); } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - save_flags(flags); byteout(cs->hw.teles3.cfg_reg, 0xff); HZDELAY(2); byteout(cs->hw.teles3.cfg_reg, 0x00); HZDELAY(2); - restore_flags(flags); } else { /* Reset off for 16.3 PnP , thanks to Georg Acher */ - save_flags(flags); byteout(cs->hw.teles3.isac + 0x3c, 0); HZDELAY(2); byteout(cs->hw.teles3.isac + 0x3c, 1); HZDELAY(2); - restore_flags(flags); } } return(0); diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index 715b84e4d773..bfa0eb2af7b3 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -43,6 +43,8 @@ extern const char *CardType[]; const char *w6692_revision = "$Revision: 1.12.6.6 $"; +static spinlock_t w6692_lock = SPIN_LOCK_UNLOCKED; + #define DBUSY_TIMER_VALUE 80 static char *W6692Ver[] __initdata = @@ -102,8 +104,9 @@ W6692_new_ph(struct IsdnCardState *cs) } static void -W6692_bh(struct IsdnCardState *cs) +W6692_bh(void *data) { + struct IsdnCardState *cs = data; struct PStack *stptr; if (!cs) @@ -135,21 +138,21 @@ void W6692_sched_event(struct IsdnCardState *cs, int event) { test_and_set_bit(event, &cs->event); - schedule_work(&cs->tqueue); + schedule_work(&cs->work); } static void W6692B_sched_event(struct BCState *bcs, int event) { bcs->event |= 1 << event; - schedule_work(&bcs->tqueue); + schedule_work(&bcs->work); } static void W6692_empty_fifo(struct IsdnCardState *cs, int count) { u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "W6692_empty_fifo"); @@ -164,11 +167,10 @@ W6692_empty_fifo(struct IsdnCardState *cs, int count) } ptr = cs->rcvbuf + cs->rcvidx; cs->rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); cs->readW6692fifo(cs, ptr, count); cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK); - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock, flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -183,7 +185,7 @@ W6692_fill_fifo(struct IsdnCardState *cs) { int count, more; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) debugl1(cs, "W6692_fill_fifo"); @@ -200,14 +202,13 @@ W6692_fill_fifo(struct IsdnCardState *cs) more = !0; count = W_D_FIFO_THRESH; } - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); ptr = cs->tx_skb->data; skb_pull(cs->tx_skb, count); cs->tx_cnt += count; cs->writeW6692fifo(cs, ptr, count); cs->writeW6692(cs, W_D_CMDR, more ? W_D_CMDR_XMS : (W_D_CMDR_XMS | W_D_CMDR_XME)); - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { debugl1(cs, "W6692_fill_fifo dbusytimer running"); del_timer(&cs->dbusytimer); @@ -229,7 +230,7 @@ W6692B_empty_fifo(struct BCState *bcs, int count) { u_char *ptr; struct IsdnCardState *cs = bcs->cs; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) debugl1(cs, "W6692B_empty_fifo"); @@ -243,11 +244,10 @@ W6692B_empty_fifo(struct BCState *bcs, int count) } ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx; bcs->hw.w6692.rcvidx += count; - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); READW6692BFIFO(cs, bcs->channel, ptr, count); cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -264,7 +264,7 @@ W6692B_fill_fifo(struct BCState *bcs) struct IsdnCardState *cs = bcs->cs; int more, count; u_char *ptr; - long flags; + unsigned long flags; if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) @@ -282,15 +282,14 @@ W6692B_fill_fifo(struct BCState *bcs) } else count = bcs->tx_skb->len; - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); ptr = bcs->tx_skb->data; skb_pull(bcs->tx_skb, count); bcs->tx_cnt -= count; bcs->hw.w6692.count += count; WRITEW6692BFIFO(cs, bcs->channel, ptr, count); cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACT | W_B_CMDR_XMS | (more ? 0 : W_B_CMDR_XME)); - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); if (cs->debug & L1_DEB_HSCX_FIFO) { char *t = bcs->blog; @@ -411,7 +410,7 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) u_char val, exval, v1; struct sk_buff *skb; unsigned int count; - long flags; + unsigned long flags; int icnt = 5; if (!cs) { @@ -442,8 +441,7 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) if (count == 0) count = W_D_FIFO_THRESH; W6692_empty_fifo(cs, count); - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); if ((count = cs->rcvidx) > 0) { cs->rcvidx = 0; if (!(skb = alloc_skb(count, GFP_ATOMIC))) @@ -453,7 +451,7 @@ W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) skb_queue_tail(&cs->rq, skb); } } - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); } cs->rcvidx = 0; W6692_sched_event(cs, D_RCVBUFREADY); @@ -745,20 +743,19 @@ static void W6692_l2l1(struct PStack *st, int pr, void *arg) { struct sk_buff *skb = arg; - long flags; + unsigned long flags; switch (pr) { case (PH_DATA | REQUEST): - save_flags(flags); - cli(); + spin_lock_irqsave(&w6692_lock, flags); if (st->l1.bcs->tx_skb) { skb_queue_tail(&st->l1.bcs->squeue, skb); - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); } else { st->l1.bcs->tx_skb = skb; test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); st->l1.bcs->hw.w6692.count = 0; - restore_flags(flags); + spin_unlock_irqrestore(&w6692_lock , flags); st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); } break; @@ -887,7 +884,7 @@ void resetW6692(struct IsdnCardState *cs) void __init initW6692(struct IsdnCardState *cs, int part) { if (part & 1) { - INIT_WORK(&cs->tqueue, (void *) (void *) W6692_bh, NULL); + INIT_WORK(&cs->work, W6692_bh, cs); cs->setstack_d = setstack_W6692; cs->DC_Close = DC_Close_W6692; cs->dbusytimer.function = (void *) dbusy_timer_handler; diff --git a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile index 3bf0d170754f..4458d5d4478b 100644 --- a/drivers/isdn/i4l/Makefile +++ b/drivers/isdn/i4l/Makefile @@ -11,15 +11,18 @@ obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o # Multipart objects. -isdn-objs := isdn_net.o isdn_net_lib.o \ +isdn-objs := isdn_net_lib.o \ isdn_fsm.o \ - isdn_ciscohdlck.o \ isdn_tty.o isdn_v110.o \ isdn_common.o \ # Optional parts of multipart objects. +isdn-objs-$(CONFIG_ISDN_NET_SIMPLE) += isdn_net.o +isdn-objs-$(CONFIG_ISDN_NET_CISCO) += isdn_ciscohdlck.o isdn-objs-$(CONFIG_ISDN_PPP) += isdn_ppp.o isdn_ppp_ccp.o +isdn-objs-$(CONFIG_ISDN_PPP_VJ) += isdn_ppp_vj.o +isdn-objs-$(CONFIG_ISDN_MPP) += isdn_ppp_mp.o isdn-objs-$(CONFIG_ISDN_X25) += isdn_concap.o isdn_x25iface.o isdn-objs-$(CONFIG_ISDN_AUDIO) += isdn_audio.o isdn-objs-$(CONFIG_ISDN_TTY_FAX) += isdn_ttyfax.o diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c index bdd92d81d13d..47b90e49b8d8 100644 --- a/drivers/isdn/i4l/isdn_audio.c +++ b/drivers/isdn/i4l/isdn_audio.c @@ -1,21 +1,20 @@ -/* $Id: isdn_audio.c,v 1.21.6.3 2002/08/13 09:45:33 keil Exp $ - * - * Linux ISDN subsystem, audio conversion and compression (linklevel). +/* Linux ISDN subsystem, audio conversion and compression * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) - * DTMF code (c) 1996 by Christian Mock (cm@tahina.priv.at) - * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de) + * 1996 by Christian Mock (cm@tahina.priv.at) + * 1998 by Armin Schindler (mac@gismo.telekom.de) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * + * DTMF code by Christian Mock + * Silence detection by Armin Schindler */ #include <linux/isdn.h> #include "isdn_audio.h" #include "isdn_common.h" - -char *isdn_audio_revision = "$Revision: 1.21.6.3 $"; +#include "isdn_tty.h" /* * Misc. lookup-tables. @@ -507,7 +506,7 @@ isdn_audio_goertzel(int *sample, modem_info * info) ((sk2 * sk2) >> AMP_BITS); } skb_queue_tail(&info->dtmf_queue, skb); - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); + mod_timer(&info->read_timer, jiffies + 4); } void @@ -518,8 +517,6 @@ isdn_audio_eval_dtmf(modem_info * info) dtmf_state *s; int silence; int i; - int di; - int ch; unsigned long flags; int grp[2]; char what; @@ -564,15 +561,11 @@ isdn_audio_eval_dtmf(modem_info * info) ISDN_AUDIO_SKB_LOCK(skb) = 0; save_flags(flags); cli(); - di = isdn_slot_driver(info->isdn_slot); - ch = isdn_slot_channel(info->isdn_slot); - __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); - dev->drv[di]->rcvcount[ch] += 2; + isdn_tty_queue_tail(info, skb, 2); restore_flags(flags); /* Schedule dequeuing */ if ((dev->modempoll) && (info->rcvsched)) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); - wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]); + mod_timer(&info->read_timer, jiffies + 4); } else kfree_skb(skb); s->last = what; @@ -661,8 +654,6 @@ isdn_audio_put_dle_code(modem_info * info, u_char code) { struct sk_buff *skb; unsigned long flags; - int di; - int ch; char *p; skb = dev_alloc_skb(2); @@ -685,15 +676,11 @@ isdn_audio_put_dle_code(modem_info * info, u_char code) ISDN_AUDIO_SKB_LOCK(skb) = 0; save_flags(flags); cli(); - di = isdn_slot_driver(info->isdn_slot); - ch = isdn_slot_channel(info->isdn_slot); - __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); - dev->drv[di]->rcvcount[ch] += 2; + isdn_tty_queue_tail(info, skb, 2); restore_flags(flags); /* Schedule dequeuing */ if ((dev->modempoll) && (info->rcvsched)) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); - wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]); + mod_timer(&info->read_timer, jiffies + 4); } void diff --git a/drivers/isdn/i4l/isdn_audio.h b/drivers/isdn/i4l/isdn_audio.h index e60c980c953a..e08d7d2a0700 100644 --- a/drivers/isdn/i4l/isdn_audio.h +++ b/drivers/isdn/i4l/isdn_audio.h @@ -1,6 +1,4 @@ -/* $Id: isdn_audio.h,v 1.9.6.1 2001/09/23 22:24:31 kai Exp $ - * - * Linux ISDN subsystem, audio conversion and compression (linklevel). +/* Linux ISDN subsystem, audio conversion and compression * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * diff --git a/drivers/isdn/i4l/isdn_ciscohdlck.c b/drivers/isdn/i4l/isdn_ciscohdlck.c index cab5b1a2100f..f8e903aa1b3c 100644 --- a/drivers/isdn/i4l/isdn_ciscohdlck.c +++ b/drivers/isdn/i4l/isdn_ciscohdlck.c @@ -1,5 +1,4 @@ -/* - * Linux ISDN subsystem, CISCO HDLC network interfaces +/* Linux ISDN subsystem, CISCO HDLC network interfaces * * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) * 1995,96 by Thinking Objects Software GmbH Wuerzburg @@ -14,7 +13,7 @@ */ #include "isdn_common.h" -#include "isdn_net.h" +#include "isdn_net_lib.h" #include "isdn_ciscohdlck.h" #include <linux/if_arp.h> @@ -56,6 +55,7 @@ static int isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { isdn_net_local *mlp = dev->priv; + struct inl_cisco *cisco = mlp->inl_priv; unsigned long len = 0; int period; char debserint; @@ -67,13 +67,13 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { /* get/set keepalive period */ case SIOCGKEEPPERIOD: - len = sizeof(mlp->cisco_keepalive_period); + len = sizeof(cisco->keepalive_period); if (copy_to_user((char *)ifr->ifr_ifru.ifru_data, - (char *)&mlp->cisco_keepalive_period, len)) + (char *)&cisco->keepalive_period, len)) rc = -EFAULT; break; case SIOCSKEEPPERIOD: - len = sizeof(mlp->cisco_keepalive_period); + len = sizeof(cisco->keepalive_period); if (copy_from_user((char *)&period, (char *)ifr->ifr_ifru.ifru_data, len)) { rc = -EFAULT; @@ -83,21 +83,21 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) rc = -EINVAL; break; } - mod_timer(&mlp->cisco_timer, jiffies + period * HZ); + mod_timer(&cisco->timer, jiffies + period * HZ); printk(KERN_INFO "%s: Keepalive period set " "to %d seconds.\n", dev->name, period); - mlp->cisco_keepalive_period = period; + cisco->keepalive_period = period; break; /* get/set debugging */ case SIOCGDEBSERINT: - len = sizeof(mlp->cisco_debserint); + len = sizeof(cisco->debserint); if (copy_to_user((char *)ifr->ifr_ifru.ifru_data, - (char *)&mlp->cisco_debserint, len)) + (char *)&cisco->debserint, len)) rc = -EFAULT; break; case SIOCSDEBSERINT: - len = sizeof(mlp->cisco_debserint); + len = sizeof(cisco->debserint); if (copy_from_user((char *)&debserint, (char *)ifr->ifr_ifru.ifru_data, len)) { rc = -EFAULT; @@ -107,7 +107,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) rc = -EINVAL; break; } - mlp->cisco_debserint = debserint; + cisco->debserint = debserint; break; default: @@ -122,10 +122,11 @@ static void isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) { isdn_net_local *mlp = (isdn_net_local *) data; - isdn_net_dev *idev; + isdn_net_dev *idev; + struct inl_cisco *cisco = mlp->inl_priv; struct sk_buff *skb; unsigned char *p; - unsigned long last_cisco_myseq = mlp->cisco_myseq; + unsigned long last_cisco_myseq = cisco->myseq; int myseq_diff = 0; if (list_empty(&mlp->online)) { @@ -133,33 +134,33 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) return; } idev = list_entry(mlp->online.next, isdn_net_dev, online); - mlp->cisco_myseq++; + cisco->myseq++; - myseq_diff = (mlp->cisco_myseq - mlp->cisco_mineseen); - if (mlp->cisco_line_state && (myseq_diff >= 3 || myseq_diff <= -3)) { + myseq_diff = cisco->myseq - cisco->mineseen; + if (cisco->line_state && (myseq_diff >= 3 || myseq_diff <= -3)) { /* line up -> down */ - mlp->cisco_line_state = 0; + cisco->line_state = 0; printk (KERN_WARNING "UPDOWN: Line protocol on Interface %s," " changed state to down\n", idev->name); /* should stop routing higher-level data accross */ - } else if (!mlp->cisco_line_state && + } else if (!cisco->line_state && myseq_diff >= 0 && myseq_diff <= 2) { /* line down -> up */ - mlp->cisco_line_state = 1; + cisco->line_state = 1; printk (KERN_WARNING "UPDOWN: Line protocol on Interface %s," " changed state to up\n", idev->name); /* restart routing higher-level data accross */ } - if (mlp->cisco_debserint) + if (cisco->debserint) printk (KERN_DEBUG "%s: HDLC " - "myseq %lu, mineseen %lu%c, yourseen %lu, %s\n", - idev->name, last_cisco_myseq, mlp->cisco_mineseen, - (last_cisco_myseq == mlp->cisco_mineseen) ? '*' : 040, - mlp->cisco_yourseq, - (mlp->cisco_line_state) ? "line up" : "line down"); + "myseq %u, mineseen %u%c, yourseen %u, %s\n", + idev->name, cisco->myseq, cisco->mineseen, + (last_cisco_myseq == cisco->mineseen) ? '*' : 040, + cisco->yourseq, + (cisco->line_state) ? "line up" : "line down"); skb = isdn_net_ciscohdlck_alloc_skb(idev, 4 + 14); if (!skb) @@ -174,13 +175,13 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) /* slarp keepalive */ p += put_u32(p, CISCO_SLARP_KEEPALIVE); - p += put_u32(p, mlp->cisco_myseq); - p += put_u32(p, mlp->cisco_yourseq); + p += put_u32(p, cisco->myseq); + p += put_u32(p, cisco->yourseq); p += put_u16(p, 0xffff); // reliablity, always 0xffff isdn_net_write_super(idev, skb); - mod_timer(&mlp->cisco_timer, jiffies + mlp->cisco_keepalive_period * HZ); + mod_timer(&cisco->timer, jiffies + cisco->keepalive_period * HZ); } static void @@ -220,24 +221,25 @@ static void isdn_ciscohdlck_connected(isdn_net_dev *idev) { isdn_net_local *lp = idev->mlp; + struct inl_cisco *cisco = lp->inl_priv; - lp->cisco_myseq = 0; - lp->cisco_mineseen = 0; - lp->cisco_yourseq = 0; - lp->cisco_keepalive_period = ISDN_TIMER_KEEPINT; - lp->cisco_last_slarp_in = 0; - lp->cisco_line_state = 0; - lp->cisco_debserint = 0; + cisco->myseq = 0; + cisco->mineseen = 0; + cisco->yourseq = 0; + cisco->keepalive_period = 10; + cisco->last_slarp_in = 0; + cisco->line_state = 0; + cisco->debserint = 0; if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK) { /* send slarp request because interface/seq.no.s reset */ isdn_net_ciscohdlck_slarp_send_request(lp); - init_timer(&lp->cisco_timer); - lp->cisco_timer.data = (unsigned long) lp; - lp->cisco_timer.function = isdn_net_ciscohdlck_slarp_send_keepalive; - lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ; - add_timer(&lp->cisco_timer); + init_timer(&cisco->timer); + cisco->timer.data = (unsigned long) lp; + cisco->timer.function = isdn_net_ciscohdlck_slarp_send_keepalive; + cisco->timer.expires = jiffies + cisco->keepalive_period * HZ; + add_timer(&cisco->timer); } netif_wake_queue(&lp->dev); } @@ -246,9 +248,10 @@ static void isdn_ciscohdlck_disconnected(isdn_net_dev *idev) { isdn_net_local *lp = idev->mlp; + struct inl_cisco *cisco = lp->inl_priv; if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK) { - del_timer(&lp->cisco_timer); + del_timer(&cisco->timer); } } @@ -296,6 +299,7 @@ static void isdn_net_ciscohdlck_slarp_in(isdn_net_dev *idev, struct sk_buff *skb) { isdn_net_local *mlp = idev->mlp; + struct inl_cisco *cisco = mlp->inl_priv; unsigned char *p; int period; u32 code; @@ -312,7 +316,7 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_dev *idev, struct sk_buff *skb) switch (code) { case CISCO_SLARP_REQUEST: - mlp->cisco_yourseq = 0; + cisco->yourseq = 0; isdn_net_ciscohdlck_slarp_send_reply(idev); break; case CISCO_SLARP_REPLY: @@ -339,21 +343,20 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_dev *idev, struct sk_buff *skb) HIPQUAD(addr), HIPQUAD(mask)); break; case CISCO_SLARP_KEEPALIVE: - period = (int)((jiffies - mlp->cisco_last_slarp_in - + HZ/2 - 1) / HZ); - if (mlp->cisco_debserint && - (period != mlp->cisco_keepalive_period) && - mlp->cisco_last_slarp_in) { + period = (jiffies - cisco->last_slarp_in + HZ/2 - 1) / HZ; + if (cisco->debserint && + (period != cisco->keepalive_period) && + cisco->last_slarp_in) { printk(KERN_DEBUG "%s: Keepalive period mismatch - " "is %d but should be %d.\n", - idev->name, period, mlp->cisco_keepalive_period); + idev->name, period, cisco->keepalive_period); } - mlp->cisco_last_slarp_in = jiffies; + cisco->last_slarp_in = jiffies; p += get_u32(p, &my_seq); p += get_u32(p, &your_seq); p += get_u16(p, &unused); - mlp->cisco_yourseq = my_seq; - mlp->cisco_mineseen = your_seq; + cisco->yourseq = my_seq; + cisco->mineseen = your_seq; break; } } @@ -362,6 +365,7 @@ static void isdn_ciscohdlck_receive(isdn_net_local *lp, isdn_net_dev *idev, struct sk_buff *skb) { + struct inl_cisco *cisco = lp->inl_priv; unsigned char *p; u8 addr; u8 ctrl; @@ -388,7 +392,7 @@ isdn_ciscohdlck_receive(isdn_net_local *lp, isdn_net_dev *idev, isdn_net_ciscohdlck_slarp_in(idev, skb); goto out_free; case CISCO_TYPE_CDP: - if (lp->cisco_debserint) + if (cisco->debserint) printk(KERN_DEBUG "%s: Received CDP packet. use " "\"no cdp enable\" on cisco.\n", idev->name); goto out_free; @@ -418,7 +422,23 @@ isdn_ciscohdlck_header(struct sk_buff *skb, struct net_device *dev, return 4; } -struct isdn_netif_ops ciscohdlck_ops = { +static int +isdn_ciscohdlck_open(isdn_net_local *lp) +{ + lp->inl_priv = kmalloc(sizeof(struct inl_cisco), GFP_KERNEL); + if (!lp->inl_priv) + return -ENOMEM; + + return 0; +} + +static void +isdn_ciscohdlck_close(isdn_net_local *lp) +{ + kfree(lp->inl_priv); +} + +struct isdn_netif_ops isdn_ciscohdlck_ops = { .hard_start_xmit = isdn_net_start_xmit, .hard_header = isdn_ciscohdlck_header, .do_ioctl = isdn_ciscohdlck_dev_ioctl, @@ -427,4 +447,6 @@ struct isdn_netif_ops ciscohdlck_ops = { .receive = isdn_ciscohdlck_receive, .connected = isdn_ciscohdlck_connected, .disconnected = isdn_ciscohdlck_disconnected, + .open = isdn_ciscohdlck_open, + .close = isdn_ciscohdlck_close, }; diff --git a/drivers/isdn/i4l/isdn_ciscohdlck.h b/drivers/isdn/i4l/isdn_ciscohdlck.h index 24cd87d2f674..dda0d7a07744 100644 --- a/drivers/isdn/i4l/isdn_ciscohdlck.h +++ b/drivers/isdn/i4l/isdn_ciscohdlck.h @@ -1,5 +1,4 @@ -/* - * Linux ISDN subsystem, CISCO HDLC network interfaces +/* Linux ISDN subsystem, CISCO HDLC network interfaces * * Copyright 1999-2002 by Kai Germaschewski <kai@germaschewski.name> * 2001 by Bjoern A. Zeeb <i4l@zabbadoz.net> @@ -11,6 +10,17 @@ #ifndef ISDN_CISCOHDLCK_H #define ISDN_CISCOHDLCK_H -extern struct isdn_netif_ops ciscohdlck_ops; +extern struct isdn_netif_ops isdn_ciscohdlck_ops; + +struct inl_cisco { + u32 myseq; /* local keepalive seq. for Cisco */ + u32 mineseen; /* returned keepalive seq. from remote */ + u32 yourseq; /* remote keepalive seq. for Cisco */ + int keepalive_period; /* keepalive period */ + int last_slarp_in; /* jiffie of last recvd keepalive pkt */ + char line_state; /* state of line */ + char debserint; /* debugging flags */ + struct timer_list timer; +}; #endif diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 37a7968aabb7..f3b158796419 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1,6 +1,4 @@ -/* $Id: isdn_common.c,v 1.114.6.16 2001/11/06 20:58:28 kai Exp $ - * - * Linux ISDN subsystem, common used functions (linklevel). +/* Linux ISDN subsystem, common used functions * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg @@ -8,7 +6,6 @@ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #include <linux/config.h> @@ -21,14 +18,14 @@ #include <linux/smp_lock.h> #include <linux/ctype.h> #include "isdn_common.h" -#include "isdn_tty.h" +#include "isdn_net_lib.h" #include "isdn_net.h" +#include "isdn_tty.h" #include "isdn_ppp.h" #ifdef CONFIG_ISDN_AUDIO #include "isdn_audio.h" #endif #include <linux/isdn_divertif.h> -#include "isdn_v110.h" #include <linux/devfs_fs_kernel.h> MODULE_DESCRIPTION("ISDN4Linux: link layer"); @@ -37,94 +34,982 @@ MODULE_LICENSE("GPL"); isdn_dev *dev; -struct isdn_slot { - int di; /* driver index */ - int ch; /* channel index (per driver) */ - int usage; /* how is it used */ - char num[ISDN_MSNLEN]; /* the current phone number */ - unsigned long ibytes; /* Statistics incoming bytes */ - unsigned long obytes; /* Statistics outgoing bytes */ - struct isdn_v110 iv110; /* For V.110 */ - int m_idx; /* Index for mdm.... */ - isdn_net_dev *idev; /* pointer to isdn_net_dev */ +static void isdn_lock_driver(struct isdn_driver *drv); +static void isdn_unlock_driver(struct isdn_driver *drv); + +static void isdn_register_devfs(int); +static void isdn_unregister_devfs(int); + +/* ====================================================================== */ + +static struct isdn_slot slots[ISDN_MAX_CHANNELS]; + +static struct fsm slot_fsm; +static void slot_debug(struct fsm_inst *fi, char *fmt, ...); + +static char *slot_st_str[] = { + "ST_SLOT_NULL", + "ST_SLOT_BOUND", + "ST_SLOT_IN", + "ST_SLOT_WAIT_DCONN", + "ST_SLOT_DCONN", + "ST_SLOT_WAIT_BCONN", + "ST_SLOT_ACTIVE", + "ST_SLOT_WAIT_BHUP", + "ST_SLOT_WAIT_DHUP", }; -static struct isdn_slot slot[ISDN_MAX_CHANNELS]; +static char *ev_str[] = { + "EV_DRV_REGISTER", + "EV_STAT_RUN", + "EV_STAT_STOP", + "EV_STAT_UNLOAD", + "EV_STAT_STAVAIL", + "EV_STAT_ADDCH", + "EV_STAT_ICALL", + "EV_STAT_DCONN", + "EV_STAT_BCONN", + "EV_STAT_BHUP", + "EV_STAT_DHUP", + "EV_STAT_BSENT", + "EV_STAT_CINF", + "EV_STAT_CAUSE", + "EV_STAT_DISPLAY", + "EV_STAT_FAXIND", + "EV_STAT_AUDIO", + "EV_CMD_CLREAZ", + "EV_CMD_SETEAZ", + "EV_CMD_SETL2", + "EV_CMD_SETL3", + "EV_CMD_DIAL", + "EV_CMD_ACCEPTD", + "EV_CMD_ACCEPTB", + "EV_CMD_HANGUP", + "EV_DATA_REQ", + "EV_DATA_IND", + "EV_SLOT_BIND", + "EV_SLOT_UNBIND", +}; -static char *isdn_revision = "$Revision: 1.114.6.16 $"; +static int __slot_command(struct isdn_slot *slot, isdn_ctrl *cmd); -extern char *isdn_net_revision; -extern char *isdn_tty_revision; -#ifdef CONFIG_ISDN_PPP -extern char *isdn_ppp_revision; -#else -static char *isdn_ppp_revision = ": none $"; -#endif -#ifdef CONFIG_ISDN_AUDIO -extern char *isdn_audio_revision; -#else -static char *isdn_audio_revision = ": none $"; -#endif -extern char *isdn_v110_revision; +static void isdn_v110_setl2(struct isdn_slot *slot, isdn_ctrl *cmd); +static void __isdn_v110_open(struct isdn_slot *slot); +static void __isdn_v110_close(struct isdn_slot *slot); +static void __isdn_v110_bsent(struct isdn_slot *slot, int pr, isdn_ctrl *cmd); +static int isdn_v110_data_ind(struct isdn_slot *slot, struct sk_buff *skb); +static int isdn_v110_data_req(struct isdn_slot *slot, struct sk_buff *skb); -#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE) -static isdn_divert_if *divert_if; /* = NULL */ -#else -#define divert_if ((isdn_divert_if *) NULL) -#endif +static inline int +do_event_cb(struct isdn_slot *slot, int pr, void *arg) +{ + if (slot->event_cb) + return slot->event_cb(slot, pr, arg); + return -ENXIO; +} -static void set_global_features(void); -static void isdn_register_devfs(int); -static void isdn_unregister_devfs(int); -static int isdn_wildmat(char *s, char *p); -static int isdn_command(isdn_ctrl *cmd); +static int +slot_bind(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + isdn_lock_driver(slot->drv); + fsm_change_state(fi, ST_SLOT_BOUND); -void -isdn_lock_drivers(void) + return 0; +} + +/* just pass through command */ +static int +slot_command(struct fsm_inst *fi, int pr, void *arg) { - int i; + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *c = arg; - for (i = 0; i < dev->drivers; i++) { - isdn_ctrl cmd; + return __slot_command(slot, c); +} - cmd.driver = i; - cmd.arg = 0; - cmd.command = ISDN_CMD_LOCK; - isdn_command(&cmd); - dev->drv[i]->locks++; +/* just pass through status */ +static int +slot_stat(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + do_event_cb(slot, pr, arg); + return 0; +} + +/* just pass through command */ +static int +slot_setl2(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *c = arg; + + isdn_v110_setl2(slot, c); + + return __slot_command(slot, c); +} + +static int +slot_dial(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + int retval; + + retval = __slot_command(slot, ctrl); + if (retval >= 0) + fsm_change_state(fi, ST_SLOT_WAIT_DCONN); + + return retval; +} + +static int +slot_acceptd(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + int retval; + + retval = __slot_command(slot, ctrl); + if (retval >= 0) + fsm_change_state(fi, ST_SLOT_WAIT_DCONN); + + return retval; +} + +static int +slot_acceptb(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + int retval; + + retval = __slot_command(slot, ctrl); + if (retval >= 0) + fsm_change_state(fi, ST_SLOT_WAIT_BCONN); + + return retval; +} + +static int +slot_actv_hangup(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + int retval; + + retval = __slot_command(slot, ctrl); + if (retval >= 0) { + fsm_change_state(fi, ST_SLOT_WAIT_BHUP); } + return retval; } -void -isdn_MOD_INC_USE_COUNT(void) +static int +slot_dconn(struct fsm_inst *fi, int pr, void *arg) { - MOD_INC_USE_COUNT; - isdn_lock_drivers(); + struct isdn_slot *slot = fi->userdata; + + fsm_change_state(fi, ST_SLOT_DCONN); + do_event_cb(slot, pr, arg); + return 0; } -void -isdn_unlock_drivers(void) +static int +slot_bconn(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + fsm_change_state(fi, ST_SLOT_ACTIVE); + __isdn_v110_open(slot); + + isdn_info_update(); + + do_event_cb(slot, pr, arg); + return 0; +} + +static int +slot_bhup(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + __isdn_v110_close(slot); + fsm_change_state(fi, ST_SLOT_WAIT_DHUP); + + do_event_cb(slot, pr, arg); + return 0; +} + +static int +slot_dhup(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + fsm_change_state(fi, ST_SLOT_BOUND); + + do_event_cb(slot, pr, arg); + return 0; +} + +static int +slot_data_req(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + struct sk_buff *skb = arg; + + return isdn_v110_data_req(slot, skb); +} + +static int +slot_data_ind(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + struct sk_buff *skb = arg; + + /* Update statistics */ + slot->ibytes += skb->len; + + return isdn_v110_data_ind(slot, skb); +} + +static int +slot_bsent(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + + __isdn_v110_bsent(slot, pr, ctrl); + return 0; +} + +static int +slot_icall(struct fsm_inst *fi, int pr, void *arg) { + struct isdn_slot *slot = fi->userdata; + isdn_ctrl *ctrl = arg; + int retval; + + isdn_lock_driver(slot->drv); + fsm_change_state(fi, ST_SLOT_IN); + slot_debug(fi, "ICALL: %s\n", ctrl->parm.num); + if (dev->global_flags & ISDN_GLOBAL_STOPPED) + return 0; + + strcpy(slot->num, ctrl->parm.setup.phone); + /* Try to find a network-interface which will accept incoming call */ + retval = isdn_net_find_icall(slot, &ctrl->parm.setup); + + /* already taken by net now? */ + if (fi->state != ST_SLOT_IN) + goto out; + + retval = isdn_tty_find_icall(slot, &ctrl->parm.setup); + out: + return 0; +} + +/* should become broadcast later */ +static int +slot_in_dhup(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + + isdn_unlock_driver(slot->drv); + fsm_change_state(fi, ST_SLOT_NULL); + do_event_cb(slot, pr, arg); + return 0; +} + +static int +slot_unbind(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_slot *slot = fi->userdata; + isdn_ctrl cmd; + + isdn_unlock_driver(slot->drv); + fsm_change_state(fi, ST_SLOT_NULL); + strcpy(slot->num, "???"); + cmd.parm.num[0] = '\0'; + isdn_slot_command(slot, ISDN_CMD_SETEAZ, &cmd); + slot->ibytes = 0; + slot->obytes = 0; + slot->usage = ISDN_USAGE_NONE; + isdn_info_update(); + return 0; +} + +static struct fsm_node slot_fn_tbl[] = { + { ST_SLOT_NULL, EV_SLOT_BIND, slot_bind }, + { ST_SLOT_NULL, EV_STAT_ICALL, slot_icall }, + + { ST_SLOT_BOUND, EV_CMD_CLREAZ, slot_command }, + { ST_SLOT_BOUND, EV_CMD_SETEAZ, slot_command }, + { ST_SLOT_BOUND, EV_CMD_SETL2, slot_setl2 }, + { ST_SLOT_BOUND, EV_CMD_SETL3, slot_command }, + { ST_SLOT_BOUND, EV_CMD_DIAL, slot_dial }, + { ST_SLOT_BOUND, EV_SLOT_UNBIND, slot_unbind }, + + { ST_SLOT_IN, EV_CMD_SETL2, slot_setl2 }, + { ST_SLOT_IN, EV_CMD_SETL3, slot_command }, + { ST_SLOT_IN, EV_CMD_ACCEPTD, slot_acceptd }, + { ST_SLOT_IN, EV_STAT_DHUP, slot_in_dhup }, + + { ST_SLOT_WAIT_DCONN, EV_STAT_DCONN, slot_dconn }, + { ST_SLOT_WAIT_DCONN, EV_STAT_DHUP, slot_dhup }, + + { ST_SLOT_DCONN, EV_CMD_ACCEPTB, slot_acceptb }, + { ST_SLOT_DCONN, EV_STAT_BCONN, slot_bconn }, + + { ST_SLOT_WAIT_BCONN, EV_STAT_BCONN, slot_bconn }, + + { ST_SLOT_ACTIVE, EV_DATA_REQ, slot_data_req }, + { ST_SLOT_ACTIVE, EV_DATA_IND, slot_data_ind }, + { ST_SLOT_ACTIVE, EV_CMD_HANGUP, slot_actv_hangup }, + { ST_SLOT_ACTIVE, EV_STAT_BSENT, slot_bsent }, + { ST_SLOT_ACTIVE, EV_STAT_BHUP, slot_bhup }, + { ST_SLOT_ACTIVE, EV_STAT_FAXIND, slot_stat }, + { ST_SLOT_ACTIVE, EV_STAT_AUDIO, slot_stat }, + + { ST_SLOT_WAIT_BHUP, EV_STAT_BHUP, slot_bhup }, + + { ST_SLOT_WAIT_DHUP, EV_STAT_DHUP, slot_dhup }, +}; + +static struct fsm slot_fsm = { + .st_cnt = ARRAY_SIZE(slot_st_str), + .st_str = slot_st_str, + .ev_cnt = ARRAY_SIZE(ev_str), + .ev_str = ev_str, + .fn_cnt = ARRAY_SIZE(slot_fn_tbl), + .fn_tbl = slot_fn_tbl, +}; + +static void slot_debug(struct fsm_inst *fi, char *fmt, ...) +{ + va_list args; + struct isdn_slot *slot = fi->userdata; + char buf[128]; + char *p = buf; + + va_start(args, fmt); + p += sprintf(p, "slot %d(%d:%d): ", slot-slots, slot->di, slot->ch); + p += vsprintf(p, fmt, args); + va_end(args); + printk(KERN_DEBUG "%s\n", buf); +} + +/* ====================================================================== */ + +static spinlock_t stat_lock = SPIN_LOCK_UNLOCKED; + +static struct fsm drv_fsm; + +enum { + ST_DRV_NULL, + ST_DRV_LOADED, + ST_DRV_RUNNING, +}; + +static char *drv_st_str[] = { + "ST_DRV_NULL", + "ST_DRV_LOADED", + "ST_DRV_RUNNING", +}; + +#define DRV_FLAG_REJBUS 1 + +/* Description of hardware-level-driver */ +struct isdn_driver { + int di; + char id[20]; + atomic_t refcnt; + unsigned long flags; /* Misc driver Flags */ + unsigned long features; + 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 */ + char msn2eaz[10][ISDN_MSNLEN]; /* MSN->EAZ */ + struct fsm_inst fi; +} driver; + +static int __drv_command(struct isdn_driver *drv, isdn_ctrl *cmd); + +static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED; +static struct isdn_driver *drivers[ISDN_MAX_DRIVERS]; + +static int +isdn_writebuf_skb(struct isdn_slot *slot, struct sk_buff *skb) +{ + struct sk_buff *skb2; + struct isdn_driver *drv = slot->drv; + int hl = drv->interface->hl_hdrlen; + int retval; + + if (skb_headroom(skb) >= hl) { + retval = drv->interface->writebuf_skb(slot->di, slot->ch, 1, skb); + goto out; + } + skb2 = skb_realloc_headroom(skb, hl); + if (!skb2) { + retval = -ENOMEM; + goto out; + } + retval = drv->interface->writebuf_skb(slot->di, slot->ch, 1, skb2); + if (retval < 0) + kfree_skb(skb2); + else + kfree_skb(skb); + + out: + if (retval > 0) + slots->obytes += retval; + + return retval; +} + +int +__isdn_drv_lookup(char *drvid) +{ + int drvidx; + + for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { + if (!drivers[drvidx]) + continue; + + if (strcmp(drivers[drvidx]->id, drvid) == 0) + return drvidx; + } + return -1; +} + +int +isdn_drv_lookup(char *drvid) +{ + unsigned long flags; + int drvidx; + + spin_lock_irqsave(&drivers_lock, flags); + drvidx = __isdn_drv_lookup(drvid); + spin_unlock_irqrestore(&drivers_lock, flags); + return drvidx; +} + +static void +drv_destroy(struct isdn_driver *drv) +{ + kfree(drv); +} + +static inline struct isdn_driver * +get_drv(struct isdn_driver *drv) +{ + printk("get_drv %d: %d -> %d\n", drv->di, atomic_read(&drv->refcnt), + atomic_read(&drv->refcnt) + 1); + atomic_inc(&drv->refcnt); + return drv; +} + +static inline void +put_drv(struct isdn_driver *drv) +{ + printk("put_drv %d: %d -> %d\n", drv->di, atomic_read(&drv->refcnt), + atomic_read(&drv->refcnt) - 1); + if (atomic_dec_and_test(&drv->refcnt)) { + drv_destroy(drv); + } +} + +static struct isdn_driver * +get_drv_by_nr(int di) +{ + unsigned long flags; + struct isdn_driver *drv; + + if (di < 0) + return NULL; + + spin_lock_irqsave(&drivers_lock, flags); + drv = drivers[di]; + if (drv) + get_drv(drv); + spin_unlock_irqrestore(&drivers_lock, flags); + return drv; +} + +char * +isdn_drv_drvid(int di) +{ + if (!drivers[di]) { + isdn_BUG(); + return ""; + } + return drivers[di]->id; +} + +/* + * Helper keeping track of the features the drivers support + */ +static void +set_global_features(void) +{ + unsigned long flags; + int drvidx; + + dev->global_features = 0; + spin_lock_irqsave(&drivers_lock, flags); + for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { + if (!drivers[drvidx]) + continue; + if (drivers[drvidx]->fi.state != ST_DRV_RUNNING) + continue; + dev->global_features |= drivers[drvidx]->features; + } + spin_unlock_irqrestore(&drivers_lock, flags); +} + +/* + * driver state machine + */ +static int isdn_add_channels(struct isdn_driver *, int, int, int); +static void isdn_receive_skb_callback(int di, int ch, struct sk_buff *skb); +static int isdn_status_callback(isdn_ctrl * c); +static int isdn_dc2minor(int di, int ch); + +static void isdn_v110_add_features(struct isdn_driver *drv); + +static int +drv_register(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + isdn_if *iif = arg; + + fsm_change_state(fi, ST_DRV_LOADED); + drv->maxbufsize = iif->maxbufsize; + drv->interface = iif; + iif->channels = drv->di; + iif->rcvcallb_skb = isdn_receive_skb_callback; + iif->statcallb = isdn_status_callback; + + isdn_info_update(); +} + +static int +drv_stat_run(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + fsm_change_state(fi, ST_DRV_RUNNING); + + drv->features = drv->interface->features; + isdn_v110_add_features(drv); + set_global_features(); +} + +static int +drv_stat_stop(struct fsm_inst *fi, int pr, void *arg) +{ + fsm_change_state(fi, ST_DRV_LOADED); + set_global_features(); +} + +static int +drv_stat_unload(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + unsigned long flags; int i; - for (i = 0; i < dev->drivers; i++) - if (dev->drv[i]->locks > 0) { - isdn_ctrl cmd; + spin_lock_irqsave(&drivers_lock, flags); + drivers[drv->di] = NULL; + spin_unlock_irqrestore(&drivers_lock, flags); + put_drv(drv); - cmd.driver = i; - cmd.arg = 0; - cmd.command = ISDN_CMD_UNLOCK; - isdn_command(&cmd); - dev->drv[i]->locks--; + while (drv->locks > 0) { + isdn_ctrl cmd; + cmd.driver = drv->di; + cmd.arg = 0; + cmd.command = ISDN_CMD_UNLOCK; + __drv_command(drv, &cmd); + drv->locks--; + } + for (i = 0; i < ISDN_MAX_CHANNELS; i++) { + if (slots[i].di == drv->di) { + slots[i].di = -1; + slots[i].drv = NULL; + slots[i].ch = -1; + slots[i].usage &= ~ISDN_USAGE_DISABLED; + isdn_unregister_devfs(i); } + } + dev->channels -= drv->channels; + + isdn_info_update(); + return 0; } -void -isdn_MOD_DEC_USE_COUNT(void) +static int +drv_stat_addch(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + isdn_ctrl *c = arg; + + isdn_add_channels(drv, c->driver, c->arg, 1); + isdn_info_update(); +} + +static int +drv_stat_stavail(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + unsigned long flags; + isdn_ctrl *c = arg; + + spin_lock_irqsave(&stat_lock, flags); + drv->stavail += c->arg; + spin_unlock_irqrestore(&stat_lock, flags); + wake_up_interruptible(&drv->st_waitq); +} + +static int +drv_to_slot(struct fsm_inst *fi, int pr, void *arg) +{ + struct isdn_driver *drv = fi->userdata; + isdn_ctrl *c = arg; + int sl = isdn_dc2minor(drv->di, c->arg & 0xff); + + if (sl < 0) { + isdn_BUG(); + return 1; + } + return fsm_event(&slots[sl].fi, pr, arg); +} + +static struct fsm_node drv_fn_tbl[] = { + { ST_DRV_NULL, EV_DRV_REGISTER, drv_register }, + + { ST_DRV_LOADED, EV_STAT_RUN, drv_stat_run }, + { ST_DRV_LOADED, EV_STAT_STAVAIL, drv_stat_stavail }, + { ST_DRV_LOADED, EV_STAT_ADDCH, drv_stat_addch }, + { ST_DRV_LOADED, EV_STAT_UNLOAD, drv_stat_unload }, + + { ST_DRV_RUNNING, EV_STAT_STOP, drv_stat_stop }, + { ST_DRV_RUNNING, EV_STAT_STAVAIL, drv_stat_stavail }, + { ST_DRV_RUNNING, EV_STAT_ICALL, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_DCONN, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_BCONN, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_BHUP, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_DHUP, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_BSENT, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_CINF, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_CAUSE, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_DISPLAY, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_FAXIND, drv_to_slot }, + { ST_DRV_RUNNING, EV_STAT_AUDIO, drv_to_slot }, +}; + +static struct fsm drv_fsm = { + .st_cnt = ARRAY_SIZE(drv_st_str), + .st_str = drv_st_str, + .ev_cnt = ARRAY_SIZE(ev_str), + .ev_str = ev_str, + .fn_cnt = ARRAY_SIZE(drv_fn_tbl), + .fn_tbl = drv_fn_tbl, +}; + +static void drv_debug(struct fsm_inst *fi, char *fmt, ...) +{ + va_list args; + struct isdn_driver *drv = fi->userdata; + char buf[128]; + char *p = buf; + + va_start(args, fmt); + p += sprintf(p, "%s: ", drv->id); + p += vsprintf(p, fmt, args); + va_end(args); + printk(KERN_DEBUG "%s\n", buf); +} + +/* ====================================================================== */ +/* callbacks from hardware driver */ +/* ====================================================================== */ + +/* Receive a packet from B-Channel. */ +static void +isdn_receive_skb_callback(int di, int ch, struct sk_buff *skb) { - MOD_DEC_USE_COUNT; - isdn_unlock_drivers(); + struct isdn_driver *drv; + int sl; + + drv = get_drv_by_nr(di); + if (!drv) { + /* hardware driver is buggy - driver isn't registered */ + isdn_BUG(); + goto out; + } + /* we short-cut here instead of going through the driver fsm */ + if (drv->fi.state != ST_DRV_RUNNING) { + /* hardware driver is buggy - driver isn't running */ + isdn_BUG(); + goto out; + } + sl = isdn_dc2minor(di, ch); + if (sl < 0) { + isdn_BUG(); + goto out; + } + if (fsm_event(&slots[sl].fi, EV_DATA_IND, skb)) + dev_kfree_skb(skb); + out: + put_drv(drv); +} + +/* Receive status indications */ +static int +isdn_status_callback(isdn_ctrl *c) +{ + struct isdn_driver *drv; + int rc; + + drv = get_drv_by_nr(c->driver); + if (!drv) { + /* hardware driver is buggy - driver isn't registered */ + isdn_BUG(); + return 1; + } + + switch (c->command) { + case ISDN_STAT_STAVAIL: + rc = fsm_event(&drv->fi, EV_STAT_STAVAIL, c); + break; + case ISDN_STAT_RUN: + rc = fsm_event(&drv->fi, EV_STAT_RUN, c); + break; + case ISDN_STAT_STOP: + rc = fsm_event(&drv->fi, EV_STAT_STOP, c); + break; + case ISDN_STAT_UNLOAD: + rc = fsm_event(&drv->fi, EV_STAT_UNLOAD, c); + break; + case ISDN_STAT_ADDCH: + rc = fsm_event(&drv->fi, EV_STAT_ADDCH, c); + break; + case ISDN_STAT_ICALL: + rc = fsm_event(&drv->fi, EV_STAT_ICALL, c); + break; + case ISDN_STAT_DCONN: + rc = fsm_event(&drv->fi, EV_STAT_DCONN, c); + break; + case ISDN_STAT_BCONN: + rc = fsm_event(&drv->fi, EV_STAT_BCONN, c); + break; + case ISDN_STAT_BHUP: + rc = fsm_event(&drv->fi, EV_STAT_BHUP, c); + break; + case ISDN_STAT_DHUP: + rc = fsm_event(&drv->fi, EV_STAT_DHUP, c); + break; + case ISDN_STAT_BSENT: + rc = fsm_event(&drv->fi, EV_STAT_BSENT, c); + break; + case ISDN_STAT_CINF: + rc = fsm_event(&drv->fi, EV_STAT_CINF, c); + break; + case ISDN_STAT_CAUSE: + rc = fsm_event(&drv->fi, EV_STAT_CAUSE, c); + break; + case ISDN_STAT_DISPLAY: + rc = fsm_event(&drv->fi, EV_STAT_DISPLAY, c); + break; + case ISDN_STAT_FAXIND: + rc = fsm_event(&drv->fi, EV_STAT_FAXIND, c); + break; + case ISDN_STAT_AUDIO: + rc = fsm_event(&drv->fi, EV_STAT_AUDIO, c); + break; +#if 0 + case ISDN_STAT_ICALL: + /* Find any ttyI, waiting for D-channel setup */ + if (isdn_tty_stat_callback(i, c)) { + cmd.driver = di; + cmd.arg = c->arg; + cmd.command = ISDN_CMD_ACCEPTB; + isdn_command(&cmd); + break; + } + break; + switch (r) { + case 0: + if (divert_if) + if ((retval = divert_if->stat_callback(c))) + return(retval); /* processed */ + if ((!retval) && (drivers[di]->flags & DRV_FLAG_REJBUS)) { + /* No tty responding */ + cmd.driver = di; + cmd.arg = c->arg; + cmd.command = ISDN_CMD_HANGUP; + isdn_command(&cmd); + retval = 2; + } + break; + case 1: /* incoming call accepted by net interface */ + + case 2: /* For calling back, first reject incoming call ... */ + case 3: /* Interface found, but down, reject call actively */ + retval = 2; + printk(KERN_INFO "isdn: Rejecting Call\n"); + cmd.driver = di; + cmd.arg = c->arg; + cmd.command = ISDN_CMD_HANGUP; + isdn_command(&cmd); + if (r == 3) + break; + /* Fall through */ + case 4: + /* ... then start callback. */ + break; + case 5: + /* Number would eventually match, if longer */ + retval = 3; + break; + } + dbg_statcallb("ICALL: ret=%d\n", retval); + return retval; + break; + case ISDN_STAT_DHUP: + if (divert_if) + divert_if->stat_callback(c); + break; + case ISDN_STAT_BCONN: + break; + case ISDN_STAT_BHUP: + break; +#endif +#if 0 // FIXME + case ISDN_STAT_DISCH: + save_flags(flags); + cli(); + for (i = 0; i < ISDN_MAX_CHANNELS; i++) + if ((slots[i].di == di) && + (slots[i].ch == c->arg)) { + if (c->parm.num[0]) + slots[i].usage &= ~ISDN_USAGE_DISABLED; + else if (USG_NONE(isdn_slot_usage(i))) + slots[i].usage |= ISDN_USAGE_DISABLED; + else + retval = -1; + break; + } + restore_flags(flags); + break; + case CAPI_PUT_MESSAGE: + return(isdn_capi_rec_hl_msg(&c->parm.cmsg)); + case ISDN_STAT_PROT: + case ISDN_STAT_REDIR: + if (divert_if) + return(divert_if->stat_callback(c)); +#endif + default: + rc = 1; + } + put_drv(drv); + return rc; +} + +/* ====================================================================== */ + +/* + * Register a new ISDN interface + */ +int +register_isdn(isdn_if *iif) +{ + struct isdn_driver *drv; + unsigned long flags; + int drvidx; + + drv = kmalloc(sizeof(*drv), GFP_KERNEL); + if (!drv) { + printk(KERN_WARNING "register_isdn: out of mem\n"); + goto fail; + } + memset(drv, 0, sizeof(*drv)); + + atomic_set(&drv->refcnt, 0); + drv->fi.fsm = &drv_fsm; + drv->fi.state = ST_DRV_NULL; + drv->fi.debug = 1; + drv->fi.userdata = drv; + drv->fi.printdebug = drv_debug; + + spin_lock_irqsave(&drivers_lock, flags); + for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) + if (!drivers[drvidx]) + break; + + if (drvidx == ISDN_MAX_DRIVERS) + goto fail_unlock; + + if (!strlen(iif->id)) + sprintf(iif->id, "line%d", drvidx); + + if (__isdn_drv_lookup(iif->id) >= 0) + goto fail_unlock; + + strcpy(drv->id, iif->id); + if (isdn_add_channels(drv, drvidx, iif->channels, 0)) + goto fail_unlock; + + drv->di = drvidx; + drivers[drvidx] = get_drv(drv); + spin_unlock_irqrestore(&drivers_lock, flags); + + fsm_event(&drv->fi, EV_DRV_REGISTER, iif); + return 1; + + fail_unlock: + spin_unlock_irqrestore(&drivers_lock, flags); + kfree(drv); + fail: + return 0; +} + +/* ====================================================================== */ + +#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE) +static isdn_divert_if *divert_if; /* = NULL */ +#else +#define divert_if ((isdn_divert_if *) NULL) +#endif + +static int isdn_wildmat(char *s, char *p); + +static void +isdn_lock_driver(struct isdn_driver *drv) +{ + isdn_ctrl cmd; + + cmd.driver = drv->di; + cmd.arg = 0; + cmd.command = ISDN_CMD_LOCK; + __drv_command(drv, &cmd); +} + +static void +isdn_unlock_driver(struct isdn_driver *drv) +{ + isdn_ctrl cmd; + + cmd.driver = drv->di; + cmd.arg = 0; + cmd.command = ISDN_CMD_UNLOCK; + __drv_command(drv, &cmd); } #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) @@ -235,177 +1120,54 @@ int isdn_msncmp( const char * msn1, const char * msn2 ) return isdn_wildmat( TmpMsn1, TmpMsn2 ); } -int +static int isdn_dc2minor(int di, int ch) { int i; for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (slot[i].ch == ch && slot[i].di == di) + if (slots[i].ch == ch && slots[i].di == di) return i; return -1; } -static int isdn_timer_cnt2 = 0; -static int isdn_timer_cnt3 = 0; - -static void -isdn_timer_funct(ulong dummy) -{ - int tf = dev->tflags; - if (tf & ISDN_TIMER_FAST) { - if (tf & ISDN_TIMER_MODEMREAD) - isdn_tty_readmodem(); - if (tf & ISDN_TIMER_MODEMPLUS) - isdn_tty_modem_escape(); - if (tf & ISDN_TIMER_MODEMXMIT) - isdn_tty_modem_xmit(); - } - if (tf & ISDN_TIMER_SLOW) { - if (++isdn_timer_cnt2 >= ISDN_TIMER_1SEC) { - isdn_timer_cnt2 = 0; - if (++isdn_timer_cnt3 >= ISDN_TIMER_RINGING) { - isdn_timer_cnt3 = 0; - if (tf & ISDN_TIMER_MODEMRING) - isdn_tty_modem_ring(); - } - if (tf & ISDN_TIMER_CARRIER) - isdn_tty_carrier_timeout(); - } - } - if (tf) - { - unsigned long flags; - - save_flags(flags); - cli(); - mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES); - restore_flags(flags); - } -} - -void -isdn_timer_ctrl(int tf, int onoff) -{ - unsigned long flags; - int old_tflags; - - save_flags(flags); - cli(); - if ((tf & ISDN_TIMER_SLOW) && (!(dev->tflags & ISDN_TIMER_SLOW))) { - /* If the slow-timer wasn't activated until now */ - isdn_timer_cnt2 = 0; - } - old_tflags = dev->tflags; - if (onoff) - dev->tflags |= tf; - else - dev->tflags &= ~tf; - if (dev->tflags && !old_tflags) - mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES); - restore_flags(flags); -} - -/* - * Receive a packet from B-Channel. (Called from low-level-module) - */ -static void -isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb) -{ - int i; - - if ((i = isdn_dc2minor(di, channel)) == -1) { - dev_kfree_skb(skb); - return; - } - /* Update statistics */ - slot[i].ibytes += skb->len; - - /* First, try to deliver data to network-device */ - if (isdn_net_rcv_skb(i, skb)) - return; - - /* V.110 handling - * makes sense for async streams only, so it is - * called after possible net-device delivery. - */ - if (slot[i].iv110.v110) { - atomic_inc(&slot[i].iv110.v110use); - skb = isdn_v110_decode(slot[i].iv110.v110, skb); - atomic_dec(&slot[i].iv110.v110use); - if (!skb) - return; - } - - /* No network-device found, deliver to tty or raw-channel */ - if (skb->len) { - if (isdn_tty_rcv_skb(i, di, channel, skb)) - return; - wake_up_interruptible(&dev->drv[di]->rcv_waitq[channel]); - } else - dev_kfree_skb(skb); -} - -/* - * Intercept command from Linklevel to Lowlevel. - * If layer 2 protocol is V.110 and this is not supported by current - * lowlevel-driver, use driver's transparent mode and handle V.110 in - * linklevel instead. - */ static int -isdn_command(isdn_ctrl *cmd) +__drv_command(struct isdn_driver *drv, isdn_ctrl *c) { - int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); - - if (cmd->driver == -1) { - printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); - return(1); - } - if (cmd->command == ISDN_CMD_SETL2) { - unsigned long l2prot = (cmd->arg >> 8) & 255; - unsigned long features = (dev->drv[cmd->driver]->interface->features - >> ISDN_FEATURE_L2_SHIFT) & - ISDN_FEATURE_L2_MASK; - unsigned long l2_feature = (1 << l2prot); - - switch (l2prot) { - case ISDN_PROTO_L2_V11096: - case ISDN_PROTO_L2_V11019: - case ISDN_PROTO_L2_V11038: - /* If V.110 requested, but not supported by - * HL-driver, set emulator-flag and change - * Layer-2 to transparent - */ - if (!(features & l2_feature)) { - slot[idx].iv110.v110emu = l2prot; - cmd->arg = (cmd->arg & 255) | - (ISDN_PROTO_L2_TRANS << 8); - } else - slot[idx].iv110.v110emu = 0; - } - } #ifdef ISDN_DEBUG_COMMAND - switch (cmd->command) { + switch (c->command) { + case ISDN_CMD_LOCK: + printk(KERN_DEBUG "ISDN_CMD_LOCK %d/%ld\n", c->driver, c->arg & 0xff); break; + case ISDN_CMD_UNLOCK: + printk(KERN_DEBUG "ISDN_CMD_UNLOCK %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_SETL2: - printk(KERN_DEBUG "ISDN_CMD_SETL2 %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_SETL2 %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_SETL3: - printk(KERN_DEBUG "ISDN_CMD_SETL3 %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_SETL3 %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_DIAL: - printk(KERN_DEBUG "ISDN_CMD_DIAL %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_DIAL %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_ACCEPTD: - printk(KERN_DEBUG "ISDN_CMD_ACCEPTD %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_ACCEPTD %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_ACCEPTB: - printk(KERN_DEBUG "ISDN_CMD_ACCEPTB %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_ACCEPTB %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_HANGUP: - printk(KERN_DEBUG "ISDN_CMD_HANGUP %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_HANGUP %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_CLREAZ: - printk(KERN_DEBUG "ISDN_CMD_CLREAZ %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_CLREAZ %d/%ld\n", c->driver, c->arg & 0xff); break; case ISDN_CMD_SETEAZ: - printk(KERN_DEBUG "ISDN_CMD_SETEAZ %d\n", idx); break; + printk(KERN_DEBUG "ISDN_CMD_SETEAZ %d/%ld\n", c->driver, c->arg & 0xff); break; default: - printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, cmd->command); + printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, c->command); } #endif - return dev->drv[cmd->driver]->interface->command(cmd); + return drv->interface->command(c); +} + +static int +__slot_command(struct isdn_slot *slot, isdn_ctrl *cmd) +{ + struct isdn_driver *drv = slot->drv; + + return __drv_command(drv, cmd); } /* @@ -431,283 +1193,6 @@ isdn_capi_rec_hl_msg(capi_msg *cm) { } } -static int -isdn_status_callback(isdn_ctrl * c) -{ - int di; - ulong flags; - int i; - int r; - int retval = 0; - isdn_ctrl cmd; - struct list_head *l; - - di = c->driver; - i = isdn_dc2minor(di, c->arg); - switch (c->command) { - case ISDN_STAT_BSENT: - if (i < 0) - return -1; - if (isdn_net_stat_callback(i, c)) - return 0; - if (isdn_v110_stat_callback(&slot[i].iv110, c)) - return 0; - if (isdn_tty_stat_callback(i, c)) - return 0; - wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]); - break; - case ISDN_STAT_STAVAIL: - save_flags(flags); - cli(); - dev->drv[di]->stavail += c->arg; - restore_flags(flags); - wake_up_interruptible(&dev->drv[di]->st_waitq); - break; - case ISDN_STAT_RUN: - dev->drv[di]->flags |= DRV_FLAG_RUNNING; - for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (slot[i].di == di) - isdn_slot_all_eaz(i); - set_global_features(); - break; - case ISDN_STAT_STOP: - dev->drv[di]->flags &= ~DRV_FLAG_RUNNING; - break; - case ISDN_STAT_ICALL: - if (i < 0) - return -1; - dbg_statcallb("ICALL: %d (%d,%ld) %s\n", i, di, c->arg, c->parm.num); - if (dev->global_flags & ISDN_GLOBAL_STOPPED) - return 0; - - /* Try to find a network-interface which will accept incoming call */ - r = isdn_net_find_icall(di, c->arg, i, &c->parm.setup); - switch (r) { - case 0: - /* No network-device replies. - * Try ttyI's. - * These return 0 on no match, 1 on match and - * 3 on eventually match, if CID is longer. - */ - if (c->command == ISDN_STAT_ICALL) - if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval); - if (divert_if) - if ((retval = divert_if->stat_callback(c))) - return(retval); /* processed */ - if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) { - /* No tty responding */ - cmd.driver = di; - cmd.arg = c->arg; - cmd.command = ISDN_CMD_HANGUP; - isdn_command(&cmd); - retval = 2; - } - break; - case 1: /* incoming call accepted by net interface */ - list_for_each(l, &isdn_net_devs) { - isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list); - if (p->isdn_slot == i) { - strcpy(cmd.parm.setup.eazmsn, p->mlp->msn); - isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET); - strcpy(isdn_slot_num(i), c->parm.setup.phone); - - isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd); - retval = 1; - break; - } - } - break; - - case 2: /* For calling back, first reject incoming call ... */ - case 3: /* Interface found, but down, reject call actively */ - retval = 2; - printk(KERN_INFO "isdn: Rejecting Call\n"); - cmd.driver = di; - cmd.arg = c->arg; - cmd.command = ISDN_CMD_HANGUP; - isdn_command(&cmd); - if (r == 3) - break; - /* Fall through */ - case 4: - /* ... then start callback. */ - break; - case 5: - /* Number would eventually match, if longer */ - retval = 3; - break; - } - dbg_statcallb("ICALL: ret=%d\n", retval); - return retval; - break; - case ISDN_STAT_CINF: - if (i < 0) - return -1; - dbg_statcallb("CINF: %d %s\n", i, c->parm.num); - if (strcmp(c->parm.num, "0")) - isdn_net_stat_callback(i, c); - isdn_tty_stat_callback(i, c); - break; - case ISDN_STAT_CAUSE: - dbg_statcallb("CAUSE: %d %s\n", i, c->parm.num); - printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n", - dev->drvid[di], c->arg, c->parm.num); - isdn_tty_stat_callback(i, c); - if (divert_if) - divert_if->stat_callback(c); - break; - case ISDN_STAT_DISPLAY: - dbg_statcallb("DISPLAY: %d %s\n", i, c->parm.display); - isdn_tty_stat_callback(i, c); - if (divert_if) - divert_if->stat_callback(c); - break; - case ISDN_STAT_DCONN: - if (i < 0) - return -1; - dbg_statcallb("DCONN: %d\n", i); - /* Find any net-device, waiting for D-channel setup */ - if (isdn_net_stat_callback(i, c)) - break; - isdn_v110_stat_callback(&slot[i].iv110, c); - /* Find any ttyI, waiting for D-channel setup */ - if (isdn_tty_stat_callback(i, c)) { - cmd.driver = di; - cmd.arg = c->arg; - cmd.command = ISDN_CMD_ACCEPTB; - isdn_command(&cmd); - break; - } - break; - case ISDN_STAT_DHUP: - if (i < 0) - return -1; - dbg_statcallb("DHUP: %d\n", i); - dev->drv[di]->online &= ~(1 << (c->arg)); - isdn_info_update(); - /* Signal hangup to network-devices */ - if (isdn_net_stat_callback(i, c)) - break; - isdn_v110_stat_callback(&slot[i].iv110, c); - if (isdn_tty_stat_callback(i, c)) - break; - if (divert_if) - divert_if->stat_callback(c); - break; - case ISDN_STAT_BCONN: - if (i < 0) - return -1; - dbg_statcallb("BCONN: %ld\n", c->arg); - /* Signal B-channel-connect to network-devices */ - dev->drv[di]->online |= (1 << (c->arg)); - isdn_info_update(); - if (isdn_net_stat_callback(i, c)) - break; - isdn_v110_stat_callback(&slot[i].iv110, c); - if (isdn_tty_stat_callback(i, c)) - break; - break; - case ISDN_STAT_BHUP: - if (i < 0) - return -1; - dbg_statcallb("BHUP: %d\n", i); - dev->drv[di]->online &= ~(1 << (c->arg)); - isdn_info_update(); - /* Signal hangup to network-devices */ - if (isdn_net_stat_callback(i, c)) - break; - isdn_v110_stat_callback(&slot[i].iv110, c); - if (isdn_tty_stat_callback(i, c)) - break; - break; - case ISDN_STAT_NODCH: - if (i < 0) - return -1; - dbg_statcallb("NODCH: %ld\n", c->arg); - if (isdn_net_stat_callback(i, c)) - break; - if (isdn_tty_stat_callback(i, c)) - break; - break; - case ISDN_STAT_ADDCH: - if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) - return -1; - isdn_info_update(); - break; - case ISDN_STAT_DISCH: - save_flags(flags); - cli(); - for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if ((slot[i].di == di) && - (slot[i].ch == c->arg)) { - if (c->parm.num[0]) - isdn_slot_set_usage(i, isdn_slot_usage(i) & ~ISDN_USAGE_DISABLED); - else if (USG_NONE(isdn_slot_usage(i))) - isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_DISABLED); - else - retval = -1; - break; - } - restore_flags(flags); - break; - case ISDN_STAT_UNLOAD: - while (dev->drv[di]->locks > 0) { - isdn_ctrl cmd; - cmd.driver = di; - cmd.arg = 0; - cmd.command = ISDN_CMD_UNLOCK; - isdn_command(&cmd); - dev->drv[di]->locks--; - } - save_flags(flags); - cli(); - isdn_tty_stat_callback(i, c); - for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (slot[i].di == di) { - slot[i].di = -1; - slot[i].ch = -1; - slot[i].usage &= ~ISDN_USAGE_DISABLED; - isdn_unregister_devfs(i); - } - dev->drivers--; - dev->channels -= dev->drv[di]->channels; - kfree(dev->drv[di]->rcverr); - kfree(dev->drv[di]->rcvcount); - for (i = 0; i < dev->drv[di]->channels; i++) - skb_queue_purge(&dev->drv[di]->rpqueue[i]); - kfree(dev->drv[di]->rpqueue); - kfree(dev->drv[di]->rcv_waitq); - kfree(dev->drv[di]); - dev->drv[di] = NULL; - dev->drvid[di][0] = '\0'; - isdn_info_update(); - set_global_features(); - restore_flags(flags); - return 0; - case ISDN_STAT_L1ERR: - break; - case CAPI_PUT_MESSAGE: - return(isdn_capi_rec_hl_msg(&c->parm.cmsg)); -#ifdef CONFIG_ISDN_TTY_FAX - case ISDN_STAT_FAXIND: - isdn_tty_stat_callback(i, c); - break; -#endif -#ifdef CONFIG_ISDN_AUDIO - case ISDN_STAT_AUDIO: - isdn_tty_stat_callback(i, c); - break; -#endif - case ISDN_STAT_PROT: - case ISDN_STAT_REDIR: - if (divert_if) - return(divert_if->stat_callback(c)); - default: - return -1; - } - return 0; -} - /* * Get integer from char-pointer, set pointer to end of number */ @@ -721,120 +1206,16 @@ isdn_getnum(char **p) return v; } -#define DLE 0x10 - -/* - * isdn_slot_readbchan() tries to get data from the read-queue. - * It MUST be called with interrupts off. - */ -int -isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len) -{ - int count; - int count_pull; - int count_put; - int dflag; - int di = isdn_slot_driver(sl); - int ch = isdn_slot_channel(sl); - struct sk_buff *skb; - u_char *cp; - - if (!dev->drv[di]) - return 0; - if (skb_queue_empty(&dev->drv[di]->rpqueue[ch])) - return 0; - - if (len > dev->drv[di]->rcvcount[ch]) - len = dev->drv[di]->rcvcount[ch]; - cp = buf; - count = 0; - while (len) { - if (!(skb = skb_peek(&dev->drv[di]->rpqueue[ch]))) - break; -#ifdef CONFIG_ISDN_AUDIO - if (ISDN_AUDIO_SKB_LOCK(skb)) - break; - ISDN_AUDIO_SKB_LOCK(skb) = 1; - if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << ch))) { - char *p = skb->data; - unsigned long DLEmask = (1 << ch); - - dflag = 0; - count_pull = count_put = 0; - while ((count_pull < skb->len) && (len > 0)) { - len--; - if (dev->drv[di]->DLEflag & DLEmask) { - *cp++ = DLE; - dev->drv[di]->DLEflag &= ~DLEmask; - } else { - *cp++ = *p; - if (*p == DLE) { - dev->drv[di]->DLEflag |= DLEmask; - (ISDN_AUDIO_SKB_DLECOUNT(skb))--; - } - p++; - count_pull++; - } - count_put++; - } - if (count_pull >= skb->len) - dflag = 1; - } else { -#endif - /* No DLE's in buff, so simply copy it */ - dflag = 1; - if ((count_pull = skb->len) > len) { - count_pull = len; - dflag = 0; - } - count_put = count_pull; - memcpy(cp, skb->data, count_put); - cp += count_put; - len -= count_put; -#ifdef CONFIG_ISDN_AUDIO - } -#endif - count += count_put; - if (fp) { - memset(fp, 0, count_put); - fp += count_put; - } - if (dflag) { - /* We got all the data in this buff. - * Now we can dequeue it. - */ - if (fp) - *(fp - 1) = 0xff; -#ifdef CONFIG_ISDN_AUDIO - ISDN_AUDIO_SKB_LOCK(skb) = 0; -#endif - skb = skb_dequeue(&dev->drv[di]->rpqueue[ch]); - dev_kfree_skb(skb); - } else { - /* Not yet emptied this buff, so it - * must stay in the queue, for further calls - * but we pull off the data we got until now. - */ - skb_pull(skb, count_pull); -#ifdef CONFIG_ISDN_AUDIO - ISDN_AUDIO_SKB_LOCK(skb) = 0; -#endif - } - dev->drv[di]->rcvcount[ch] -= count_put; - } - return count; -} - static __inline int isdn_minor2drv(int minor) { - return slot[minor].di; + return slots[minor].di; } static __inline int isdn_minor2chan(int minor) { - return slot[minor].ch; + return slots[minor].ch; } static char * @@ -847,32 +1228,32 @@ isdn_statstr(void) sprintf(istatbuf, "idmap:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - sprintf(p, "%s ", (slot[i].di < 0) ? "-" : dev->drvid[slot[i].di]); + sprintf(p, "%s ", (slots[i].di < 0) ? "-" : isdn_drv_drvid(slots[i].di)); p = istatbuf + strlen(istatbuf); } sprintf(p, "\nchmap:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - sprintf(p, "%d ", slot[i].ch); + sprintf(p, "%d ", slots[i].ch); p = istatbuf + strlen(istatbuf); } sprintf(p, "\ndrmap:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - sprintf(p, "%d ", slot[i].di); + sprintf(p, "%d ", slots[i].di); p = istatbuf + strlen(istatbuf); } sprintf(p, "\nusage:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - sprintf(p, "%d ", slot[i].usage); + sprintf(p, "%d ", slots[i].usage); p = istatbuf + strlen(istatbuf); } sprintf(p, "\nflags:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_DRIVERS; i++) { - if (dev->drv[i]) { - sprintf(p, "%ld ", dev->drv[i]->online); + if (drivers[i]) { + sprintf(p, "0 "); p = istatbuf + strlen(istatbuf); } else { sprintf(p, "? "); @@ -882,7 +1263,7 @@ isdn_statstr(void) sprintf(p, "\nphone:\t"); p = istatbuf + strlen(istatbuf); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - sprintf(p, "%s ", isdn_slot_num(i)); + sprintf(p, "%s ", slots[i].num); p = istatbuf + strlen(istatbuf); } sprintf(p, "\n"); @@ -1026,8 +1407,8 @@ isdn_status_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) sizeof(ulong) * ISDN_MAX_CHANNELS * 2))) return ret; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - put_user(slot[i].ibytes, p++); - put_user(slot[i].obytes, p++); + put_user(slots[i].ibytes, p++); + put_user(slots[i].obytes, p++); } return 0; } else @@ -1057,132 +1438,128 @@ static struct file_operations isdn_status_fops = */ static int -isdn_ctrl_open(struct inode *ino, struct file *filep) +isdn_ctrl_open(struct inode *ino, struct file *file) { - uint minor = minor(ino->i_rdev); - int drvidx; + unsigned int minor = minor(ino->i_rdev); + int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); + struct isdn_driver *drv; - drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); - if (drvidx < 0) + drv = get_drv_by_nr(drvidx); + if (!drv) return -ENODEV; - isdn_lock_drivers(); + isdn_lock_driver(drv); + + file->private_data = drv; return 0; } static int -isdn_ctrl_release(struct inode *ino, struct file *filep) +isdn_ctrl_release(struct inode *ino, struct file *file) { - lock_kernel(); + struct isdn_driver *drv = file->private_data; if (dev->profd == current) dev->profd = NULL; - isdn_unlock_drivers(); + isdn_unlock_driver(drv); + put_drv(drv); - unlock_kernel(); return 0; } static ssize_t isdn_ctrl_read(struct file *file, char *buf, size_t count, loff_t * off) { - uint minor = minor(file->f_dentry->d_inode->i_rdev); - ulong flags; + struct isdn_driver *drv = file->private_data; + unsigned int minor = minor(file->f_dentry->d_inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; int len = 0; - int drvidx; - int retval; + if (off != &file->f_pos) return -ESPIPE; - lock_kernel(); - - drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); - if (drvidx < 0) { - retval = -ENODEV; - goto out; + if (!drv->interface->readstat) { + isdn_BUG(); + return 0; } - if (!dev->drv[drvidx]->stavail) { + add_wait_queue(&drv->st_waitq, &wait); + for (;;) { + spin_lock_irqsave(&stat_lock, flags); + len = drv->stavail; + spin_unlock_irqrestore(&stat_lock, flags); + if (len > 0) + break; + if (signal_pending(current)) { + len = -ERESTARTSYS; + break; + } if (file->f_flags & O_NONBLOCK) { - retval = -EAGAIN; - goto out; + len = -EAGAIN; + break; } - interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq)); + schedule(); } - if (dev->drv[drvidx]->interface->readstat) { - if (count > dev->drv[drvidx]->stavail) - count = dev->drv[drvidx]->stavail; - len = dev->drv[drvidx]->interface-> - readstat(buf, count, 1, drvidx, - isdn_minor2chan(minor)); + __set_current_state(TASK_RUNNING); + remove_wait_queue(&drv->st_waitq, &wait); + + if (len < 0) + return len; + + if (count > len) + count = len; + + len = drv->interface->readstat(buf, count, 1, drv->di, + isdn_minor2chan(minor)); + + spin_lock_irqsave(&stat_lock, flags); + if (len) { + drv->stavail -= len; } else { - len = 0; + isdn_BUG(); + drv->stavail = 0; } - save_flags(flags); - cli(); - if (len) - dev->drv[drvidx]->stavail -= len; - else - dev->drv[drvidx]->stavail = 0; - restore_flags(flags); + spin_unlock_irqrestore(&stat_lock, flags); + *off += len; - retval = len; - - out: - unlock_kernel(); - return retval; + return len; } static ssize_t isdn_ctrl_write(struct file *file, const char *buf, size_t count, loff_t *off) { - uint minor = minor(file->f_dentry->d_inode->i_rdev); - int drvidx; + struct isdn_driver *drv = file->private_data; + unsigned int minor = minor(file->f_dentry->d_inode->i_rdev); int retval; if (off != &file->f_pos) return -ESPIPE; - lock_kernel(); - - drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); - if (drvidx < 0) { - retval = -ENODEV; - goto out; - } - if (!dev->drv[drvidx]->interface->writecmd) { + if (!drv->interface->writecmd) { retval = -EINVAL; goto out; } - retval = dev->drv[drvidx]->interface-> - writecmd(buf, count, 1, drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL)); + retval = drv->interface-> + writecmd(buf, count, 1, drv->di, + isdn_minor2chan(minor - ISDN_MINOR_CTRL)); out: - unlock_kernel(); return retval; } static unsigned int isdn_ctrl_poll(struct file *file, poll_table *wait) { + struct isdn_driver *drv = file->private_data; unsigned int mask = 0; - unsigned int minor = minor(file->f_dentry->d_inode->i_rdev); - int drvidx; - drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); - if (drvidx < 0) - /* driver deregistered while file open */ - return POLLHUP; - - lock_kernel(); - - poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait); + poll_wait(file, &drv->st_waitq, wait); mask = POLLOUT | POLLWRNORM; - if (dev->drv[drvidx]->stavail) + if (drv->stavail) mask |= POLLIN | POLLRDNORM; - unlock_kernel(); return mask; } @@ -1240,7 +1617,6 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) case IIOCSETBRJ: drvidx = -1; if (arg) { - int i; char *p; if (copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct))) @@ -1248,20 +1624,15 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) if (strlen(iocts.drvid)) { if ((p = strchr(iocts.drvid, ','))) *p = 0; - drvidx = -1; - for (i = 0; i < ISDN_MAX_DRIVERS; i++) - if (!(strcmp(dev->drvid[i], iocts.drvid))) { - drvidx = i; - break; - } + drvidx = isdn_drv_lookup(iocts.drvid); } } if (drvidx == -1) return -ENODEV; if (iocts.arg) - dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS; + drivers[drvidx]->flags |= DRV_FLAG_REJBUS; else - dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS; + drivers[drvidx]->flags &= ~DRV_FLAG_REJBUS; return 0; case IIOCSIGPRF: dev->profd = current; @@ -1279,14 +1650,14 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) return ret; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - if (copy_to_user(p, dev->mdm.info[i].emu.profile, + if (copy_to_user(p, isdn_mdm.info[i].emu.profile, ISDN_MODEM_NUMREG)) return -EFAULT; p += ISDN_MODEM_NUMREG; - if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN)) + if (copy_to_user(p, isdn_mdm.info[i].emu.pmsn, ISDN_MSNLEN)) return -EFAULT; p += ISDN_MSNLEN; - if (copy_to_user(p, dev->mdm.info[i].emu.plmsn, ISDN_LMSNLEN)) + if (copy_to_user(p, isdn_mdm.info[i].emu.plmsn, ISDN_LMSNLEN)) return -EFAULT; p += ISDN_LMSNLEN; } @@ -1306,14 +1677,14 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) return ret; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - if (copy_from_user(dev->mdm.info[i].emu.profile, p, + if (copy_from_user(isdn_mdm.info[i].emu.profile, p, ISDN_MODEM_NUMREG)) return -EFAULT; p += ISDN_MODEM_NUMREG; - if (copy_from_user(dev->mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN)) + if (copy_from_user(isdn_mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN)) return -EFAULT; p += ISDN_LMSNLEN; - if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN)) + if (copy_from_user(isdn_mdm.info[i].emu.pmsn, p, ISDN_MSNLEN)) return -EFAULT; p += ISDN_MSNLEN; } @@ -1330,15 +1701,7 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) (char *) arg, sizeof(isdn_ioctl_struct))) return -EFAULT; - if (strlen(iocts.drvid)) { - drvidx = -1; - for (i = 0; i < ISDN_MAX_DRIVERS; i++) - if (!(strcmp(dev->drvid[i], iocts.drvid))) { - drvidx = i; - break; - } - } else - drvidx = 0; + drvidx = isdn_drv_lookup(iocts.drvid); if (drvidx == -1) return -ENODEV; if (cmd == IIOCSETMAP) { @@ -1359,7 +1722,7 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) /* Fall through */ case ',': bname[j] = '\0'; - strcpy(dev->drv[drvidx]->msn2eaz[i], bname); + strcpy(drivers[drvidx]->msn2eaz[i], bname); j = ISDN_MSNLEN; break; default: @@ -1375,8 +1738,8 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) p = (char *) iocts.arg; for (i = 0; i < 10; i++) { sprintf(bname, "%s%s", - strlen(dev->drv[drvidx]->msn2eaz[i]) ? - dev->drv[drvidx]->msn2eaz[i] : "_", + strlen(drivers[drvidx]->msn2eaz[i]) ? + drivers[drvidx]->msn2eaz[i] : "_", (i < 9) ? "," : "\0"); if (copy_to_user(p, bname, strlen(bname) + 1)) return -EFAULT; @@ -1400,21 +1763,9 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) else return -EINVAL; if (arg) { - int i; - char *p; if (copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct))) return -EFAULT; - if (strlen(iocts.drvid)) { - if ((p = strchr(iocts.drvid, ','))) - *p = 0; - drvidx = -1; - for (i = 0; i < ISDN_MAX_DRIVERS; i++) - if (!(strcmp(dev->drvid[i], iocts.drvid))) { - drvidx = i; - break; - } - } else - drvidx = 0; + drvidx = isdn_drv_lookup(iocts.drvid); if (drvidx == -1) return -ENODEV; if ((ret = verify_area(VERIFY_WRITE, (void *) arg, @@ -1424,7 +1775,7 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) c.command = ISDN_CMD_IOCTL; c.arg = cmd; memcpy(c.parm.num, (char *) &iocts.arg, sizeof(ulong)); - ret = isdn_command(&c); + ret = __drv_command(drivers[drvidx], &c); memcpy((char *) &iocts.arg, c.parm.num, sizeof(ulong)); if (copy_to_user((char *) arg, &iocts, sizeof(isdn_ioctl_struct))) return -EFAULT; @@ -1498,7 +1849,7 @@ static struct file_operations isdn_fops = char * isdn_map_eaz2msn(char *msn, int di) { - driver *this = dev->drv[di]; + struct isdn_driver *this = drivers[di]; int i; if (strlen(msn) == 1) { @@ -1514,167 +1865,78 @@ isdn_map_eaz2msn(char *msn, int di) * Find an unused ISDN-channel, whose feature-flags match the * given L2- and L3-protocols. */ -#define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038)) - -int +struct isdn_slot * isdn_get_free_slot(int usage, int l2_proto, int l3_proto, int pre_dev, int pre_chan, char *msn) { + struct isdn_slot *slot; int i; - ulong flags; - ulong features; - ulong vfeatures; + unsigned long flags; + unsigned long features; save_flags(flags); cli(); features = ((1 << l2_proto) | (0x10000 << l3_proto)); - vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) & - ~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038)); - /* If Layer-2 protocol is V.110, accept drivers with - * transparent feature even if these don't support V.110 - * because we can emulate this in linklevel. - */ - for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (USG_NONE(slot[i].usage) && - (slot[i].di != -1)) { - int d = slot[i].di; - if (!strcmp(isdn_map_eaz2msn(msn, d), "-")) - continue; - if (slot[i].usage & ISDN_USAGE_DISABLED) - continue; /* usage not allowed */ - if (!dev->drv[d]->flags & DRV_FLAG_RUNNING) - continue; - if (((dev->drv[d]->interface->features & features) == features) || - (((dev->drv[d]->interface->features & vfeatures) == vfeatures) && - (dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) { - if (pre_dev < 0 || pre_chan < 0 || - (pre_dev == d && pre_chan == slot[i].ch)) { - isdn_slot_set_usage(i, usage); - restore_flags(flags); - return i; - } - } + + for (i = 0; i < ISDN_MAX_CHANNELS; i++) { + slot = &slots[i]; + + if (!slot->drv || slot->drv->fi.state != ST_DRV_RUNNING) + continue; + + if (!USG_NONE(slots[i].usage)) + continue; + + if (slots[i].usage & ISDN_USAGE_DISABLED) + continue; + + if (slots[i].di == -1) + continue; + + if (strcmp(isdn_map_eaz2msn(msn, slot->di), "-") == 0) + continue; + + if (!(drivers[slot->di]->features & features) == features) + continue; + + if (pre_dev < 0 || pre_chan < 0 || + (pre_dev == slot->di && pre_chan == slot->ch)) { + slot->usage = usage; + isdn_info_update(); + fsm_event(&slot->fi, EV_SLOT_BIND, NULL); + return slot; } + } restore_flags(flags); - return -1; + return NULL; } /* * Set state of ISDN-channel to 'unused' */ void -isdn_free_channel(int di, int ch, int usage) -{ - int sl; - - sl = isdn_dc2minor(di, ch); - isdn_slot_free(sl); -} - -void -isdn_slot_free(int sl) +isdn_slot_free(struct isdn_slot *slot) { - unsigned long flags; - - save_flags(flags); - cli(); - strcpy(isdn_slot_num(sl), "???"); - slot[sl].ibytes = 0; - slot[sl].obytes = 0; -// 20.10.99 JIM, try to reinitialize v110 ! - slot[sl].iv110.v110emu = 0; - atomic_set(&slot[sl].iv110.v110use, 0); - isdn_v110_close(slot[sl].iv110.v110); - slot[sl].iv110.v110 = NULL; -// 20.10.99 JIM, try to reinitialize v110 ! - isdn_slot_set_usage(sl, ISDN_USAGE_NONE); - skb_queue_purge(&dev->drv[isdn_slot_driver(sl)]->rpqueue[isdn_slot_channel(sl)]); - restore_flags(flags); + fsm_event(&slot->fi, EV_SLOT_UNBIND, NULL); } /* * Return: length of data on success, -ERRcode on failure. */ int -isdn_slot_write(int sl, struct sk_buff *skb) +isdn_slot_write(struct isdn_slot *slot, struct sk_buff *skb) { - int ret; - struct sk_buff *nskb = NULL; - int v110_ret = skb->len; - int di = isdn_slot_driver(sl); - int ch = isdn_slot_channel(sl); - - BUG_ON(sl < 0); - - if (slot[sl].iv110.v110) { - atomic_inc(&slot[sl].iv110.v110use); - nskb = isdn_v110_encode(slot[sl].iv110.v110, skb); - atomic_dec(&slot[sl].iv110.v110use); - if (!nskb) - return 0; - v110_ret = *((int *)nskb->data); - skb_pull(nskb, sizeof(int)); - if (!nskb->len) { - dev_kfree_skb(nskb); - return v110_ret; - } - /* V.110 must always be acknowledged */ - ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, nskb); - } else { - int hl = isdn_slot_hdrlen(sl); - - if( skb_headroom(skb) < hl ){ - /* - * This should only occur when new HL driver with - * increased hl_hdrlen was loaded after netdevice - * was created and connected to the new driver. - * - * The V.110 branch (re-allocates on its own) does - * not need this - */ - struct sk_buff * skb_tmp; - - skb_tmp = skb_realloc_headroom(skb, hl); - printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed"); - if (!skb_tmp) return -ENOMEM; /* 0 better? */ - ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb_tmp); - if( ret > 0 ){ - dev_kfree_skb(skb); - } else { - dev_kfree_skb(skb_tmp); - } - } else { - ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb); - } - } - if (ret > 0) { - slot[sl].obytes += ret; - if (slot[sl].iv110.v110) { - atomic_inc(&slot[sl].iv110.v110use); - slot[sl].iv110.v110->skbuser++; - atomic_dec(&slot[sl].iv110.v110use); - /* For V.110 return unencoded data length */ - ret = v110_ret; - /* if the complete frame was send we free the skb; - if not upper function will requeue the skb */ - if (ret == skb->len) - dev_kfree_skb(skb); - } - } else - if (slot[sl].iv110.v110) - dev_kfree_skb(nskb); - return ret; + return fsm_event(&slot->fi, EV_DATA_REQ, skb); } -int -isdn_add_channels(driver *d, int drvidx, int n, int adding) +static int +isdn_add_channels(struct isdn_driver *d, int drvidx, int n, int adding) { int j, k, m; ulong flags; init_waitqueue_head(&d->st_waitq); - if (d->flags & DRV_FLAG_RUNNING) - return -1; + if (n < 1) return 0; m = (adding) ? d->channels + n : n; @@ -1684,70 +1946,20 @@ isdn_add_channels(driver *d, int drvidx, int n, int adding) ISDN_MAX_CHANNELS); return -1; } - - if ((adding) && (d->rcverr)) - kfree(d->rcverr); - if (!(d->rcverr = kmalloc(sizeof(int) * m, GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n"); - return -1; - } - memset((char *) d->rcverr, 0, sizeof(int) * m); - - if ((adding) && (d->rcvcount)) - kfree(d->rcvcount); - if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n"); - if (!adding) kfree(d->rcverr); - return -1; - } - memset((char *) d->rcvcount, 0, sizeof(int) * m); - - if ((adding) && (d->rpqueue)) { - for (j = 0; j < d->channels; j++) - skb_queue_purge(&d->rpqueue[j]); - kfree(d->rpqueue); - } - if (!(d->rpqueue = kmalloc(sizeof(struct sk_buff_head) * m, GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n"); - if (!adding) { - kfree(d->rcvcount); - kfree(d->rcverr); - } - return -1; - } - for (j = 0; j < m; j++) { - skb_queue_head_init(&d->rpqueue[j]); - } - - if ((adding) && (d->rcv_waitq)) - kfree(d->rcv_waitq); - d->rcv_waitq = kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_KERNEL); - if (!d->rcv_waitq) { - printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); - if (!adding) { - kfree(d->rpqueue); - kfree(d->rcvcount); - kfree(d->rcverr); - } - return -1; - } - d->snd_waitq = d->rcv_waitq + m; - for (j = 0; j < m; j++) { - init_waitqueue_head(&d->rcv_waitq[j]); - init_waitqueue_head(&d->snd_waitq[j]); - } - dev->channels += n; save_flags(flags); cli(); - for (j = d->channels; j < m; j++) - for (k = 0; k < ISDN_MAX_CHANNELS; k++) - if (slot[k].ch < 0) { - slot[k].ch = j; - slot[k].di = drvidx; + for (j = d->channels; j < m; j++) { + for (k = 0; k < ISDN_MAX_CHANNELS; k++) { + if (slots[k].ch < 0) { + slots[k].ch = j; + slots[k].di = drvidx; + slots[k].drv = d; isdn_register_devfs(k); break; } + } + } restore_flags(flags); d->channels = m; return 0; @@ -1757,20 +1969,6 @@ isdn_add_channels(driver *d, int drvidx, int n, int adding) * Low-level-driver registration */ -static void -set_global_features(void) -{ - int drvidx; - - dev->global_features = 0; - for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { - if (!dev->drv[drvidx]) - continue; - if (dev->drv[drvidx]->interface) - dev->global_features |= dev->drv[drvidx]->interface->features; - } -} - #if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE) static char *map_drvname(int di) @@ -1830,105 +2028,34 @@ EXPORT_SYMBOL(isdn_ppp_unregister_compressor); #endif int -register_isdn(isdn_if * i) -{ - driver *d; - int j; - ulong flags; - int drvidx; - - if (dev->drivers >= ISDN_MAX_DRIVERS) { - printk(KERN_WARNING "register_isdn: Max. %d drivers supported\n", - ISDN_MAX_DRIVERS); - return 0; - } - if (!i->writebuf_skb) { - printk(KERN_WARNING "register_isdn: No write routine given.\n"); - return 0; - } - if (!(d = kmalloc(sizeof(driver), GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n"); - return 0; - } - memset((char *) d, 0, sizeof(driver)); - - d->maxbufsize = i->maxbufsize; - d->pktcount = 0; - d->stavail = 0; - d->flags = DRV_FLAG_LOADED; - d->online = 0; - d->interface = i; - d->channels = 0; - for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) - if (!dev->drv[drvidx]) - break; - if (isdn_add_channels(d, drvidx, i->channels, 0)) { - kfree(d); - return 0; - } - i->channels = drvidx; - i->rcvcallb_skb = isdn_receive_skb_callback; - i->statcallb = isdn_status_callback; - if (!strlen(i->id)) - sprintf(i->id, "line%d", drvidx); - save_flags(flags); - cli(); - for (j = 0; j < drvidx; j++) - if (!strcmp(i->id, dev->drvid[j])) - sprintf(i->id, "line%d", drvidx); - dev->drv[drvidx] = d; - strcpy(dev->drvid[drvidx], i->id); - isdn_info_update(); - dev->drivers++; - set_global_features(); - restore_flags(flags); - return 1; -} - -int -isdn_slot_driver(int sl) -{ - BUG_ON(sl < 0); - - return slot[sl].di; -} - -int -isdn_slot_channel(int sl) +isdn_slot_maxbufsize(struct isdn_slot *slot) { - BUG_ON(sl < 0); - - return slot[sl].ch; + return slot->drv->maxbufsize; } int -isdn_slot_hdrlen(int sl) +isdn_slot_hdrlen(struct isdn_slot *slot) { - int di = isdn_slot_driver(sl); - - return dev->drv[di]->interface->hl_hdrlen; + return slot->drv->interface->hl_hdrlen; } char * -isdn_slot_map_eaz2msn(int sl, char *msn) +isdn_slot_map_eaz2msn(struct isdn_slot *slot, char *msn) { - int di = isdn_slot_driver(sl); - - return isdn_map_eaz2msn(msn, di); + return isdn_map_eaz2msn(msn, slot->di); } int -isdn_slot_command(int sl, int cmd, isdn_ctrl *ctrl) +isdn_slot_command(struct isdn_slot *slot, int cmd, isdn_ctrl *ctrl) { - ctrl->command = cmd; - ctrl->driver = isdn_slot_driver(sl); + ctrl->driver = slot->di; switch (cmd) { case ISDN_CMD_SETL2: case ISDN_CMD_SETL3: case ISDN_CMD_PROT_IO: - ctrl->arg &= ~0xff; ctrl->arg |= isdn_slot_channel(sl); + ctrl->arg &= ~0xff; ctrl->arg |= slot->ch; break; case ISDN_CMD_DIAL: if (dev->global_flags & ISDN_GLOBAL_STOPPED) @@ -1936,19 +2063,37 @@ isdn_slot_command(int sl, int cmd, isdn_ctrl *ctrl) /* fall through */ default: - ctrl->arg = isdn_slot_channel(sl); + ctrl->arg = slot->ch; break; } - - return isdn_command(ctrl); + switch (cmd) { + case ISDN_CMD_CLREAZ: + return fsm_event(&slot->fi, EV_CMD_CLREAZ, ctrl); + case ISDN_CMD_SETEAZ: + return fsm_event(&slot->fi, EV_CMD_SETEAZ, ctrl); + case ISDN_CMD_SETL2: + return fsm_event(&slot->fi, EV_CMD_SETL2, ctrl); + case ISDN_CMD_SETL3: + return fsm_event(&slot->fi, EV_CMD_SETL3, ctrl); + case ISDN_CMD_DIAL: + return fsm_event(&slot->fi, EV_CMD_DIAL, ctrl); + case ISDN_CMD_ACCEPTD: + return fsm_event(&slot->fi, EV_CMD_ACCEPTD, ctrl); + case ISDN_CMD_ACCEPTB: + return fsm_event(&slot->fi, EV_CMD_ACCEPTB, ctrl); + case ISDN_CMD_HANGUP: + return fsm_event(&slot->fi, EV_CMD_HANGUP, ctrl); + } + HERE; + return -1; } int -isdn_slot_dial(int sl, struct dial_info *dial) +isdn_slot_dial(struct isdn_slot *slot, struct dial_info *dial) { isdn_ctrl cmd; int retval; - char *msn = isdn_slot_map_eaz2msn(sl, dial->msn); + char *msn = isdn_slot_map_eaz2msn(slot, dial->msn); /* check for DOV */ if (dial->si1 == 7 && tolower(dial->phone[0]) == 'v') { /* DOV call */ @@ -1956,24 +2101,25 @@ isdn_slot_dial(int sl, struct dial_info *dial) dial->phone++; /* skip v/V */ } - strcpy(isdn_slot_num(sl), dial->phone); - isdn_slot_set_usage(sl, isdn_slot_usage(sl) | ISDN_USAGE_OUTGOING); + strcpy(slot->num, dial->phone); + slot->usage |= ISDN_USAGE_OUTGOING; + isdn_info_update(); - retval = isdn_slot_command(sl, ISDN_CMD_CLREAZ, &cmd); + retval = isdn_slot_command(slot, ISDN_CMD_CLREAZ, &cmd); if (retval) return retval; strcpy(cmd.parm.num, msn); - retval = isdn_slot_command(sl, ISDN_CMD_SETEAZ, &cmd); + retval = isdn_slot_command(slot, ISDN_CMD_SETEAZ, &cmd); cmd.arg = dial->l2_proto << 8; cmd.parm.fax = dial->fax; - retval = isdn_slot_command(sl, ISDN_CMD_SETL2, &cmd); + retval = isdn_slot_command(slot, ISDN_CMD_SETL2, &cmd); if (retval) return retval; cmd.arg = dial->l3_proto << 8; - retval = isdn_slot_command(sl, ISDN_CMD_SETL3, &cmd); + retval = isdn_slot_command(slot, ISDN_CMD_SETL3, &cmd); if (retval) return retval; @@ -1982,78 +2128,12 @@ isdn_slot_dial(int sl, struct dial_info *dial) strcpy(cmd.parm.setup.eazmsn, msn); strcpy(cmd.parm.setup.phone, dial->phone); - printk(KERN_INFO "ISDN: slot %d: Dialing %s -> %s (SI %d/%d) (B %d/%d)\n", - sl, cmd.parm.setup.eazmsn, cmd.parm.setup.phone, + printk(KERN_INFO "ISDN: Dialing %s -> %s (SI %d/%d) (B %d/%d)\n", + cmd.parm.setup.eazmsn, cmd.parm.setup.phone, cmd.parm.setup.si1, cmd.parm.setup.si2, dial->l2_proto, dial->l3_proto); - return isdn_slot_command(sl, ISDN_CMD_DIAL, &cmd); -} - -void -isdn_slot_all_eaz(int sl) -{ - isdn_ctrl cmd; - - cmd.parm.num[0] = '\0'; - isdn_slot_command(sl, ISDN_CMD_SETEAZ, &cmd); -} - -int -isdn_slot_usage(int sl) -{ - BUG_ON(sl < 0); - - return slot[sl].usage; -} - -void -isdn_slot_set_usage(int sl, int usage) -{ - BUG_ON(sl < 0); - - slot[sl].usage = usage; - isdn_info_update(); -} - -int -isdn_slot_m_idx(int sl) -{ - BUG_ON(sl < 0); - - return slot[sl].m_idx; -} - -void -isdn_slot_set_m_idx(int sl, int midx) -{ - BUG_ON(sl < 0); - - slot[sl].m_idx = midx; -} - -char * -isdn_slot_num(int sl) -{ - BUG_ON(sl < 0); - - return slot[sl].num; -} - -void -isdn_slot_set_idev(int sl, isdn_net_dev *idev) -{ - BUG_ON(sl < 0); - - slot[sl].idev = idev; -} - -isdn_net_dev * -isdn_slot_idev(int sl) -{ - BUG_ON(sl < 0); - - return slot[sl].idev; + return isdn_slot_command(slot, ISDN_CMD_DIAL, &cmd); } int @@ -2063,9 +2143,9 @@ isdn_hard_header_len(void) int max = 0; for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { - if (dev->drv[drvidx] && - max < dev->drv[drvidx]->interface->hl_hdrlen) { - max = dev->drv[drvidx]->interface->hl_hdrlen; + if (drivers[drvidx] && + max < drivers[drvidx]->interface->hl_hdrlen) { + max = drivers[drvidx]->interface->hl_hdrlen; } } return max; @@ -2077,21 +2157,6 @@ isdn_hard_header_len(void) ***************************************************************************** */ -static char * -isdn_getrev(const char *revision) -{ - char *rev; - char *p; - - if ((p = strchr(revision, ':'))) { - rev = p + 2; - p = strchr(rev, '$'); - *--p = 0; - } else - rev = "???"; - return rev; -} - #ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_handle; @@ -2179,25 +2244,32 @@ static int __init isdn_init(void) { int i; int retval; - char tmprev[50]; + + retval = fsm_new(&slot_fsm); + if (retval) + goto err; + + retval = fsm_new(&drv_fsm); + if (retval) + goto err_slot_fsm; dev = vmalloc(sizeof(*dev)); if (!dev) { retval = -ENOMEM; - goto err; + goto err_drv_fsm; } memset(dev, 0, sizeof(*dev)); - init_timer(&dev->timer); - dev->timer.function = isdn_timer_funct; init_MUTEX(&dev->sem); init_waitqueue_head(&dev->info_waitq); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - slot[i].di = -1; - slot[i].ch = -1; - slot[i].m_idx = -1; - strcpy(isdn_slot_num(i), "???"); - init_waitqueue_head(&dev->mdm.info[i].open_wait); - init_waitqueue_head(&dev->mdm.info[i].close_wait); + slots[i].di = -1; + slots[i].ch = -1; + strcpy(slots[i].num, "???"); + slots[i].fi.fsm = &slot_fsm; + slots[i].fi.state = ST_SLOT_NULL; + slots[i].fi.debug = 1; + slots[i].fi.userdata = slots + i; + slots[i].fi.printdebug = slot_debug; } retval = register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops); if (retval) { @@ -2218,26 +2290,9 @@ static int __init isdn_init(void) } #endif /* CONFIG_ISDN_PPP */ - strcpy(tmprev, isdn_revision); - printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_tty_revision); - printk("%s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_net_revision); - printk("%s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_ppp_revision); - printk("%s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_audio_revision); - printk("%s/", isdn_getrev(tmprev)); - strcpy(tmprev, isdn_v110_revision); - printk("%s", isdn_getrev(tmprev)); - -#ifdef MODULE - printk(" loaded\n"); -#else - printk("\n"); -#endif + isdn_net_lib_init(); + printk(KERN_NOTICE "ISDN subsystem initialized\n"); isdn_info_update(); - isdn_net_init(); return 0; err_tty_modem: @@ -2247,6 +2302,10 @@ static int __init isdn_init(void) unregister_chrdev(ISDN_MAJOR, "isdn"); err_vfree: vfree(dev); + err_drv_fsm: + fsm_free(&drv_fsm); + err_slot_fsm: + fsm_free(&slot_fsm); err: return retval; } @@ -2256,25 +2315,144 @@ static int __init isdn_init(void) */ static void __exit isdn_exit(void) { - unsigned long flags; - #ifdef CONFIG_ISDN_PPP isdn_ppp_cleanup(); #endif - save_flags(flags); - cli(); - isdn_net_exit(); + isdn_net_lib_exit(); isdn_tty_exit(); - if (unregister_chrdev(ISDN_MAJOR, "isdn")) - BUG(); - + unregister_chrdev(ISDN_MAJOR, "isdn"); isdn_cleanup_devfs(); - del_timer(&dev->timer); - restore_flags(flags); - /* call vfree with interrupts enabled, else it will hang */ vfree(dev); + fsm_free(&drv_fsm); + fsm_free(&slot_fsm); } module_init(isdn_init); module_exit(isdn_exit); + +static void +isdn_v110_add_features(struct isdn_driver *drv) +{ + unsigned long features = drv->features >> ISDN_FEATURE_L2_SHIFT; + + if (features & ISDN_FEATURE_L2_TRANS) + drv->features |= (ISDN_FEATURE_L2_V11096| + ISDN_FEATURE_L2_V11019| + ISDN_FEATURE_L2_V11038) << + ISDN_FEATURE_L2_SHIFT; +} + +static void +__isdn_v110_open(struct isdn_slot *slot) +{ + if (!slot->iv110.v110emu) + return; + + isdn_v110_open(slot, &slot->iv110); +} + +static void +__isdn_v110_close(struct isdn_slot *slot) +{ + if (!slot->iv110.v110emu) + return; + + isdn_v110_close(slot, &slot->iv110); +} + +static void +__isdn_v110_bsent(struct isdn_slot *slot, int pr, isdn_ctrl *c) +{ + if (!slot->iv110.v110emu) { + do_event_cb(slot, pr, c); + return; + } + isdn_v110_bsent(slot, &slot->iv110); +} + +/* + * Intercept command from Linklevel to Lowlevel. + * If layer 2 protocol is V.110 and this is not supported by current + * lowlevel-driver, use driver's transparent mode and handle V.110 in + * linklevel instead. + */ +static void +isdn_v110_setl2(struct isdn_slot *slot, isdn_ctrl *cmd) +{ + struct isdn_driver *drv = slot->drv; + + unsigned long l2prot = (cmd->arg >> 8) & 255; + unsigned long l2_feature = 1 << l2prot; + unsigned long features = drv->interface->features >> + ISDN_FEATURE_L2_SHIFT; + + switch (l2prot) { + case ISDN_PROTO_L2_V11096: + case ISDN_PROTO_L2_V11019: + case ISDN_PROTO_L2_V11038: + /* If V.110 requested, but not supported by + * HL-driver, set emulator-flag and change + * Layer-2 to transparent + */ + if (!(features & l2_feature)) { + slot->iv110.v110emu = l2prot; + cmd->arg = (cmd->arg & 255) | + (ISDN_PROTO_L2_TRANS << 8); + } else + slot->iv110.v110emu = 0; + } +} + +static int +isdn_v110_data_ind(struct isdn_slot *slot, struct sk_buff *skb) +{ + if (!slot->iv110.v110emu) + goto recv; + + skb = isdn_v110_decode(slot->iv110.v110, skb); + if (!skb) + return 0; + +recv: + if (slot->event_cb) + slot->event_cb(slot, EV_DATA_IND, skb); + return 0; +} + +static int +isdn_v110_data_req(struct isdn_slot *slot, struct sk_buff *skb) +{ + int retval, v110_ret; + struct sk_buff *nskb = NULL; + + if (!slot->iv110.v110emu) + return isdn_writebuf_skb(slot, skb); + + atomic_inc(&slot->iv110.v110use); + nskb = isdn_v110_encode(slot->iv110.v110, skb); + atomic_dec(&slot->iv110.v110use); + if (!nskb) + return -ENOMEM; + + v110_ret = *(int *)nskb->data; + skb_pull(nskb, sizeof(int)); + if (!nskb->len) { + dev_kfree_skb(nskb); + return v110_ret; + } + + retval = isdn_writebuf_skb(slot, nskb); + if (retval <= 0) { + dev_kfree_skb(nskb); + return retval; + } + dev_kfree_skb(skb); + + atomic_inc(&slot->iv110.v110use); + slot->iv110.v110->skbuser++; + atomic_dec(&slot->iv110.v110use); + + /* For V.110 return unencoded data length */ + return v110_ret; +} diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index 64e1c1e9c819..ff80a0063722 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h @@ -1,7 +1,4 @@ -/* $Id: isdn_common.h,v 1.21.6.1 2001/09/23 22:24:31 kai Exp $ - * - * header for Linux ISDN subsystem - * common used functions and debugging-switches (linklevel). +/* Linux ISDN subsystem, common used functions and debugging-switches * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg @@ -13,6 +10,7 @@ */ #include <linux/isdn.h> +#include "isdn_v110.h" #undef ISDN_DEBUG_MODEM_OPEN #undef ISDN_DEBUG_MODEM_IOCTL @@ -22,7 +20,7 @@ #undef ISDN_DEBUG_MODEM_DUMP #undef ISDN_DEBUG_MODEM_VOICE #undef ISDN_DEBUG_AT -#define ISDN_DEBUG_NET_DUMP +#undef ISDN_DEBUG_NET_DUMP #define ISDN_DEBUG_NET_DIAL #define ISDN_DEBUG_NET_ICALL #define ISDN_DEBUG_STATCALLB @@ -59,20 +57,30 @@ extern void isdn_MOD_INC_USE_COUNT(void); extern void isdn_MOD_DEC_USE_COUNT(void); extern void isdn_lock_drivers(void); extern void isdn_unlock_drivers(void); -extern void isdn_free_channel(int di, int ch, int usage); -extern int isdn_dc2minor(int di, int ch); extern void isdn_info_update(void); extern char *isdn_map_eaz2msn(char *msn, int di); -extern void isdn_timer_ctrl(int tf, int onoff); extern int isdn_getnum(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) extern void isdn_dumppkt(char *, u_char *, int, int); #else static inline void isdn_dumppkt(char *s, u_char *d, int l, int m) { } #endif +struct isdn_slot { + int di; /* driver index */ + struct isdn_driver *drv; /* driver */ + int ch; /* channel index (per driver) */ + int usage; /* how is it used */ + char num[ISDN_MSNLEN]; /* the current phone number */ + unsigned long ibytes; /* Statistics incoming bytes */ + unsigned long obytes; /* Statistics outgoing bytes */ + struct isdn_v110 iv110; /* For V.110 */ + void *priv; /* pointer to isdn_net_dev */ + int (*event_cb)(struct isdn_slot *, int pr, void *arg); + struct fsm_inst fi; +}; + struct dial_info { int l2_proto; int l3_proto; @@ -83,22 +91,59 @@ struct dial_info { unsigned char *phone; }; -extern int isdn_get_free_slot(int, int, int, int, int, char *); -extern void isdn_slot_free(int slot); -extern void isdn_slot_all_eaz(int slot); -extern int isdn_slot_command(int slot, int cmd, isdn_ctrl *); -extern int isdn_slot_dial(int slot, struct dial_info *dial); -extern char *isdn_slot_map_eaz2msn(int slot, char *msn); -extern int isdn_slot_write(int slot, struct sk_buff *); -extern int isdn_slot_readbchan(int slot, u_char *, u_char *, int); -extern int isdn_slot_hdrlen(int slot); -extern int isdn_slot_driver(int slot); -extern int isdn_slot_channel(int slot); -extern int isdn_slot_usage(int slot); -extern void isdn_slot_set_usage(int slot, int usage); -extern char *isdn_slot_num(int slot); -extern int isdn_slot_m_idx(int slot); -extern void isdn_slot_set_m_idx(int slot, int midx); -extern void isdn_slot_set_idev(int sl, isdn_net_dev *); -extern isdn_net_dev *isdn_slot_idev(int sl); -extern int isdn_hard_header_len(void); +struct isdn_slot *isdn_get_free_slot(int, int, int, int, int, char *); +void isdn_slot_free(struct isdn_slot *); +int isdn_slot_command(struct isdn_slot *, int cmd, isdn_ctrl *); +int isdn_slot_dial(struct isdn_slot *, struct dial_info *dial); +char *isdn_slot_map_eaz2msn(struct isdn_slot *, char *msn); +int isdn_slot_write(struct isdn_slot *, struct sk_buff *); +int isdn_slot_hdrlen(struct isdn_slot *); +int isdn_slot_maxbufsize(struct isdn_slot *); +int isdn_hard_header_len(void); + +int isdn_drv_lookup(char *drvid); +char *isdn_drv_drvid(int di); + +enum { + ST_SLOT_NULL, + ST_SLOT_BOUND, + ST_SLOT_IN, + ST_SLOT_WAIT_DCONN, + ST_SLOT_DCONN, + ST_SLOT_WAIT_BCONN, + ST_SLOT_ACTIVE, + ST_SLOT_WAIT_BHUP, + ST_SLOT_WAIT_DHUP, +}; + +enum { + EV_DRV_REGISTER, + EV_STAT_RUN, + EV_STAT_STOP, + EV_STAT_UNLOAD, + EV_STAT_STAVAIL, + EV_STAT_ADDCH, + EV_STAT_ICALL, + EV_STAT_DCONN, + EV_STAT_BCONN, + EV_STAT_BHUP, + EV_STAT_DHUP, + EV_STAT_BSENT, + EV_STAT_CINF, + EV_STAT_CAUSE, + EV_STAT_DISPLAY, + EV_STAT_FAXIND, + EV_STAT_AUDIO, + EV_CMD_CLREAZ, + EV_CMD_SETEAZ, + EV_CMD_SETL2, + EV_CMD_SETL3, + EV_CMD_DIAL, + EV_CMD_ACCEPTD, + EV_CMD_ACCEPTB, + EV_CMD_HANGUP, + EV_DATA_REQ, + EV_DATA_IND, + EV_SLOT_BIND, + EV_SLOT_UNBIND, +}; diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c index 935358fe2bb2..0bc42ad91364 100644 --- a/drivers/isdn/i4l/isdn_concap.c +++ b/drivers/isdn/i4l/isdn_concap.c @@ -1,16 +1,12 @@ -/* $Id: isdn_concap.c,v 1.8.6.1 2001/09/23 22:24:31 kai Exp $ - * - * Linux ISDN subsystem, protocol encapsulation +/* Linux ISDN subsystem, protocol encapsulation * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ /* Stuff to support the concap_proto by isdn4linux. isdn4linux - specific * stuff goes here. Stuff that depends only on the concap protocol goes to * another -- protocol specific -- source file. - * */ @@ -115,8 +111,8 @@ static int isdn_x25_open(isdn_net_local *lp) { struct net_device * dev = & lp -> netdev -> dev; - struct concap_proto * cprot = lp -> netdev -> cprot; - struct concap_proto * dops = lp -> dops; + struct concap_proto * cprot = lp -> netdev -> ind_priv; + struct concap_proto * dops = lp -> inl_priv; unsigned long flags; save_flags(flags); @@ -130,7 +126,7 @@ isdn_x25_open(isdn_net_local *lp) static void isdn_x25_close(isdn_net_local *lp) { - struct concap_proto * cprot = lp -> netdev -> cprot; + struct concap_proto * cprot = lp -> netdev -> ind_priv; if( cprot && cprot -> pops ) cprot -> pops -> close( cprot ); } @@ -138,7 +134,7 @@ isdn_x25_close(isdn_net_local *lp) static void isdn_x25_connected(isdn_net_local *lp) { - struct concap_proto *cprot = lp -> netdev -> cprot; + struct concap_proto *cprot = lp -> netdev -> ind_priv; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; /* try if there are generic concap receiver routines */ @@ -152,7 +148,7 @@ isdn_x25_connected(isdn_net_local *lp) static void isdn_x25_disconnected(isdn_net_local *lp) { - struct concap_proto *cprot = lp -> netdev -> cprot; + struct concap_proto *cprot = lp -> netdev -> ind_priv; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; /* try if there are generic encap protocol @@ -177,7 +173,7 @@ isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev) when a dl_establish request is received from the upper layer. */ isdn_net_local *lp = (isdn_net_local *) dev->priv; - struct concap_proto * cprot = lp -> netdev -> cprot; + struct concap_proto * cprot = lp -> netdev -> ind_priv; int ret = cprot -> pops -> encap_and_xmit ( cprot , skb); if (ret) @@ -190,7 +186,7 @@ static void isdn_x25_receive(isdn_net_dev *p, isdn_net_local *olp, struct sk_buff *skb) { isdn_net_local *lp = &p->local; - struct concap_proto *cprot = lp -> netdev -> cprot; + struct concap_proto *cprot = lp -> netdev -> ind_priv; /* try if there are generic sync_device receiver routines */ if(cprot) @@ -211,7 +207,7 @@ isdn_x25_init(struct net_device *dev) /* ... , prepare for configuration of new one ... */ switch ( lp->p_encap ){ case ISDN_NET_ENCAP_X25IFACE: - lp -> dops = &isdn_concap_reliable_dl_dops; + lp -> inl_priv = &isdn_concap_reliable_dl_dops; } /* ... and allocate new one ... */ p -> cprot = isdn_concap_new( cfg -> p_encap ); @@ -237,7 +233,7 @@ isdn_x25_cleanup(isdn_net_dev *p) if( cprot && cprot -> pops ) cprot -> pops -> proto_del ( cprot ); p -> cprot = NULL; - lp -> dops = NULL; + lp -> inl_priv = NULL; restore_flags(flags); } diff --git a/drivers/isdn/i4l/isdn_concap.h b/drivers/isdn/i4l/isdn_concap.h index 8150d6f595e0..49ee3cb27101 100644 --- a/drivers/isdn/i4l/isdn_concap.h +++ b/drivers/isdn/i4l/isdn_concap.h @@ -1,10 +1,7 @@ -/* $Id: isdn_concap.h,v 1.3.6.1 2001/09/23 22:24:31 kai Exp $ - * - * Linux ISDN subsystem, protocol encapsulation +/* Linux ISDN subsystem, protocol encapsulation * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ extern struct concap_device_ops isdn_concap_reliable_dl_dops; diff --git a/drivers/isdn/i4l/isdn_fsm.c b/drivers/isdn/i4l/isdn_fsm.c index 52de59763fe8..673b3ad9d632 100644 --- a/drivers/isdn/i4l/isdn_fsm.c +++ b/drivers/isdn/i4l/isdn_fsm.c @@ -1,17 +1,14 @@ -/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $ - * - * Finite state machine +/* Linux ISDN subsystem, finite state machine * * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Kai Germaschewski <kai.germaschewski@gmx.de> + * Copyright by Karsten Keil <keil@isdn4linux.de> + * 2001-2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * * Thanks to Jan den Ouden * Fritz Elfert - * */ #include <linux/kernel.h> @@ -19,7 +16,7 @@ #include <linux/slab.h> #include <linux/errno.h> #include <linux/string.h> -#include "isdn_fsm.h" +#include <linux/isdn/fsm.h> int fsm_new(struct fsm *fsm) diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index f41603c1287d..370e3e5f8011 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1,6 +1,4 @@ -/* $Id: isdn_net.c,v 1.140.6.11 2001/11/06 20:58:28 kai Exp $ - * - * Linux ISDN subsystem, network interfaces and related functions (linklevel). +/* Linux ISDN subsystem, network interfaces and related functions (linklevel). * * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) * 1995,96 by Thinking Objects Software GmbH Wuerzburg @@ -9,31 +7,14 @@ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * - * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02 - * guy@traverse.com.au - * Outgoing calls - looks for a 'V' in first char of dialed number - * Incoming calls - checks first character of eaz as follows: - * Numeric - accept DATA only - original functionality - * 'V' - accept VOICE (DOV) only - * 'B' - accept BOTH DATA and DOV types - * */ -#include <linux/config.h> #include <linux/isdn.h> -#include <net/arp.h> -#include <net/dst.h> -#include <net/pkt_sched.h> #include <linux/inetdevice.h> +#include <net/arp.h> #include "isdn_common.h" +#include "isdn_net_lib.h" #include "isdn_net.h" -#include "isdn_ppp.h" -#include <linux/concap.h> -#include "isdn_concap.h" -#include "isdn_ciscohdlck.h" - -char *isdn_net_revision = "$Revision: 1.140.6.11 $"; // ISDN_NET_ENCAP_IPTYP // ethernet type field @@ -52,13 +33,14 @@ static void isdn_iptyp_receive(isdn_net_local *lp, isdn_net_dev *idev, struct sk_buff *skb) { - idev->huptimer = 0; - get_u16(skb->data, &skb->protocol); + u16 protocol; + + get_u16(skb->data, &protocol); skb_pull(skb, 2); - netif_rx(skb); + isdn_netif_rx(idev, skb, protocol); } -static struct isdn_netif_ops iptyp_ops = { +struct isdn_netif_ops isdn_iptyp_ops = { .hard_start_xmit = isdn_net_start_xmit, .hard_header = isdn_iptyp_header, .flags = IFF_NOARP | IFF_POINTOPOINT, @@ -84,13 +66,11 @@ static void isdn_uihdlc_receive(isdn_net_local *lp, isdn_net_dev *idev, struct sk_buff *skb) { - idev->huptimer = 0; skb_pull(skb, 2); - skb->protocol = htons(ETH_P_IP); - netif_rx(skb); + isdn_netif_rx(idev, skb, htons(ETH_P_IP)); } -static struct isdn_netif_ops uihdlc_ops = { +struct isdn_netif_ops isdn_uihdlc_ops = { .hard_start_xmit = isdn_net_start_xmit, .hard_header = isdn_uihdlc_header, .flags = IFF_NOARP | IFF_POINTOPOINT, @@ -112,7 +92,7 @@ isdn_rawip_receive(isdn_net_local *lp, isdn_net_dev *idev, netif_rx(skb); } -static struct isdn_netif_ops rawip_ops = { +struct isdn_netif_ops isdn_rawip_ops = { .hard_start_xmit = isdn_net_start_xmit, .flags = IFF_NOARP | IFF_POINTOPOINT, .type = ARPHRD_PPP, @@ -127,9 +107,7 @@ static void isdn_ether_receive(isdn_net_local *lp, isdn_net_dev *idev, struct sk_buff *skb) { - idev->huptimer = 0; - skb->protocol = eth_type_trans(skb, skb->dev); - netif_rx(skb); + isdn_netif_rx(idev, skb, eth_type_trans(skb, &lp->dev)); } static int @@ -164,38 +142,9 @@ isdn_ether_init(isdn_net_local *lp) return 0; } -static struct isdn_netif_ops ether_ops = { +struct isdn_netif_ops isdn_ether_ops = { .hard_start_xmit = isdn_net_start_xmit, - .hard_header = eth_header, .receive = isdn_ether_receive, .init = isdn_ether_init, .open = isdn_ether_open, }; - -// ====================================================================== - -void -isdn_net_init(void) -{ - isdn_net_lib_init(); - - register_isdn_netif(ISDN_NET_ENCAP_ETHER, ðer_ops); - register_isdn_netif(ISDN_NET_ENCAP_RAWIP, &rawip_ops); - register_isdn_netif(ISDN_NET_ENCAP_IPTYP, &iptyp_ops); - register_isdn_netif(ISDN_NET_ENCAP_UIHDLC, &uihdlc_ops); - register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLC, &ciscohdlck_ops); - register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLCK, &ciscohdlck_ops); -#ifdef CONFIG_ISDN_X25 - register_isdn_netif(ISDN_NET_ENCAP_X25IFACE, &isdn_x25_ops); -#endif -#ifdef CONFIG_ISDN_PPP - register_isdn_netif(ISDN_NET_ENCAP_SYNCPPP, &isdn_ppp_ops); -#endif -} - -void -isdn_net_exit(void) -{ - isdn_net_lib_exit(); -} - diff --git a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h index 14f94befc91f..049f2aa3059c 100644 --- a/drivers/isdn/i4l/isdn_net.h +++ b/drivers/isdn/i4l/isdn_net.h @@ -1,83 +1,15 @@ -/* $Id: isdn_net.h,v 1.19.6.4 2001/09/28 08:05:29 kai Exp $ - * - * header for Linux ISDN subsystem, network related functions (linklevel). +/* Linux ISDN subsystem, network related functions * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) - * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg - * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/isdn.h> - -void isdn_net_init(void); -void isdn_net_exit(void); -void isdn_net_lib_init(void); -void isdn_net_lib_exit(void); -void isdn_net_hangup_all(void); -int isdn_net_ioctl(struct inode *, struct file *, uint, ulong); - -int register_isdn_netif(int encap, struct isdn_netif_ops *ops); -int isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev); -void isdn_net_online(isdn_net_dev *idev); -void isdn_net_offline(isdn_net_dev *idev); - -int isdn_net_stat_callback(int, isdn_ctrl *); -int isdn_net_find_icall(int, int, int, setup_parm *); -int isdn_net_rcv_skb(int, struct sk_buff *); - -int isdn_net_hangup(isdn_net_dev *); -int isdn_net_dial_req(isdn_net_dev *); -void isdn_net_writebuf_skb(isdn_net_dev *, struct sk_buff *skb); -void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb); -int isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev); -isdn_net_dev *isdn_net_get_xmit_dev(isdn_net_local *mlp); - -static inline int -put_u8(unsigned char *p, u8 x) -{ - *p = x; - return 1; -} - -static inline int -put_u16(unsigned char *p, u16 x) -{ - *((u16 *)p) = htons(x); - return 2; -} - -static inline int -put_u32(unsigned char *p, u32 x) -{ - *((u32 *)p) = htonl(x); - return 4; -} - -static inline int -get_u8(unsigned char *p, u8 *x) -{ - *x = *p; - return 1; -} - -static inline int -get_u16(unsigned char *p, u16 *x) -{ - *x = ntohs(*((u16 *)p)); - return 2; -} - -static inline int -get_u32(unsigned char *p, u32 *x) -{ - *x = ntohl(*((u32 *)p)); - return 4; -} - - +extern struct isdn_netif_ops isdn_iptyp_ops; +extern struct isdn_netif_ops isdn_uihdlc_ops; +extern struct isdn_netif_ops isdn_rawip_ops; +extern struct isdn_netif_ops isdn_ether_ops; diff --git a/drivers/isdn/i4l/isdn_net_lib.c b/drivers/isdn/i4l/isdn_net_lib.c index ba0144200c1f..f5dc1e8ddd95 100644 --- a/drivers/isdn/i4l/isdn_net_lib.c +++ b/drivers/isdn/i4l/isdn_net_lib.c @@ -1,5 +1,4 @@ -/* - * Linux ISDN subsystem, Network interface configuration +/* Linux ISDN subsystem, network interface support code * * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) * 1995,96 by Thinking Objects Software GmbH Wuerzburg @@ -10,6 +9,17 @@ * of the GNU General Public License, incorporated herein by reference. */ +/* + * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02 + * guy@traverse.com.au + * Outgoing calls - looks for a 'V' in first char of dialed number + * Incoming calls - checks first character of eaz as follows: + * Numeric - accept DATA only - original functionality + * 'V' - accept VOICE (DOV) only + * 'B' - accept BOTH DATA and DOV types + * + */ + /* Locking works as follows: * * The configuration of isdn_net_devs works via ioctl on @@ -44,9 +54,10 @@ #include <linux/capability.h> #include <linux/rtnetlink.h> #include "isdn_common.h" +#include "isdn_net_lib.h" #include "isdn_net.h" #include "isdn_ppp.h" -#include "isdn_fsm.h" +#include "isdn_ciscohdlck.h" #define ISDN_NET_TX_TIMEOUT (20*HZ) @@ -117,21 +128,21 @@ static char *isdn_net_st_str[] = { }; enum { - EV_TIMER_INCOMING, - EV_TIMER_DIAL, - EV_TIMER_DIAL_WAIT, - EV_TIMER_CB_OUT, - EV_TIMER_CB_IN, - EV_TIMER_HUP, - EV_STAT_DCONN, - EV_STAT_BCONN, - EV_STAT_DHUP, - EV_STAT_BHUP, - EV_STAT_CINF, - EV_STAT_BSENT, - EV_DO_DIAL, - EV_DO_CALLBACK, - EV_DO_ACCEPT, + EV_NET_TIMER_INCOMING, + EV_NET_TIMER_DIAL, + EV_NET_TIMER_DIAL_WAIT, + EV_NET_TIMER_CB_OUT, + EV_NET_TIMER_CB_IN, + EV_NET_TIMER_HUP, + EV_NET_STAT_DCONN, + EV_NET_STAT_BCONN, + EV_NET_STAT_DHUP, + EV_NET_STAT_BHUP, + EV_NET_STAT_CINF, + EV_NET_STAT_BSENT, + EV_NET_DO_DIAL, + EV_NET_DO_CALLBACK, + EV_NET_DO_ACCEPT, }; static char *isdn_net_ev_str[] = { @@ -141,15 +152,15 @@ static char *isdn_net_ev_str[] = { "EV_NET_TIMER_CB_OUT", "EV_NET_TIMER_CB_IN", "EV_NET_TIMER_HUP", - "EV_STAT_DCONN", - "EV_STAT_BCONN", - "EV_STAT_DHUP", - "EV_STAT_BHUP", - "EV_STAT_CINF", - "EV_STAT_BSENT", - "EV_DO_DIAL", - "EV_DO_CALLBACK", - "EV_DO_ACCEPT", + "EV_NET_STAT_DCONN", + "EV_NET_STAT_BCONN", + "EV_NET_STAT_DHUP", + "EV_NET_STAT_BHUP", + "EV_NET_STAT_CINF", + "EV_NET_STAT_BSENT", + "EV_NET_DO_DIAL", + "EV_NET_DO_CALLBACK", + "EV_NET_DO_ACCEPT", }; /* Definitions for hupflags: */ @@ -253,7 +264,7 @@ static int isdn_net_bind(isdn_net_dev *idev, isdn_net_ioctl_cfg *cfg) { isdn_net_local *mlp = idev->mlp; - int i, retval; + int retval; int drvidx = -1; int chidx = -1; char drvid[25]; @@ -276,35 +287,28 @@ isdn_net_bind(isdn_net_dev *idev, isdn_net_ioctl_cfg *cfg) /* The channel-number is appended to the driver-Id with a comma */ *c = 0; chidx = simple_strtol(c + 1, NULL, 10); - - for (i = 0; i < ISDN_MAX_DRIVERS; i++) { - /* Lookup driver-Id in array */ - if (!strcmp(dev->drvid[i], drvid)) { - drvidx = i; - break; - } - } + drvidx = isdn_drv_lookup(drvid); if (drvidx == -1 || chidx == -1) { /* Either driver-Id or channel-number invalid */ retval = -ENODEV; goto out; } } - if (cfg->exclusive == (idev->exclusive >= 0) && + if (cfg->exclusive == !!idev->exclusive && drvidx == idev->pre_device && chidx == idev->pre_channel) { /* no change */ retval = 0; goto out; } - if (idev->exclusive >= 0) { + if (idev->exclusive) { isdn_slot_free(idev->exclusive); - idev->exclusive = -1; + idev->exclusive = NULL; } if (cfg->exclusive) { /* If binding is exclusive, try to grab the channel */ idev->exclusive = isdn_get_free_slot(ISDN_USAGE_NET | ISDN_USAGE_EXCLUSIVE, mlp->l2_proto, mlp->l3_proto, drvidx, chidx, cfg->eaz); - if (idev->exclusive < 0) { + if (!idev->exclusive) { /* Grab failed, because desired channel is in use */ retval = -EBUSY; goto out; @@ -364,12 +368,11 @@ isdn_net_addif(char *name, isdn_net_local *mlp) tasklet_init(&idev->tlet, isdn_net_tasklet, (unsigned long) idev); skb_queue_head_init(&idev->super_tx_queue); - idev->isdn_slot = -1; + idev->isdn_slot = NULL; idev->pre_device = -1; idev->pre_channel = -1; - idev->exclusive = -1; + idev->exclusive = NULL; - idev->ipppd = NULL; idev->pppbind = -1; init_timer(&idev->dial_timer); @@ -405,7 +408,7 @@ isdn_net_addif(char *name, isdn_net_local *mlp) mlp->hupflags = ISDN_INHUP; mlp->onhtime = 10; mlp->dialmax = 1; - mlp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL; + mlp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL | ISDN_NET_SECURE; mlp->cbdelay = 5 * HZ; /* Wait 5 secs before call-back */ mlp->dialtimeout = 60 * HZ;/* Wait 1 min for connection */ mlp->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */ @@ -459,11 +462,12 @@ isdn_net_addslave(char *parm) rtnl_lock(); - if (netif_running(&mlp->dev)) - return -EBUSY; - + if (netif_running(&mlp->dev)) { + retval = -EBUSY; + goto out; + } retval = isdn_net_addif(p, mlp); - + out: rtnl_unlock(); return retval; } @@ -535,8 +539,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg *cfg) { isdn_net_dev *idev = isdn_net_findif(cfg->name); isdn_net_local *mlp; - ulong features; - int i, retval; + int retval; if (!idev) return -ENODEV; @@ -549,19 +552,6 @@ isdn_net_setcfg(isdn_net_ioctl_cfg *cfg) retval = -EBUSY; goto out; } - /* See if any registered driver supports the features we want */ - features = ((1 << cfg->l2_proto) << ISDN_FEATURE_L2_SHIFT) | - ((1 << cfg->l3_proto) << ISDN_FEATURE_L3_SHIFT); - for (i = 0; i < ISDN_MAX_DRIVERS; i++) - if (dev->drv[i] && - (dev->drv[i]->interface->features & features) == features) - break; - - if (i == ISDN_MAX_DRIVERS) { - printk(KERN_WARNING "isdn_net: No driver with selected features\n"); - retval = -ENODEV; - goto out; - } retval = isdn_net_set_encap(mlp, cfg->p_encap); if (retval) @@ -653,9 +643,9 @@ isdn_net_getcfg(isdn_net_ioctl_cfg *cfg) mlp = idev->mlp; strcpy(cfg->eaz, mlp->msn); - cfg->exclusive = idev->exclusive >= 0; + cfg->exclusive = !!idev->exclusive; if (idev->pre_device >= 0) { - sprintf(cfg->drvid, "%s,%d", dev->drvid[idev->pre_device], + sprintf(cfg->drvid, "%s,%d", isdn_drv_drvid(idev->pre_device), idev->pre_channel); } else { cfg->drvid[0] = '\0'; @@ -814,6 +804,29 @@ isdn_net_dial_out(char *name) return isdn_net_dial(idev); } +static int +__isdn_net_dial_slave(isdn_net_local *mlp) +{ + isdn_net_dev *idev; + + list_for_each_entry(idev, &mlp->slaves, slaves) { + if (isdn_net_dial(idev) == 0) + return 0; + } + return -EBUSY; +} + +static int +isdn_net_dial_slave(char *name) +{ + isdn_net_dev *idev = isdn_net_findif(name); + + if (!idev) + return -ENODEV; + + return __isdn_net_dial_slave(idev->mlp); +} + /* * Force a hangup of a network-interface. */ @@ -840,25 +853,18 @@ static int isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone *peer) { isdn_net_dev *idev = isdn_net_findif(phone->name); - int idx; + struct isdn_slot *slot; if (!idev) return -ENODEV; - /* FIXME - * Theoretical race: while this executes, the remote number might - * become invalid (hang up) or change (new connection), resulting - * in (partially) wrong number copied to user. This race - * currently ignored. - */ - idx = idev->isdn_slot; - if (idx < 0) - return -ENOTCONN; - /* for pre-bound channels, we need this extra check */ - if (strncmp(isdn_slot_num(idx), "???", 3) == 0 ) + + if (idev->fi.state != ST_ACTIVE) return -ENOTCONN; - strncpy(phone->phone, isdn_slot_num(idx), ISDN_MSNLEN); - phone->outgoing = USG_OUTGOING(isdn_slot_usage(idx)); + slot = idev->isdn_slot; + + strncpy(phone->phone, slot->num, ISDN_MSNLEN); + phone->outgoing = USG_OUTGOING(slot->usage); if (copy_to_user(peer, phone, sizeof(*peer))) return -EFAULT; @@ -972,22 +978,20 @@ isdn_net_ioctl(struct inode *ino, struct file *file, uint cmd, ulong arg) } retval = isdn_net_getpeer(&phone, (isdn_net_ioctl_phone *) arg); break; -#ifdef CONFIG_ISDN_PPP case IIOCNETALN: /* Add link */ if (copy_from_user(name, (char *) arg, sizeof(name))) { retval = -EFAULT; break; } - retval = isdn_ppp_dial_slave(name); + retval = isdn_net_dial_slave(name); break; case IIOCNETDLN: /* Delete link */ if (copy_from_user(name, (char *) arg, sizeof(name))) { retval = -EFAULT; break; } - retval = isdn_ppp_hangup_slave(name); + retval = isdn_net_force_hangup(name); break; -#endif default: retval = -ENOTTY; } @@ -1191,14 +1195,15 @@ isdn_net_unbind_channel(isdn_net_dev *idev) if (mlp->ops->unbind) mlp->ops->unbind(idev); - isdn_slot_set_idev(idev->isdn_slot, NULL); + idev->isdn_slot->priv = NULL; + idev->isdn_slot->event_cb = NULL; skb_queue_purge(&idev->super_tx_queue); if (idev->isdn_slot != idev->exclusive) isdn_slot_free(idev->isdn_slot); - idev->isdn_slot = -1; + idev->isdn_slot = NULL; if (idev->fi.state != ST_NULL) { lp_put(mlp); @@ -1206,24 +1211,29 @@ isdn_net_unbind_channel(isdn_net_dev *idev) } } +static int isdn_net_event_callback(struct isdn_slot *slot, int pr, void *arg); + /* * Assign an ISDN-channel to a net-interface */ static int -isdn_net_bind_channel(isdn_net_dev *idev, int slot) +isdn_net_bind_channel(isdn_net_dev *idev, struct isdn_slot *slot) { isdn_net_local *mlp = idev->mlp; int retval = 0; - idev->isdn_slot = slot; - isdn_slot_set_idev(idev->isdn_slot, idev); - if (mlp->ops->bind) retval = mlp->ops->bind(idev); if (retval < 0) - isdn_net_unbind_channel(idev); + goto out; + + idev->isdn_slot = slot; + slot->priv = idev; + slot->event_cb = isdn_net_event_callback; + slot->usage |= ISDN_USAGE_NET; + out: return retval; } @@ -1233,7 +1243,7 @@ isdn_net_dial(isdn_net_dev *idev) int retval; lp_get(idev->mlp); - retval = fsm_event(&idev->fi, EV_DO_DIAL, NULL); + retval = fsm_event(&idev->fi, EV_NET_DO_DIAL, NULL); if (retval == -ESRCH) /* event not handled in this state */ retval = -EBUSY; @@ -1348,29 +1358,13 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev) return 0; } - -static void -isdn_net_dial_slave(isdn_net_local *mlp) -{ - isdn_net_dev *idev; - - if (ISDN_NET_DIALMODE(*mlp) != ISDN_NET_DM_AUTO) - return; - - list_for_each_entry(idev, &mlp->slaves, slaves) { - if (fsm_event(&idev->fi, EV_DO_DIAL, NULL) != -ESRCH) { - break; - } - } -} - static int accept_icall(struct fsm_inst *fi, int pr, void *arg) { isdn_net_dev *idev = fi->userdata; isdn_net_local *mlp = idev->mlp; isdn_ctrl cmd; - int slot = (int) arg; + struct isdn_slot *slot = arg; isdn_net_bind_channel(idev, slot); @@ -1383,9 +1377,10 @@ accept_icall(struct fsm_inst *fi, int pr, void *arg) isdn_slot_command(idev->isdn_slot, ISDN_CMD_SETL2, &cmd); cmd.arg = mlp->l3_proto << 8; isdn_slot_command(idev->isdn_slot, ISDN_CMD_SETL3, &cmd); + isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTD, &cmd); idev->dial_timer.expires = jiffies + mlp->dialtimeout; - idev->dial_event = EV_TIMER_INCOMING; + idev->dial_event = EV_NET_TIMER_INCOMING; add_timer(&idev->dial_timer); fsm_change_state(&idev->fi, ST_IN_WAIT_DCONN); return 0; @@ -1400,7 +1395,7 @@ do_callback(struct fsm_inst *fi, int pr, void *arg) printk(KERN_DEBUG "%s: start callback\n", idev->name); idev->dial_timer.expires = jiffies + mlp->cbdelay; - idev->dial_event = EV_TIMER_CB_IN; + idev->dial_event = EV_NET_TIMER_CB_IN; add_timer(&idev->dial_timer); fsm_change_state(&idev->fi, ST_WAIT_BEFORE_CB); @@ -1408,12 +1403,11 @@ do_callback(struct fsm_inst *fi, int pr, void *arg) } static int -isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, - char *eaz, char *nr) +isdn_net_dev_icall(isdn_net_dev *idev, struct isdn_slot *slot, + int si1, char *eaz, char *nr) { isdn_net_local *mlp = idev->mlp; struct isdn_net_phone *ph; - int slot = isdn_dc2minor(di, ch); char *my_eaz; /* check acceptable call types for DOV */ @@ -1431,9 +1425,6 @@ isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, if (*my_eaz == 'b' || *my_eaz == 'B') my_eaz++; /* skip to allow a match */ } - if (!USG_NONE(isdn_slot_usage(slot))) // FIXME? - return 0; - /* check called number */ switch (isdn_msncmp(eaz, my_eaz)) { case 1: /* no match */ @@ -1443,11 +1434,11 @@ isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, } dbg_net_icall("%s: pdev=%d di=%d pch=%d ch = %d\n", idev->name, - idev->pre_device, di, idev->pre_channel, ch); + idev->pre_device, slot->di, idev->pre_channel, slot->ch); /* check if exclusive */ - if ((isdn_slot_usage(slot) & ISDN_USAGE_EXCLUSIVE) && - (idev->pre_channel != ch || idev->pre_device != di)) { + if ((slot->usage & ISDN_USAGE_EXCLUSIVE) && + (idev->pre_channel != slot->ch || idev->pre_device != slot->di)) { dbg_net_icall("%s: excl check failed\n", idev->name); return 0; } @@ -1471,7 +1462,7 @@ isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, lp_get(mlp); /* check callback */ if (mlp->flags & ISDN_NET_CALLBACK) { - if (fsm_event(&idev->fi, EV_DO_CALLBACK, NULL)) { + if (fsm_event(&idev->fi, EV_NET_DO_CALLBACK, NULL)) { lp_put(mlp); return 0; } @@ -1481,7 +1472,7 @@ isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, printk(KERN_INFO "%s: call from %s -> %s accepted\n", idev->name, nr, eaz); - if (fsm_event(&idev->fi, EV_DO_ACCEPT, (void *) slot)) { + if (fsm_event(&idev->fi, EV_NET_DO_ACCEPT, slot)) { lp_put(mlp); return 0; } @@ -1505,7 +1496,7 @@ isdn_net_dev_icall(isdn_net_dev *idev, int di, int ch, int si1, * would eventually match if CID was longer. */ int -isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) +isdn_net_find_icall(struct isdn_slot *slot, setup_parm *setup) { isdn_net_local *lp; isdn_net_dev *idev; @@ -1545,8 +1536,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) return 0; } - dbg_net_icall("n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx, - isdn_slot_usage(idx)); + dbg_net_icall("n_fi: di=%d ch=%d usg=%#x\n", slot->di, slot->ch, + slot->usage); retval = 0; spin_lock_irqsave(&running_devs_lock, flags); @@ -1555,7 +1546,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) spin_unlock_irqrestore(&running_devs_lock, flags); list_for_each_entry(idev, &lp->slaves, slaves) { - retval = isdn_net_dev_icall(idev, di, ch, si1, eaz, nr); + retval = isdn_net_dev_icall(idev, slot, si1, eaz, nr); if (retval > 0) break; } @@ -1604,7 +1595,7 @@ do_dial(struct fsm_inst *fi, int pr, void *arg) { isdn_net_dev *idev = fi->userdata; isdn_net_local *mlp = idev->mlp; - int slot; + struct isdn_slot *slot; if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF) return -EPERM; @@ -1612,13 +1603,13 @@ do_dial(struct fsm_inst *fi, int pr, void *arg) if (list_empty(&mlp->phone[1])) /* no number to dial ? */ return -EINVAL; - if (idev->exclusive >= 0) + if (idev->exclusive) slot = idev->exclusive; else slot = isdn_get_free_slot(ISDN_USAGE_NET, mlp->l2_proto, mlp->l3_proto, idev->pre_device, idev->pre_channel, mlp->msn); - if (slot < 0) + if (!slot) return -EAGAIN; if (isdn_net_bind_channel(idev, slot) < 0) { @@ -1663,10 +1654,10 @@ dialout_next(struct fsm_inst *fi, int pr, void *arg) /* For outgoing callback, use cbdelay instead of dialtimeout */ if (mlp->cbdelay && (mlp->flags & ISDN_NET_CBOUT)) { idev->dial_timer.expires = jiffies + mlp->cbdelay; - idev->dial_event = EV_TIMER_CB_OUT; + idev->dial_event = EV_NET_TIMER_CB_OUT; } else { idev->dial_timer.expires = jiffies + mlp->dialtimeout; - idev->dial_event = EV_TIMER_DIAL; + idev->dial_event = EV_NET_TIMER_DIAL; } fsm_change_state(&idev->fi, ST_OUT_WAIT_DCONN); add_timer(&idev->dial_timer); @@ -1699,7 +1690,7 @@ dial_timeout(struct fsm_inst *fi, int pr, void *arg) isdn_net_hangup(idev); return 0; } - idev->dial_event = EV_TIMER_DIAL_WAIT; + idev->dial_event = EV_NET_TIMER_DIAL_WAIT; mod_timer(&idev->dial_timer, jiffies + mlp->dialwait); return 0; } @@ -1710,7 +1701,6 @@ connect_fail(struct fsm_inst *fi, int pr, void *arg) isdn_net_dev *idev = fi->userdata; del_timer(&idev->dial_timer); - isdn_slot_all_eaz(idev->isdn_slot); printk(KERN_INFO "%s: connection failed\n", idev->name); isdn_net_unbind_channel(idev); return 0; @@ -1748,7 +1738,7 @@ bconn(struct fsm_inst *fi, int pr, void *arg) if (mlp->onhtime) { idev->huptimer = 0; - idev->dial_event = EV_TIMER_HUP; + idev->dial_event = EV_NET_TIMER_HUP; mod_timer(&idev->dial_timer, jiffies + HZ); } else { del_timer(&idev->dial_timer); @@ -1794,7 +1784,6 @@ dhup(struct fsm_inst *fi, int pr, void *arg) isdn_net_dev *idev = fi->userdata; printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, idev->charge); - isdn_slot_all_eaz(idev->isdn_slot); isdn_net_unbind_channel(idev); return 0; } @@ -1862,39 +1851,45 @@ isdn_net_hangup(isdn_net_dev *idev) del_timer(&idev->dial_timer); printk(KERN_INFO "%s: local hangup\n", idev->name); - isdn_slot_command(idev->isdn_slot, ISDN_CMD_HANGUP, &cmd); + // FIXME via state machine + if (idev->isdn_slot) + isdn_slot_command(idev->isdn_slot, ISDN_CMD_HANGUP, &cmd); return 1; } +static int isdn_net_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb); + /* * Handle status-messages from ISDN-interfacecard. * This function is called from within the main-status-dispatcher * isdn_status_callback, which itself is called from the low-level driver. - * Return: 1 = event handled, 0 = not handled */ -int -isdn_net_stat_callback(int idx, isdn_ctrl *c) +static int +isdn_net_event_callback(struct isdn_slot *slot, int pr, void *arg) { - isdn_net_dev *idev = isdn_slot_idev(idx); + isdn_net_dev *idev = slot->priv; if (!idev) { + isdn_BUG(); return 0; } - switch (c->command) { - case ISDN_STAT_DCONN: - return fsm_event(&idev->fi, EV_STAT_DCONN, c); - case ISDN_STAT_BCONN: - return fsm_event(&idev->fi, EV_STAT_BCONN, c); - case ISDN_STAT_BHUP: - return fsm_event(&idev->fi, EV_STAT_BHUP, c); - case ISDN_STAT_DHUP: - return fsm_event(&idev->fi, EV_STAT_DHUP, c); - case ISDN_STAT_CINF: - return fsm_event(&idev->fi, EV_STAT_CINF, c); - case ISDN_STAT_BSENT: - return fsm_event(&idev->fi, EV_STAT_BSENT, c); + switch (pr) { + case EV_DATA_IND: + return isdn_net_rcv_skb(slot, arg); + case EV_STAT_DCONN: + return fsm_event(&idev->fi, EV_NET_STAT_DCONN, arg); + case EV_STAT_BCONN: + return fsm_event(&idev->fi, EV_NET_STAT_BCONN, arg); + case EV_STAT_BHUP: + return fsm_event(&idev->fi, EV_NET_STAT_BHUP, arg); + case EV_STAT_DHUP: + return fsm_event(&idev->fi, EV_NET_STAT_DHUP, arg); + case EV_STAT_CINF: + return fsm_event(&idev->fi, EV_NET_STAT_CINF, arg); + case EV_STAT_BSENT: + return fsm_event(&idev->fi, EV_NET_STAT_BSENT, arg); default: - printk("unknown stat %d\n", c->command); + printk("unknown pr %d\n", pr); return 0; } } @@ -1925,37 +1920,37 @@ got_bsent(struct fsm_inst *fi, int pr, void *arg) } static struct fsm_node isdn_net_fn_tbl[] = { - { ST_NULL, EV_DO_DIAL, do_dial }, - { ST_NULL, EV_DO_ACCEPT, accept_icall }, - { ST_NULL, EV_DO_CALLBACK, do_callback }, + { ST_NULL, EV_NET_DO_DIAL, do_dial }, + { ST_NULL, EV_NET_DO_ACCEPT, accept_icall }, + { ST_NULL, EV_NET_DO_CALLBACK, do_callback }, - { ST_OUT_WAIT_DCONN, EV_TIMER_DIAL, dial_timeout }, - { ST_OUT_WAIT_DCONN, EV_STAT_DCONN, out_dconn }, - { ST_OUT_WAIT_DCONN, EV_STAT_DHUP, connect_fail }, - { ST_OUT_WAIT_DCONN, EV_TIMER_CB_OUT, hang_up }, + { ST_OUT_WAIT_DCONN, EV_NET_TIMER_DIAL, dial_timeout }, + { ST_OUT_WAIT_DCONN, EV_NET_STAT_DCONN, out_dconn }, + { ST_OUT_WAIT_DCONN, EV_NET_STAT_DHUP, connect_fail }, + { ST_OUT_WAIT_DCONN, EV_NET_TIMER_CB_OUT, hang_up }, - { ST_OUT_WAIT_BCONN, EV_TIMER_DIAL, dial_timeout }, - { ST_OUT_WAIT_BCONN, EV_STAT_BCONN, bconn }, - { ST_OUT_WAIT_BCONN, EV_STAT_DHUP, connect_fail }, + { ST_OUT_WAIT_BCONN, EV_NET_TIMER_DIAL, dial_timeout }, + { ST_OUT_WAIT_BCONN, EV_NET_STAT_BCONN, bconn }, + { ST_OUT_WAIT_BCONN, EV_NET_STAT_DHUP, connect_fail }, - { ST_IN_WAIT_DCONN, EV_TIMER_INCOMING, hang_up }, - { ST_IN_WAIT_DCONN, EV_STAT_DCONN, in_dconn }, - { ST_IN_WAIT_DCONN, EV_STAT_DHUP, connect_fail }, + { ST_IN_WAIT_DCONN, EV_NET_TIMER_INCOMING, hang_up }, + { ST_IN_WAIT_DCONN, EV_NET_STAT_DCONN, in_dconn }, + { ST_IN_WAIT_DCONN, EV_NET_STAT_DHUP, connect_fail }, - { ST_IN_WAIT_BCONN, EV_TIMER_INCOMING, hang_up }, - { ST_IN_WAIT_BCONN, EV_STAT_BCONN, bconn }, - { ST_IN_WAIT_BCONN, EV_STAT_DHUP, connect_fail }, + { ST_IN_WAIT_BCONN, EV_NET_TIMER_INCOMING, hang_up }, + { ST_IN_WAIT_BCONN, EV_NET_STAT_BCONN, bconn }, + { ST_IN_WAIT_BCONN, EV_NET_STAT_DHUP, connect_fail }, - { ST_ACTIVE, EV_TIMER_HUP, check_hup }, - { ST_ACTIVE, EV_STAT_BHUP, bhup }, - { ST_ACTIVE, EV_STAT_CINF, got_cinf }, - { ST_ACTIVE, EV_STAT_BSENT, got_bsent }, + { ST_ACTIVE, EV_NET_TIMER_HUP, check_hup }, + { ST_ACTIVE, EV_NET_STAT_BHUP, bhup }, + { ST_ACTIVE, EV_NET_STAT_CINF, got_cinf }, + { ST_ACTIVE, EV_NET_STAT_BSENT, got_bsent }, - { ST_WAIT_DHUP, EV_STAT_DHUP, dhup }, + { ST_WAIT_DHUP, EV_NET_STAT_DHUP, dhup }, - { ST_WAIT_BEFORE_CB, EV_TIMER_CB_IN, do_dial }, + { ST_WAIT_BEFORE_CB, EV_NET_TIMER_CB_IN, do_dial }, - { ST_OUT_DIAL_WAIT, EV_TIMER_DIAL_WAIT, dialout_next }, + { ST_OUT_DIAL_WAIT, EV_NET_TIMER_DIAL_WAIT, dialout_next }, }; static struct fsm isdn_net_fsm = { @@ -2224,7 +2219,8 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) } else { /* subsequent overload: if slavedelay exceeded, start dialing */ if (time_after(jiffies, idev->sqfull_stamp + mlp->slavedelay)) { - isdn_net_dial_slave(mlp); + if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_AUTO) + __isdn_net_dial_slave(mlp); } } } else { @@ -2267,10 +2263,10 @@ isdn_net_write_super(isdn_net_dev *idev, struct sk_buff *skb) * interface. If found, deliver packet to receiver-function and return 1, * else return 0. */ -int -isdn_net_rcv_skb(int idx, struct sk_buff *skb) +static int +isdn_net_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb) { - isdn_net_dev *idev = isdn_slot_idev(idx); + isdn_net_dev *idev = slot->priv; isdn_net_local *mlp; if (!idev) { @@ -2297,6 +2293,20 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb) return 1; } +/* + * After handling connection-type specific stuff, the receiver function + * can use this function to pass the skb on to the network layer. + */ +void +isdn_netif_rx(isdn_net_dev *idev, struct sk_buff *skb, u16 protocol) +{ + idev->huptimer = 0; + + skb->protocol = protocol; + skb->dev = &idev->mlp->dev; + netif_rx(skb); +} + /* ====================================================================== */ /* init / exit */ /* ====================================================================== */ @@ -2305,12 +2315,27 @@ void isdn_net_lib_init(void) { fsm_new(&isdn_net_fsm); + +#ifdef CONFIG_ISDN_NET_SIMPLE + register_isdn_netif(ISDN_NET_ENCAP_ETHER, &isdn_ether_ops); + register_isdn_netif(ISDN_NET_ENCAP_RAWIP, &isdn_rawip_ops); + register_isdn_netif(ISDN_NET_ENCAP_IPTYP, &isdn_iptyp_ops); + register_isdn_netif(ISDN_NET_ENCAP_UIHDLC, &isdn_uihdlc_ops); +#endif +#ifdef CONFIG_ISDN_NET_CISCO + register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLC, &isdn_ciscohdlck_ops); + register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLCK, &isdn_ciscohdlck_ops); +#endif +#ifdef CONFIG_ISDN_X25 + register_isdn_netif(ISDN_NET_ENCAP_X25IFACE, &isdn_x25_ops); +#endif +#ifdef CONFIG_ISDN_PPP + register_isdn_netif(ISDN_NET_ENCAP_SYNCPPP, &isdn_ppp_ops); +#endif } void isdn_net_lib_exit(void) { - isdn_net_cleanup(); - fsm_free(&isdn_net_fsm); } diff --git a/drivers/isdn/i4l/isdn_net_lib.h b/drivers/isdn/i4l/isdn_net_lib.h new file mode 100644 index 000000000000..0258036dc0fb --- /dev/null +++ b/drivers/isdn/i4l/isdn_net_lib.h @@ -0,0 +1,224 @@ +/* Linux ISDN subsystem, network interface support code + * + * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef __ISDN_NET_LIB_H__ +#define __ISDN_NET_LIB_H__ + +#include <linux/isdn.h> + +typedef struct isdn_net_local_s isdn_net_local; +typedef struct isdn_net_dev_s isdn_net_dev; + +struct isdn_netif_ops { + int (*hard_start_xmit) (struct sk_buff *skb, + struct net_device *dev); + int (*hard_header) (struct sk_buff *skb, + struct net_device *dev, + unsigned short type, + void *daddr, + void *saddr, + unsigned len); + int (*do_ioctl)(struct net_device *dev, + struct ifreq *ifr, int cmd); + + unsigned short flags; /* interface flags (a la BSD) */ + unsigned short type; /* interface hardware type */ + unsigned char addr_len;/* hardware address length */ + void (*receive)(struct isdn_net_local_s *, + struct isdn_net_dev_s *, + struct sk_buff *); + void (*connected)(struct isdn_net_dev_s *); + void (*disconnected)(struct isdn_net_dev_s *); + int (*bind)(struct isdn_net_dev_s *); + void (*unbind)(struct isdn_net_dev_s *); + int (*init)(struct isdn_net_local_s *); + void (*cleanup)(struct isdn_net_local_s *); + int (*open)(struct isdn_net_local_s *); + void (*close)(struct isdn_net_local_s *); +}; + +/* our interface to isdn_common.c */ +void isdn_net_lib_init(void); +void isdn_net_lib_exit(void); +void isdn_net_hangup_all(void); +int isdn_net_ioctl(struct inode *, struct file *, uint, ulong); +int isdn_net_find_icall(struct isdn_slot *slot, setup_parm *setup); + +/* provided for interface types to use */ +void isdn_net_writebuf_skb(isdn_net_dev *, struct sk_buff *skb); +void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb); +void isdn_net_online(isdn_net_dev *idev); +void isdn_net_offline(isdn_net_dev *idev); +int isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev); +void isdn_netif_rx(isdn_net_dev *idev, struct sk_buff *skb, u16 protocol); +isdn_net_dev *isdn_net_get_xmit_dev(isdn_net_local *mlp); +int isdn_net_hangup(isdn_net_dev *); +int isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev); +int isdn_net_dial_req(isdn_net_dev *); +int register_isdn_netif(int encap, struct isdn_netif_ops *ops); + +/* ====================================================================== */ + +/* Feature- and status-flags for a net-interface */ +#define ISDN_NET_SECURE 0x02 /* Accept calls from phonelist only */ +#define ISDN_NET_CALLBACK 0x04 /* activate callback */ +#define ISDN_NET_CBHUP 0x08 /* hangup before callback */ +#define ISDN_NET_CBOUT 0x10 /* remote machine does callback */ + +#define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */ + +/* Phone-list-element */ +struct isdn_net_phone { + struct list_head list; + char num[ISDN_MSNLEN]; +}; + +/* per network interface data (dev->priv) */ + +struct isdn_net_local_s { + ulong magic; + struct net_device dev; /* interface to upper levels */ + struct net_device_stats stats; /* Ethernet Statistics */ + struct isdn_netif_ops *ops; + void *inl_priv; /* interface types can put their + private data here */ + int flags; /* Connection-flags */ + int dialmax; /* Max. Number of Dial-retries */ + int dialtimeout; /* How long shall we try on dialing */ + int dialwait; /* wait after failed attempt */ + + int cbdelay; /* Delay before Callback starts */ + char msn[ISDN_MSNLEN]; /* MSNs/EAZs for this interface */ + + u_char cbhup; /* Flag: Reject Call before Callback*/ + int hupflags; /* Flags for charge-unit-hangup: */ + int onhtime; /* Time to keep link up */ + + u_char p_encap; /* Packet encapsulation */ + u_char l2_proto; /* Layer-2-protocol */ + u_char l3_proto; /* Layer-3-protocol */ + + ulong slavedelay; /* Dynamic bundling delaytime */ + int triggercps; /* BogoCPS needed for trigger slave */ + struct list_head phone[2]; /* List of remote-phonenumbers */ + /* phone[0] = Incoming Numbers */ + /* phone[1] = Outgoing Numbers */ + + struct list_head slaves; /* list of all bundled channels + protected by serializing config + ioctls / no change allowed when + interface is running */ + struct list_head online; /* list of all bundled channels + which can be used for actual + data (IP) transfer + protected by xmit_lock */ + + spinlock_t xmit_lock; /* used to protect the xmit path of + a net_device, including all + associated channels's frame_cnt */ + struct list_head running_devs; /* member of global running_devs */ + atomic_t refcnt; /* references held by ISDN code */ + +}; + + +/* per ISDN channel (ISDN interface) data */ + +struct isdn_net_dev_s { + struct isdn_slot *isdn_slot; /* Index to isdn device/channel */ + struct isdn_slot *exclusive; /* NULL if non excl */ + int pre_device; /* Preselected isdn-device */ + int pre_channel; /* Preselected isdn-channel */ + + struct timer_list dial_timer; /* dial events timer */ + struct fsm_inst fi; /* call control state machine */ + int dial_event; /* event in case of timer expiry */ + int dial; /* # of phone number just dialed */ + int outgoing; /* Flag: outgoing call */ + int dialretry; /* Counter for Dialout-retries */ + + int cps; /* current speed of this interface */ + int transcount; /* byte-counter for cps-calculation */ + int last_jiffies; /* when transcount was reset */ + int sqfull; /* Flag: netdev-queue overloaded */ + ulong sqfull_stamp; /* Start-Time of overload */ + + int huptimer; /* Timeout-counter for auto-hangup */ + int charge; /* Counter for charging units */ + int charge_state; /* ChargeInfo state machine */ + unsigned long chargetime; /* Timer for Charging info */ + int chargeint; /* Interval between charge-infos */ + + int pppbind; /* ippp device for bindings */ + + struct sk_buff_head super_tx_queue; /* List of supervisory frames to */ + /* be transmitted asap */ + int frame_cnt; /* number of frames currently */ + /* queued in HL driver */ + struct tasklet_struct tlet; + + isdn_net_local *mlp; /* Ptr to master device for all devs*/ + + struct list_head slaves; /* member of local->slaves */ + struct list_head online; /* member of local->online */ + + char name[10]; /* Name of device */ + struct list_head global_list; /* global list of all isdn_net_devs */ + void *ind_priv; /* interface types can put their + private data here */ +}; + +/* ====================================================================== */ + +static inline int +put_u8(unsigned char *p, u8 x) +{ + *p = x; + return 1; +} + +static inline int +put_u16(unsigned char *p, u16 x) +{ + *((u16 *)p) = htons(x); + return 2; +} + +static inline int +put_u32(unsigned char *p, u32 x) +{ + *((u32 *)p) = htonl(x); + return 4; +} + +static inline int +get_u8(unsigned char *p, u8 *x) +{ + *x = *p; + return 1; +} + +static inline int +get_u16(unsigned char *p, u16 *x) +{ + *x = ntohs(*((u16 *)p)); + return 2; +} + +static inline int +get_u32(unsigned char *p, u32 *x) +{ + *x = ntohl(*((u32 *)p)); + return 4; +} + + +#endif diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 13395d86720a..33465ebbaffb 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -1,12 +1,10 @@ -/* $Id: isdn_ppp.c,v 1.85.6.9 2001/11/06 20:58:28 kai Exp $ +/* Linux ISDN subsystem, functions for synchronous PPP (linklevel). * - * Linux ISDN subsystem, functions for synchronous PPP (linklevel). - * - * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #include <linux/module.h> @@ -17,12 +15,15 @@ #include <linux/if_arp.h> #include "isdn_common.h" +#include "isdn_net_lib.h" #include "isdn_ppp.h" #include "isdn_ppp_ccp.h" -#include "isdn_net.h" +#include "isdn_ppp_vj.h" +#include "isdn_ppp_mp.h" -static struct sk_buff * -isdn_ppp_dev_alloc_skb(void *priv, int len, int gfp_mask); +/* ====================================================================== */ + +#define IPPP_MAX_RQ_LEN 8 /* max #frames queued for ipppd to read */ static int isdn_ppp_set_compressor(isdn_net_dev *idev, struct isdn_ppp_comp_data *); @@ -42,7 +43,7 @@ isdn_ppp_set_compressor(isdn_net_dev *idev, struct isdn_ppp_comp_data *); * idev->ipppd is safe without further locking. */ -#define IPPPD_DEBUG +#undef IPPPD_DEBUG #ifdef IPPPD_DEBUG #define ipppd_debug(i, fmt, arg...) \ @@ -211,6 +212,8 @@ static ssize_t ipppd_write(struct file *file, const char *buf, size_t count, loff_t *off) { isdn_net_dev *idev; + struct inl_ppp *inl_ppp; + struct ind_ppp *ind_ppp; struct ipppd *ipppd; struct sk_buff *skb; char *p; @@ -234,6 +237,8 @@ ipppd_write(struct file *file, const char *buf, size_t count, loff_t *off) retval = -ENODEV; goto out; } + ind_ppp = idev->ind_priv; + inl_ppp = idev->mlp->inl_priv; /* Daemon needs to send at least full header, AC + proto */ if (count < 4) { retval = -EMSGSIZE; @@ -258,10 +263,10 @@ ipppd_write(struct file *file, const char *buf, size_t count, loff_t *off) /* Keeps CCP/compression states in sync */ switch (proto) { case PPP_CCP: - ippp_ccp_send_ccp(idev->mlp->ccp, skb); + ippp_ccp_send_ccp(inl_ppp->ccp, skb); break; case PPP_CCPFRAG: - ippp_ccp_send_ccp(idev->ccp, skb); + ippp_ccp_send_ccp(ind_ppp->ccp, skb); break; } /* FIXME: Somewhere we need protection against the @@ -302,8 +307,6 @@ ipppd_poll(struct file *file, poll_table * wait) if (!skb_queue_empty(&is->rq) || is->flags & IPPPD_FL_WAKEUP) { is->flags &= ~IPPPD_FL_WAKEUP; mask |= POLLIN | POLLRDNORM; - set_current_state(TASK_INTERRUPTIBLE); // FIXME - schedule_timeout(HZ); } out: @@ -335,6 +338,8 @@ ipppd_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned long arg) { isdn_net_dev *idev; + struct ind_ppp *ind_ppp = NULL; + struct inl_ppp *inl_ppp = NULL; unsigned long val; int r; struct ipppd *is; @@ -342,28 +347,16 @@ ipppd_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned int cfg; is = file->private_data; - idev = is->idev; ipppd_debug(is, "cmd %#x", cmd); + // FIXME that needs locking? + idev = is->idev; + if (idev) { + ind_ppp = idev->ind_priv; + inl_ppp = idev->mlp->inl_priv; + } switch (cmd) { - case PPPIOCBUNDLE: -#ifdef CONFIG_ISDN_MPP - if (is->state != IPPPD_ST_CONNECTED) { - r = -EINVAL; - break; - } - r = get_arg(arg, &val, sizeof(val)); - if (r) - break; - - printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n", - is->minor, is->unit, val); - r = isdn_ppp_bundle(is, val); -#else - r = -EINVAL; -#endif - break; case PPPIOCGUNIT: /* get ppp/isdn unit number */ r = set_arg(arg, &is->unit, sizeof(is->unit)); break; @@ -376,8 +369,8 @@ ipppd_ioctl(struct inode *ino, struct file *file, unsigned int cmd, break; is->debug = val; if (idev) { - idev->debug = val; - idev->mlp->debug = val; + ind_ppp->debug = val; + inl_ppp->debug = val; } break; case PPPIOCGCOMPRESSORS: @@ -401,33 +394,40 @@ ipppd_ioctl(struct inode *ino, struct file *file, unsigned int cmd, } switch (cmd) { + case PPPIOCBUNDLE: + r = get_arg(arg, &val, sizeof(val)); + if (r) + break; + + r = ippp_mp_bundle(idev, val); + break; case PPPIOCGIFNAME: r = set_arg(arg, idev->name, strlen(idev->name)+1); break; case PPPIOCGMPFLAGS: /* get configuration flags */ - r = set_arg(arg, &idev->mlp->mpppcfg, sizeof(idev->mlp->mpppcfg)); + r = set_arg(arg, &inl_ppp->mp_cfg, sizeof(inl_ppp->mp_cfg)); break; case PPPIOCSMPFLAGS: /* set configuration flags */ r = get_arg(arg, &val, sizeof(val)); if (r) break; - idev->mlp->mpppcfg = val; + inl_ppp->mp_cfg = val; break; case PPPIOCGFLAGS: /* get configuration flags */ - cfg = idev->pppcfg | ippp_ccp_get_flags(idev->ccp); + cfg = ind_ppp->pppcfg | ippp_ccp_get_flags(ind_ppp->ccp); r = set_arg(arg, &cfg, sizeof(cfg)); break; case PPPIOCSFLAGS: /* set configuration flags */ r = get_arg(arg, &val, sizeof(val)); if (r) break; - if ((val & SC_ENABLE_IP) && !(idev->pppcfg & SC_ENABLE_IP)) { - idev->pppcfg = val; + if ((val & SC_ENABLE_IP) && !(ind_ppp->pppcfg & SC_ENABLE_IP)) { + ind_ppp->pppcfg = val; /* OK .. we are ready to send buffers */ isdn_net_online(idev); break; } - idev->pppcfg = val; + ind_ppp->pppcfg = val; break; case PPPIOCGIDLE: /* get idle time information */ { @@ -440,32 +440,18 @@ ipppd_ioctl(struct inode *ino, struct file *file, unsigned int cmd, r = get_arg(arg, &val, sizeof(val)); if (r) break; - r = ippp_ccp_set_mru(idev->ccp, val); + r = ippp_ccp_set_mru(ind_ppp->ccp, val); break; case PPPIOCSMPMRU: break; case PPPIOCSMPMTU: break; -#ifdef CONFIG_ISDN_PPP_VJ case PPPIOCSMAXCID: /* set the maximum compression slot id */ - { - struct slcompress *sltmp; r = get_arg(arg, &val, sizeof(val)); if (r) break; - val++; - sltmp = slhc_init(16, val); - if (!sltmp) { - r = -ENOMEM; - break; - } - if (idev->mlp->slcomp) - slhc_free(idev->mlp->slcomp); - idev->mlp->slcomp = sltmp; - r = 0; + r = ippp_vj_set_maxcid(idev, val); break; - } -#endif case PPPIOCSCOMPRESSOR: r = get_arg(arg, &data, sizeof(data)); if (r) @@ -563,42 +549,24 @@ ipppd_queue_read(struct ipppd *is, u16 proto, unsigned char *buf, int len) } /* ====================================================================== */ +/* interface to isdn_net_lib */ +/* ====================================================================== */ -/* Prototypes */ -static void isdn_ppp_push_higher(isdn_net_local *lp, isdn_net_dev *idev, - struct sk_buff *skb, int proto); -static int isdn_ppp_if_get_unit(char *namebuf); -static void -isdn_ppp_dev_push_header(void *priv, struct sk_buff *skb, u16 proto); +/* Prototypes */ +static int +isdn_ppp_if_get_unit(char *namebuf); static void -isdn_ppp_dev_xmit(void *priv, struct sk_buff *skb); +isdn_ppp_dev_xmit(void *priv, struct sk_buff *skb, u16 proto); static struct sk_buff * isdn_ppp_lp_alloc_skb(void *priv, int len, int gfp_mask); -static void -isdn_ppp_lp_push_header(void *priv, struct sk_buff *skb, u16 proto); - /* New CCP stuff */ static void isdn_ppp_dev_kick_up(void *priv); -#ifdef CONFIG_ISDN_MPP -static ippp_bundle * isdn_ppp_bundle_arr = NULL; - -static int isdn_ppp_mp_bundle_array_init(void); -static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to); -static void isdn_ppp_mp_receive(isdn_net_local *lp, isdn_net_dev *idev, - struct sk_buff *skb); -static void isdn_ppp_mp_cleanup(isdn_net_local *lp ); - -static int isdn_ppp_bundle(struct ipppd *, int unit); -#endif /* CONFIG_ISDN_MPP */ - -char *isdn_ppp_revision = "$Revision: 1.85.6.9 $"; - /* * frame log (debug) */ @@ -620,23 +588,30 @@ isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot } } - -static void -isdn_ppp_push_header(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +void +ippp_push_proto(struct ind_ppp *ind_ppp, struct sk_buff *skb, u16 proto) { - unsigned char *p; - - if (skb_headroom(skb) < 4) { + if (skb_headroom(skb) < 2) { isdn_BUG(); return; } - - if ((idev->pppcfg & SC_COMP_PROT) && proto <= 0xff) + if ((ind_ppp->pppcfg & SC_COMP_PROT) && proto <= 0xff) put_u8(skb_push(skb, 1), proto); else put_u16(skb_push(skb, 2), proto); - if (idev->pppcfg & SC_COMP_AC) +} + +static void +ippp_push_ac(struct ind_ppp *ind_ppp, struct sk_buff *skb) +{ + unsigned char *p; + + if (skb_headroom(skb) < 2) { + isdn_BUG(); + return; + } + if (ind_ppp->pppcfg & SC_COMP_AC) return; p = skb_push(skb, 2); @@ -652,13 +627,13 @@ isdn_ppp_push_header(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) static void isdn_ppp_unbind(isdn_net_dev *idev) { - struct ipppd *is = idev->ipppd; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *is = ind_ppp->ipppd; if (!is) { isdn_BUG(); return; } - ipppd_debug(is, ""); if (is->state != IPPPD_ST_ASSIGNED) @@ -667,12 +642,15 @@ isdn_ppp_unbind(isdn_net_dev *idev) is->state = IPPPD_ST_OPEN; /* is->idev will be invalid shortly */ - ippp_ccp_free(idev->ccp); + ippp_ccp_free(ind_ppp->ccp); is->idev = NULL; /* lose the reference we took on isdn_ppp_bind */ ipppd_put(is); - idev->ipppd = NULL; + ind_ppp->ipppd = NULL; + + kfree(ind_ppp); + idev->ind_priv = NULL; return; } @@ -683,15 +661,19 @@ isdn_ppp_unbind(isdn_net_dev *idev) int isdn_ppp_bind(isdn_net_dev *idev) { + struct ind_ppp *ind_ppp; int unit = 0; unsigned long flags; int retval = 0; struct ipppd *ipppd; - if (idev->ipppd) { + if (idev->ind_priv) { isdn_BUG(); - return 0; + return -EIO; } + ind_ppp = kmalloc(sizeof(struct ind_ppp), GFP_KERNEL); + if (!ind_ppp) + return -ENOMEM; spin_lock_irqsave(&ipppds_lock, flags); if (idev->pppbind < 0) { /* device bound to ippp device ? */ @@ -743,39 +725,40 @@ isdn_ppp_bind(isdn_net_dev *idev) ipppd->state = IPPPD_ST_ASSIGNED; ipppd->idev = idev; /* we hold a reference until isdn_ppp_unbind() */ - idev->ipppd = ipppd_get(ipppd); + ipppd_get(ipppd); spin_unlock_irqrestore(&ipppds_lock, flags); - idev->pppcfg = 0; /* config flags */ - /* seq no last seen, maybe set to bundle min, when joining? */ - idev->pppseq = -1; - - idev->ccp = ippp_ccp_alloc(); - if (!idev->ccp) { + idev->ind_priv = ind_ppp; + ind_ppp->pppcfg = 0; /* config flags */ + ind_ppp->ipppd = ipppd; + ind_ppp->ccp = ippp_ccp_alloc(); + if (!ind_ppp->ccp) { retval = -ENOMEM; goto out; } - idev->ccp->proto = PPP_COMPFRAG; - idev->ccp->priv = idev; - idev->ccp->alloc_skb = isdn_ppp_dev_alloc_skb; - idev->ccp->push_header = isdn_ppp_dev_push_header; - idev->ccp->xmit = isdn_ppp_dev_xmit; - idev->ccp->kick_up = isdn_ppp_dev_kick_up; - -#ifdef CONFIG_ISDN_MPP - retval = isdn_ppp_mp_init(lp, NULL); -#endif /* CONFIG_ISDN_MPP */ - out: - if (retval) { - idev->ipppd->state = IPPPD_ST_OPEN; - ipppd_put(idev->ipppd); - idev->ipppd = NULL; - } + ind_ppp->ccp->proto = PPP_COMPFRAG; + ind_ppp->ccp->priv = idev; + ind_ppp->ccp->alloc_skb = isdn_ppp_dev_alloc_skb; + ind_ppp->ccp->xmit = isdn_ppp_dev_xmit; + ind_ppp->ccp->kick_up = isdn_ppp_dev_kick_up; + + retval = ippp_mp_bind(idev); + if (retval) + goto out; + + return 0; + out: + ipppd->state = IPPPD_ST_OPEN; + ipppd_put(ipppd); + ind_ppp->ipppd = NULL; + kfree(ind_ppp); + idev->ind_priv = NULL; return retval; err: spin_unlock_irqrestore(&ipppds_lock, flags); + kfree(ind_ppp); return retval; } @@ -787,7 +770,8 @@ isdn_ppp_bind(isdn_net_dev *idev) static void isdn_ppp_connected(isdn_net_dev *idev) { - struct ipppd *ipppd = idev->ipppd; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *ipppd = ind_ppp->ipppd; ipppd_debug(ipppd, ""); @@ -799,11 +783,12 @@ isdn_ppp_connected(isdn_net_dev *idev) static void isdn_ppp_disconnected(isdn_net_dev *idev) { - struct ipppd *ipppd = idev->ipppd; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *ipppd = ind_ppp->ipppd; ipppd_debug(ipppd, ""); - if (idev->pppcfg & SC_ENABLE_IP) + if (ind_ppp->pppcfg & SC_ENABLE_IP) isdn_net_offline(idev); if (ipppd->state != IPPPD_ST_CONNECTED) @@ -813,15 +798,7 @@ isdn_ppp_disconnected(isdn_net_dev *idev) ipppd->flags |= IPPPD_FL_HUP; wake_up(&ipppd->wq); -#ifdef CONFIG_ISDN_MPP - spin_lock(&idev->pb->lock); - if (lp->netdev->pb->ref_ct == 1) /* last link in queue? */ - isdn_ppp_mp_cleanup(lp); - - lp->netdev->pb->ref_ct--; - spin_unlock(&lp->netdev->pb->lock); -#endif /* CONFIG_ISDN_MPP */ - + ippp_mp_disconnected(idev); } /* @@ -831,50 +808,41 @@ isdn_ppp_disconnected(isdn_net_dev *idev) int isdn_ppp_init(void) { -#ifdef CONFIG_ISDN_MPP - if( isdn_ppp_mp_bundle_array_init() < 0 ) - return -ENOMEM; -#endif /* CONFIG_ISDN_MPP */ - return 0; } void isdn_ppp_cleanup(void) { -#ifdef CONFIG_ISDN_MPP - if (isdn_ppp_bundle_arr) - kfree(isdn_ppp_bundle_arr); -#endif /* CONFIG_ISDN_MPP */ - } /* * check for address/control field and skip if allowed * retval != 0 -> discard packet silently */ -static int isdn_ppp_skip_ac(isdn_net_dev *idev, struct sk_buff *skb) +static int +isdn_ppp_skip_ac(struct ind_ppp *ind_ppp, struct sk_buff *skb) { u8 val; if (skb->len < 1) - return -1; + return -EINVAL; get_u8(skb->data, &val); if (val != PPP_ALLSTATIONS) { /* if AC compression was not negotiated, but no AC present, discard packet */ - if (idev->pppcfg & SC_REJ_COMP_AC) - return -1; + if (ind_ppp->pppcfg & SC_REJ_COMP_AC) + return -EINVAL; return 0; } if (skb->len < 2) - return -1; + return -EINVAL; get_u8(skb->data + 1, &val); if (val != PPP_UI) - return -1; + return -EINVAL; /* skip address/control (AC) field */ skb_pull(skb, 2); @@ -885,38 +853,38 @@ static int isdn_ppp_skip_ac(isdn_net_dev *idev, struct sk_buff *skb) * get the PPP protocol header and pull skb * retval < 0 -> discard packet silently */ -int isdn_ppp_strip_proto(struct sk_buff *skb) +int +isdn_ppp_strip_proto(struct sk_buff *skb, u16 *proto) { - u16 proto; u8 val; if (skb->len < 1) - return -1; + return -EINVAL; get_u8(skb->data, &val); if (val & 0x1) { /* protocol field is compressed */ - proto = val; + *proto = val; skb_pull(skb, 1); } else { if (skb->len < 2) return -1; - get_u16(skb->data, &proto); + get_u16(skb->data, proto); skb_pull(skb, 2); } - return proto; + return 0; } /* * handler for incoming packets on a syncPPP interface */ -static void isdn_ppp_receive(isdn_net_local *lp, isdn_net_dev *idev, - struct sk_buff *skb) +static void +isdn_ppp_receive(isdn_net_local *lp, isdn_net_dev *idev, struct sk_buff *skb) { - struct ipppd *is; - int proto; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *is = ind_ppp->ipppd; + u16 proto; - is = idev->ipppd; if (!is) goto err; @@ -926,117 +894,64 @@ static void isdn_ppp_receive(isdn_net_local *lp, isdn_net_dev *idev, isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,-1); } - if (isdn_ppp_skip_ac(idev, skb) < 0) + if (isdn_ppp_skip_ac(ind_ppp, skb) < 0) goto err; - proto = isdn_ppp_strip_proto(skb); - if (proto < 0) + if (isdn_ppp_strip_proto(skb, &proto)) goto err; - /* Don't reset huptimer on LCP packets. */ - if (proto != PPP_LCP) - idev->huptimer = 0; - -#ifdef CONFIG_ISDN_MPP - if (is->compflags & SC_LINK_DECOMP_ON) { - skb = isdn_ppp_decompress(skb, is, NULL, &proto); - if (!skb) // decompression error - goto put; - } - - if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP - if (proto == PPP_MP) { - isdn_ppp_mp_receive(lp, idev, skb); - goto put; - } - } - isdn_ppp_push_higher(lp, idev, skb, proto); - put: -#else - isdn_ppp_push_higher(lp, idev, skb, proto); -#endif + ippp_mp_receive(idev, skb, proto); return; err: + lp->stats.rx_dropped++; kfree_skb(skb); } /* - * we receive a reassembled frame, MPPP has been taken care of before. * address/control and protocol have been stripped from the skb - * note: net_dev has to be master net_dev */ -static void -isdn_ppp_push_higher(isdn_net_local *lp, isdn_net_dev *idev, - struct sk_buff *skb, int proto) +void +ippp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) { - struct net_device *dev = &lp->dev; - struct ipppd *is = idev->ipppd; + isdn_net_local *lp = idev->mlp; + struct inl_ppp *inl_ppp = lp->inl_priv; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *is = ind_ppp->ipppd; if (is->debug & 0x10) { printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto); - isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit, -1); + isdn_ppp_frame_log("rpush", skb->data, skb->len, 256, is->unit, -1); } - skb = ippp_ccp_decompress(lp->ccp, skb, &proto); - if (!skb) // decompression error - goto out; + /* all packets need to be passed through the compressor */ + skb = ippp_ccp_decompress(inl_ppp->ccp, skb, &proto); + if (!skb) /* decompression error */ + goto error; switch (proto) { case PPP_IPX: /* untested */ if (is->debug & 0x20) printk(KERN_DEBUG "isdn_ppp: IPX\n"); - skb->protocol = htons(ETH_P_IPX); + isdn_netif_rx(idev, skb, htons(ETH_P_IPX)); break; case PPP_IP: if (is->debug & 0x20) printk(KERN_DEBUG "isdn_ppp: IP\n"); - skb->protocol = htons(ETH_P_IP); + isdn_netif_rx(idev, skb, htons(ETH_P_IP)); break; case PPP_COMP: case PPP_COMPFRAG: printk(KERN_INFO "isdn_ppp: unexpected compressed frame dropped\n"); goto drop; -#ifdef CONFIG_ISDN_PPP_VJ case PPP_VJC_UNCOMP: - if (is->debug & 0x20) - printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n"); - if (slhc_remember(lp->slcomp, skb->data, skb->len) <= 0) { - printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n"); - goto drop; - } - skb->protocol = htons(ETH_P_IP); - break; case PPP_VJC_COMP: - if (is->debug & 0x20) - printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n"); - { - struct sk_buff *skb_old = skb; - int pkt_len; - skb = dev_alloc_skb(skb_old->len + 128); - - if (!skb) { - printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); - skb = skb_old; - goto drop; - } - skb_put(skb, skb_old->len + 128); - memcpy(skb->data, skb_old->data, skb_old->len); - pkt_len = slhc_uncompress(lp->slcomp, - skb->data, skb_old->len); - kfree_skb(skb_old); - if (pkt_len < 0) - goto drop; - - skb_trim(skb, pkt_len); - skb->protocol = htons(ETH_P_IP); - } + ippp_vj_decompress(idev, skb, proto); break; -#endif case PPP_CCPFRAG: - ippp_ccp_receive_ccp(idev->ccp, skb); + ippp_ccp_receive_ccp(ind_ppp->ccp, skb); goto ccp; case PPP_CCP: - ippp_ccp_receive_ccp(lp->ccp, skb); + ippp_ccp_receive_ccp(inl_ppp->ccp, skb); ccp: /* Dont pop up ResetReq/Ack stuff to the daemon any longer - the job is done already */ @@ -1049,20 +964,16 @@ isdn_ppp_push_higher(isdn_net_local *lp, isdn_net_dev *idev, ipppd_queue_read(is, proto, skb->data, skb->len); goto free; } - - /* Reset hangup-timer */ - idev->huptimer = 0; - - skb->dev = dev; - netif_rx(skb); - /* net_dev->local->stats.rx_packets++; done in isdn_net.c */ - out: return; drop: lp->stats.rx_dropped++; free: kfree_skb(skb); + return; + + error: + lp->stats.rx_dropped++; } /* @@ -1077,8 +988,10 @@ static int isdn_ppp_start_xmit(struct sk_buff *skb, struct net_device *ndev) { isdn_net_local *mlp = ndev->priv; + struct inl_ppp *inl_ppp = mlp->inl_priv; + struct ind_ppp *ind_ppp; isdn_net_dev *idev = list_entry(mlp->online.next, isdn_net_dev, online); - unsigned int proto = PPP_IP; /* 0x21 */ + u16 proto = PPP_IP; /* 0x21 */ struct ipppd *ipppd; ndev->trans_start = jiffies; @@ -1094,10 +1007,9 @@ isdn_ppp_start_xmit(struct sk_buff *skb, struct net_device *ndev) proto = PPP_IPX; /* untested */ break; default: - printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n", + printk(KERN_INFO "isdn_ppp: skipped unsupported protocol: %#x.\n", skb->protocol); - dev_kfree_skb(skb); - goto out; + goto drop; } idev = isdn_net_get_xmit_dev(mlp); @@ -1105,126 +1017,33 @@ isdn_ppp_start_xmit(struct sk_buff *skb, struct net_device *ndev) printk(KERN_INFO "%s: IP frame delayed.\n", ndev->name); goto stop; } - if (!(idev->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */ + ind_ppp = idev->ind_priv; + if (!(ind_ppp->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */ isdn_BUG(); goto stop; } - ipppd = idev->ipppd; + ipppd = ind_ppp->ipppd; idev->huptimer = 0; - /* - * after this line .. requeueing in the device queue is no longer allowed!!! - */ - - if (ipppd->debug & 0x4) - printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len); if (ipppd->debug & 0x40) - isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32, ipppd->unit, -1); + isdn_ppp_frame_log("xmit0", skb->data, skb->len, 256, ipppd->unit, -1); -#ifdef CONFIG_ISDN_PPP_VJ - if (proto == PPP_IP && idev->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */ - struct sk_buff *new_skb; - unsigned short hl; - /* - * we need to reserve enought space in front of - * sk_buff. old call to dev_alloc_skb only reserved - * 16 bytes, now we are looking what the driver want. - */ - hl = isdn_slot_hdrlen(idev->isdn_slot) + IPPP_MAX_HEADER;; - /* - * Note: hl might still be insufficient because the method - * above does not account for a possibible MPPP slave channel - * which had larger HL header space requirements than the - * master. - */ - new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC); - if (new_skb) { - u_char *buf; - int pktlen; - - skb_reserve(new_skb, hl); - new_skb->dev = skb->dev; - skb_put(new_skb, skb->len); - buf = skb->data; - - pktlen = slhc_compress(mlp->slcomp, skb->data, skb->len, new_skb->data, - &buf, !(idev->pppcfg & SC_NO_TCP_CCID)); - - if (buf != skb->data) { - if (new_skb->data != buf) - printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n"); - dev_kfree_skb(skb); - skb = new_skb; - } else { - dev_kfree_skb(new_skb); - } + /* after this line,requeueing is no longer allowed! */ + skb = ippp_vj_compress(idev, skb, &proto); - skb_trim(skb, pktlen); - if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */ - proto = PPP_VJC_COMP; - skb->data[0] ^= SL_TYPE_COMPRESSED_TCP; - } else { - if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP) - proto = PPP_VJC_UNCOMP; - skb->data[0] = (skb->data[0] & 0x0f) | 0x40; - } - } - } -#endif + /* normal (single link) or bundle compression */ + skb = ippp_ccp_compress(inl_ppp->ccp, skb, &proto); - /* - * normal (single link) or bundle compression - */ - skb = ippp_ccp_compress(mlp->ccp, skb, &proto); - - if (ipppd->debug & 0x24) - printk(KERN_DEBUG "xmit2 skb, len %d, proto %04x\n", (int) skb->len, proto); - -#ifdef CONFIG_ISDN_MPP - if (ipt->mpppcfg & SC_MP_PROT) { - /* we get mp_seqno from static isdn_net_local */ - long mp_seqno = ipts->mp_seqno; - ipts->mp_seqno++; - if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) { - unsigned char *data = isdn_ppp_skb_push(&skb, 3); - if(!data) - goto unlock; - mp_seqno &= 0xfff; - data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf); /* (B)egin & (E)ndbit .. */ - data[1] = mp_seqno & 0xff; - data[2] = proto; /* PID compression */ - } else { - unsigned char *data = isdn_ppp_skb_push(&skb, 5); - if(!data) - goto unlock; - data[0] = MP_BEGIN_FRAG | MP_END_FRAG; /* (B)egin & (E)ndbit .. */ - data[1] = (mp_seqno >> 16) & 0xff; /* sequence number: 24bit */ - data[2] = (mp_seqno >> 8) & 0xff; - data[3] = (mp_seqno >> 0) & 0xff; - data[4] = proto; /* PID compression */ - } - proto = PPP_MP; /* MP Protocol, 0x003d */ - } -#endif + if (ipppd->debug & 0x40) + isdn_ppp_frame_log("xmit1", skb->data, skb->len, 32, ipppd->unit, -1); -#if 0 - /* - * 'link in bundle' compression ... - */ - if (ipt->compflags & SC_LINK_COMP_ON) - skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1); -#endif - - isdn_ppp_push_header(idev, skb, proto); - - if (ipppd->debug & 0x40) { - printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len); - isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, ipppd->unit, -1); - } - - isdn_net_writebuf_skb(idev, skb); + ippp_push_proto(ind_ppp, skb, proto); + ippp_mp_xmit(idev, skb, proto); + return 0; - out: + drop: + kfree_skb(skb); + mlp->stats.tx_dropped++; return 0; stop: @@ -1232,483 +1051,21 @@ isdn_ppp_start_xmit(struct sk_buff *skb, struct net_device *ndev) return 1; } -#ifdef CONFIG_ISDN_MPP - -/* this is _not_ rfc1990 header, but something we convert both short and long - * headers to for convinience's sake: - * byte 0 is flags as in rfc1990 - * bytes 1...4 is 24-bit seqence number converted to host byte order - */ -#define MP_HEADER_LEN 5 - -#define MP_LONGSEQ_MASK 0x00ffffff -#define MP_SHORTSEQ_MASK 0x00000fff -#define MP_LONGSEQ_MAX MP_LONGSEQ_MASK -#define MP_SHORTSEQ_MAX MP_SHORTSEQ_MASK -#define MP_LONGSEQ_MAXBIT ((MP_LONGSEQ_MASK+1)>>1) -#define MP_SHORTSEQ_MAXBIT ((MP_SHORTSEQ_MASK+1)>>1) - -/* sequence-wrap safe comparisions (for long sequence)*/ -#define MP_LT(a,b) ((a-b)&MP_LONGSEQ_MAXBIT) -#define MP_LE(a,b) !((b-a)&MP_LONGSEQ_MAXBIT) -#define MP_GT(a,b) ((b-a)&MP_LONGSEQ_MAXBIT) -#define MP_GE(a,b) !((a-b)&MP_LONGSEQ_MAXBIT) - -#define MP_SEQ(f) ((*(u32*)(f->data+1))) -#define MP_FLAGS(f) (f->data[0]) - -static int isdn_ppp_mp_bundle_array_init(void) -{ - int i; - int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); - if( (isdn_ppp_bundle_arr = (ippp_bundle*)kmalloc(sz, - GFP_KERNEL)) == NULL ) - return -ENOMEM; - memset(isdn_ppp_bundle_arr, 0, sz); - for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) - spin_lock_init(&isdn_ppp_bundle_arr[i].lock); - return 0; -} - -static ippp_bundle * isdn_ppp_mp_bundle_alloc(void) -{ - int i; - for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) - if (isdn_ppp_bundle_arr[i].ref_ct <= 0) - return (isdn_ppp_bundle_arr + i); - return NULL; -} - -static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) -{ - isdn_net_dev *idev = lp->netdev; - struct ipppd * is; - - if (idev->ppp_slot < 0) { - printk(KERN_ERR "%s: >ppp_slot(%d) out of range\n", - __FUNCTION__ , idev->ppp_slot); - return -EINVAL; - } - - is = ippp_table[idev->ppp_slot]; - if (add_to) { - if( lp->netdev->pb ) - lp->netdev->pb->ref_ct--; - lp->netdev->pb = add_to; - } else { /* first link in a bundle */ - is->mp_seqno = 0; - if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) - return -ENOMEM; - - lp->netdev->pb->frags = NULL; - lp->netdev->pb->frames = 0; - lp->netdev->pb->seq = LONG_MAX; - } - lp->netdev->pb->ref_ct++; - - is->pppseq = 0; - return 0; -} - -static u32 isdn_ppp_mp_get_seq( int short_seq, - struct sk_buff * skb, u32 last_seq ); -static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, - struct sk_buff * from, struct sk_buff * to ); -static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, - struct sk_buff * from, struct sk_buff * to ); -static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); -static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); - -static void isdn_ppp_mp_receive(isdn_net_local *lp, isdn_net_dev *dev, - struct sk_buff *skb) +void +ippp_xmit(isdn_net_dev *idev, struct sk_buff *skb) { - isdn_net_dev *idev = lp->netdev; - struct ipppd *is; - isdn_net_dev *qdev; - ippp_bundle * mp; - isdn_mppp_stats * stats; - struct sk_buff * newfrag, * frag, * start, *nextf; - u32 newseq, minseq, thisseq; - unsigned long flags; - int slot; - - spin_lock_irqsave(&lp->netdev->pb->lock, flags); - mp = lp->netdev->pb; - stats = &mp->stats; - slot = idev->ppp_slot; - if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR "%s: ppp_slot(%d)\n", - __FUNCTION__, slot); - stats->frame_drops++; - dev_kfree_skb(skb); - spin_unlock_irqrestore(&mp->lock, flags); - return; - } - is = ippp_table[slot]; - if( ++mp->frames > stats->max_queue_len ) - stats->max_queue_len = mp->frames; - - if (is->debug & 0x8) - isdn_ppp_mp_print_recv_pkt(slot, skb); - - newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, - skb, is->pppseq); - - - /* if this packet seq # is less than last already processed one, - * toss it right away, but check for sequence start case first - */ - if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) { - mp->seq = newseq; /* the first packet: required for - * rfc1990 non-compliant clients -- - * prevents constant packet toss */ - } else if( MP_LT(newseq, mp->seq) ) { - stats->frame_drops++; - isdn_ppp_mp_free_skb(mp, skb); - spin_unlock_irqrestore(&mp->lock, flags); - return; - } - - /* find the minimum received sequence number over all links */ - is->pppseq = minseq = newseq; - list_for_each_entry(qdev, &lp->online, online) { - slot = qdev->ppp_slot; - if (slot < 0 || slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n", - __FUNCTION__ ,slot); - } else { - u32 lls = ippp_table[slot]->pppseq; - if (MP_LT(lls, minseq)) - minseq = lls; - } - } - if (MP_LT(minseq, mp->seq)) - minseq = mp->seq; /* can't go beyond already processed - * packets */ - newfrag = skb; - - /* if this new fragment is before the first one, then enqueue it now. */ - if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { - newfrag->next = frag; - mp->frags = frag = newfrag; - newfrag = NULL; - } - - start = MP_FLAGS(frag) & MP_BEGIN_FRAG && - MP_SEQ(frag) == mp->seq ? frag : NULL; - - /* - * main fragment traversing loop - * - * try to accomplish several tasks: - * - insert new fragment into the proper sequence slot (once that's done - * newfrag will be set to NULL) - * - reassemble any complete fragment sequence (non-null 'start' - * indicates there is a continguous sequence present) - * - discard any incomplete sequences that are below minseq -- due - * to the fact that sender always increment sequence number, if there - * is an incomplete sequence below minseq, no new fragments would - * come to complete such sequence and it should be discarded - * - * loop completes when we accomplished the following tasks: - * - new fragment is inserted in the proper sequence ('newfrag' is - * set to NULL) - * - we hit a gap in the sequence, so no reassembly/processing is - * possible ('start' would be set to NULL) - * - * algorightm for this code is derived from code in the book - * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) - */ - while (start != NULL || newfrag != NULL) { - - thisseq = MP_SEQ(frag); - nextf = frag->next; - - /* drop any duplicate fragments */ - if (newfrag != NULL && thisseq == newseq) { - isdn_ppp_mp_free_skb(mp, newfrag); - newfrag = NULL; - } - - /* insert new fragment before next element if possible. */ - if (newfrag != NULL && (nextf == NULL || - MP_LT(newseq, MP_SEQ(nextf)))) { - newfrag->next = nextf; - frag->next = nextf = newfrag; - newfrag = NULL; - } - - if (start != NULL) { - /* check for misplaced start */ - if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { - printk(KERN_WARNING"isdn_mppp(seq %d): new " - "BEGIN flag with no prior END", thisseq); - stats->seqerrs++; - stats->frame_drops++; - start = isdn_ppp_mp_discard(mp, start,frag); - nextf = frag->next; - } - } else if (MP_LE(thisseq, minseq)) { - if (MP_FLAGS(frag) & MP_BEGIN_FRAG) - start = frag; - else { - if (MP_FLAGS(frag) & MP_END_FRAG) - stats->frame_drops++; - if( mp->frags == frag ) - mp->frags = nextf; - isdn_ppp_mp_free_skb(mp, frag); - frag = nextf; - continue; - } - } - - /* if start is non-null and we have end fragment, then - * we have full reassembly sequence -- reassemble - * and process packet now - */ - if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { - minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; - /* Reassemble the packet then dispatch it */ - isdn_ppp_mp_reassembly(lp->netdev, lp, start, nextf); - - start = NULL; - frag = NULL; - - mp->frags = nextf; - } - - /* check if need to update start pointer: if we just - * reassembled the packet and sequence is contiguous - * then next fragment should be the start of new reassembly - * if sequence is contiguous, but we haven't reassembled yet, - * keep going. - * if sequence is not contiguous, either clear everyting - * below low watermark and set start to the next frag or - * clear start ptr. - */ - if (nextf != NULL && - ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { - /* if we just reassembled and the next one is here, - * then start another reassembly. */ - - if (frag == NULL) { - if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) - start = nextf; - else - { - printk(KERN_WARNING"isdn_mppp(seq %d):" - " END flag with no following " - "BEGIN", thisseq); - stats->seqerrs++; - } - } + struct ind_ppp *ind_ppp = idev->ind_priv; + struct ipppd *ipppd = ind_ppp->ipppd; - } else { - if ( nextf != NULL && frag != NULL && - MP_LT(thisseq, minseq)) { - /* we've got a break in the sequence - * and we not at the end yet - * and we did not just reassembled - *(if we did, there wouldn't be anything before) - * and we below the low watermark - * discard all the frames below low watermark - * and start over */ - stats->frame_drops++; - mp->frags = isdn_ppp_mp_discard(mp,start,nextf); - } - /* break in the sequence, no reassembly */ - start = NULL; - } - - frag = nextf; - } /* while -- main loop */ - - if (mp->frags == NULL) - mp->frags = frag; - - /* rather straighforward way to deal with (not very) possible - * queue overflow */ - if (mp->frames > MP_MAX_QUEUE_LEN) { - stats->overflows++; - while (mp->frames > MP_MAX_QUEUE_LEN) { - frag = mp->frags->next; - isdn_ppp_mp_free_skb(mp, mp->frags); - mp->frags = frag; - } - } - spin_unlock_irqrestore(&mp->lock, flags); -} + ippp_push_ac(ind_ppp, skb); -static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) -{ - struct sk_buff * frag = lp->netdev->pb->frags; - struct sk_buff * nextfrag; - while( frag ) { - nextfrag = frag->next; - isdn_ppp_mp_free_skb(lp->netdev->pb, frag); - frag = nextfrag; - } - lp->netdev->pb->frags = NULL; -} - -static u32 isdn_ppp_mp_get_seq( int short_seq, - struct sk_buff * skb, u32 last_seq ) -{ - u32 seq; - int flags = skb->data[0] & (MP_BEGIN_FRAG | MP_END_FRAG); - - if( !short_seq ) - { - seq = ntohl(*(u32*)skb->data) & MP_LONGSEQ_MASK; - skb_push(skb,1); + if (ipppd->debug & 0x40) { + isdn_ppp_frame_log("xmit3", skb->data, skb->len, 32, ipppd->unit, -1); } - else - { - /* convert 12-bit short seq number to 24-bit long one - */ - seq = ntohs(*(u16*)skb->data) & MP_SHORTSEQ_MASK; - /* check for seqence wrap */ - if( !(seq & MP_SHORTSEQ_MAXBIT) && - (last_seq & MP_SHORTSEQ_MAXBIT) && - (unsigned long)last_seq <= MP_LONGSEQ_MAX ) - seq |= (last_seq + MP_SHORTSEQ_MAX+1) & - (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK); - else - seq |= last_seq & (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK); - - skb_push(skb, 3); /* put converted seqence back in skb */ - } - *(u32*)(skb->data+1) = seq; /* put seqence back in _host_ byte - * order */ - skb->data[0] = flags; /* restore flags */ - return seq; -} - -struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, - struct sk_buff * from, struct sk_buff * to ) -{ - if( from ) - while (from != to) { - struct sk_buff * next = from->next; - isdn_ppp_mp_free_skb(mp, from); - from = next; - } - return from; -} - -void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, - struct sk_buff * from, struct sk_buff * to ) -{ - isdn_net_dev *idev = lp->netdev; - ippp_bundle * mp = net_dev->pb; - int proto; - struct sk_buff * skb; - unsigned int tot_len; - - if (idev->ppp_slot < 0 || idev->ppp_slot > ISDN_MAX_CHANNELS) { - printk(KERN_ERR "%s: ppp_slot(%d) out of range\n", - __FUNCTION__ , idev->ppp_slot); - return; - } - if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { - if( ippp_table[idev->ppp_slot]->debug & 0x40 ) - printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " - "len %d\n", MP_SEQ(from), from->len ); - skb = from; - skb_pull(skb, MP_HEADER_LEN); - mp->frames--; - } else { - struct sk_buff * frag; - int n; - - for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) - tot_len += frag->len - MP_HEADER_LEN; - - if( ippp_table[idev->ppp_slot]->debug & 0x40 ) - printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " - "to %d, len %d\n", MP_SEQ(from), - (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); - if( (skb = dev_alloc_skb(tot_len)) == NULL ) { - printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " - "of size %d\n", tot_len); - isdn_ppp_mp_discard(mp, from, to); - return; - } - - while( from != to ) { - unsigned int len = from->len - MP_HEADER_LEN; - - memcpy(skb_put(skb,len), from->data+MP_HEADER_LEN, len); - frag = from->next; - isdn_ppp_mp_free_skb(mp, from); - from = frag; - } - } - proto = isdn_ppp_strip_proto(skb); - isdn_ppp_push_higher(lp, idev, skb, proto); -} - -static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb) -{ - dev_kfree_skb(skb); - mp->frames--; -} - -static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ) -{ - printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n", - slot, (int) skb->len, - (int) skb->data[0], (int) skb->data[1], (int) skb->data[2], - (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]); + isdn_net_writebuf_skb(idev, skb); } -static int -isdn_ppp_bundle(struct ipppd *is, int unit) -{ - char ifn[IFNAMSIZ + 1]; - isdn_net_dev *p; - isdn_net_dev *idev, *nidev; - int rc; - unsigned long flags; - - sprintf(ifn, "ippp%d", unit); - p = isdn_net_findif(ifn); - if (!p) { - printk(KERN_ERR "ippp_bundle: cannot find %s\n", ifn); - return -EINVAL; - } - - spin_lock_irqsave(&p->pb->lock, flags); - - nidev = is->idev; - idev = list_entry(p->mlp->online.next, isdn_net_dev, online); - if( nidev->ppp_slot < 0 || nidev->ppp_slot >= ISDN_MAX_CHANNELS || - idev ->ppp_slot < 0 || idev ->ppp_slot >= ISDN_MAX_CHANNELS ) { - printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n", - nidev->ppp_slot < 0 || nidev->ppp_slot >= ISDN_MAX_CHANNELS ? - nidev->ppp_slot : idev->ppp_slot ); - rc = -EINVAL; - goto out; - } - - isdn_net_add_to_bundle(p->mlp, nidev); - - ippp_table[nidev->ppp_slot]->unit = ippp_table[idev->ppp_slot]->unit; - - /* maybe also SC_CCP stuff */ - ippp_table[nidev->ppp_slot]->pppcfg |= ippp_table[idev->ppp_slot]->pppcfg & - (SC_ENABLE_IP | SC_NO_TCP_CCID | SC_REJ_COMP_TCP); - ippp_table[nidev->ppp_slot]->mpppcfg |= ippp_table[idev->ppp_slot]->mpppcfg & - (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ); - rc = isdn_ppp_mp_init(nidev->mlp, p->pb); -out: - spin_unlock_irqrestore(&p->pb->lock, flags); - return rc; -} - -#endif /* CONFIG_ISDN_MPP */ - /* * network device ioctl handlers */ @@ -1718,6 +1075,7 @@ isdn_ppp_dev_ioctl_stats(struct ifreq *ifr, struct net_device *dev) { struct ppp_stats *res, t; isdn_net_local *lp = (isdn_net_local *) dev->priv; + struct inl_ppp *inl_ppp = lp->inl_priv; struct slcompress *slcomp; int err; @@ -1738,7 +1096,7 @@ isdn_ppp_dev_ioctl_stats(struct ifreq *ifr, struct net_device *dev) t.p.ppp_obytes = lp->stats.tx_bytes; t.p.ppp_oerrors = lp->stats.tx_errors; #ifdef CONFIG_ISDN_PPP_VJ - slcomp = lp->slcomp; + slcomp = inl_ppp->slcomp; if (slcomp) { t.vj.vjs_packets = slcomp->sls_o_compressed + slcomp->sls_o_uncompressed; t.vj.vjs_compressed = slcomp->sls_o_compressed; @@ -1810,61 +1168,6 @@ isdn_ppp_if_get_unit(char *name) return unit; } - -int -isdn_ppp_dial_slave(char *name) -{ -#ifdef CONFIG_ISDN_MPP - isdn_net_dev *idev; - isdn_net_dev *sdev; - - idev = isdn_net_findif(name); - if (!idev) - return 1; - - if (!isdn_net_bound(idev)) - return 5; - - sdev = idev->slave; - while (sdev) { - if (!isdn_net_bound(sdev)) - break; - sdev = sdev->slave; - } - if (!sdev) - return 2; - - isdn_net_dial_req(sdev); - return 0; -#else - return -1; -#endif -} - -int -isdn_ppp_hangup_slave(char *name) -{ -#ifdef CONFIG_ISDN_MPP - isdn_net_dev *idev, *sdev; - - idev = isdn_net_findif(name); - if (!idev) - return 1; - - if (!isdn_net_bound(idev)) - return 5; - - sdev = idev->slave; - if (!sdev || !isdn_net_bound(sdev)) - return 2; - - isdn_net_hangup(sdev); - return 0; -#else - return -1; -#endif -} - /* * PPP compression stuff */ @@ -1876,21 +1179,24 @@ isdn_ppp_hangup_slave(char *name) static void isdn_ppp_dev_kick_up(void *priv) { isdn_net_dev *idev = priv; + struct ind_ppp *ind_ppp = idev->ind_priv; - ipppd_queue_read(idev->ipppd, PPP_COMPFRAG, NULL, 0); + ipppd_queue_read(ind_ppp->ipppd, PPP_COMPFRAG, NULL, 0); } static void isdn_ppp_lp_kick_up(void *priv) { isdn_net_local *lp = priv; isdn_net_dev *idev; + struct ind_ppp *ind_ppp; if (list_empty(&lp->online)) { isdn_BUG(); return; } idev = list_entry(lp->online.next, isdn_net_dev, online); - ipppd_queue_read(idev->ipppd, PPP_COMP, NULL, 0); + ind_ppp = idev->ind_priv; + ipppd_queue_read(ind_ppp->ipppd, PPP_COMP, NULL, 0); } /* Send a CCP Reset-Request or Reset-Ack directly from the kernel. */ @@ -1909,7 +1215,7 @@ __isdn_ppp_alloc_skb(isdn_net_dev *idev, int len, unsigned int gfp_mask) return skb; } -static struct sk_buff * +struct sk_buff * isdn_ppp_dev_alloc_skb(void *priv, int len, int gfp_mask) { isdn_net_dev *idev = priv; @@ -1932,46 +1238,31 @@ isdn_ppp_lp_alloc_skb(void *priv, int len, int gfp_mask) } static void -isdn_ppp_dev_push_header(void *priv, struct sk_buff *skb, u16 proto) -{ - isdn_net_dev *idev = priv; - - isdn_ppp_push_header(idev, skb, proto); -} - -static void -isdn_ppp_lp_push_header(void *priv, struct sk_buff *skb, u16 proto) -{ - isdn_net_local *lp = priv; - isdn_net_dev *idev; - - if (list_empty(&lp->online)) { - isdn_BUG(); - return; - } - idev = list_entry(lp->online.next, isdn_net_dev, online); - isdn_ppp_push_header(idev, skb, proto); -} - -static void -isdn_ppp_dev_xmit(void *priv, struct sk_buff *skb) +isdn_ppp_dev_xmit(void *priv, struct sk_buff *skb, u16 proto) { isdn_net_dev *idev = priv; + struct ind_ppp *ind_ppp = idev->ind_priv; + ippp_push_proto(ind_ppp, skb, proto); + ippp_push_ac(ind_ppp, skb); isdn_net_write_super(idev, skb); } static void -isdn_ppp_lp_xmit(void *priv, struct sk_buff *skb) +isdn_ppp_lp_xmit(void *priv, struct sk_buff *skb, u16 proto) { isdn_net_local *lp = priv; isdn_net_dev *idev; + struct ind_ppp *ind_ppp; if (list_empty(&lp->online)) { isdn_BUG(); return; } idev = list_entry(lp->online.next, isdn_net_dev, online); + ind_ppp = idev->ind_priv; + ippp_push_proto(ind_ppp, skb, proto); + ippp_push_ac(ind_ppp, skb); isdn_net_write_super(idev, skb); } @@ -1979,13 +1270,15 @@ static int isdn_ppp_set_compressor(isdn_net_dev *idev, struct isdn_ppp_comp_data *data) { struct ippp_ccp *ccp; + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + struct ind_ppp *ind_ppp = idev->ind_priv; if (data->flags & IPPP_COMP_FLAG_LINK) - ccp = idev->ccp; + ccp = ind_ppp->ccp; else - ccp = idev->mlp->ccp; + ccp = inl_ppp->ccp; - return ippp_ccp_set_compressor(ccp, idev->ipppd->unit, data); + return ippp_ccp_set_compressor(ccp, ind_ppp->ipppd->unit, data); } // ISDN_NET_ENCAP_SYNCPPP @@ -1994,34 +1287,48 @@ isdn_ppp_set_compressor(isdn_net_dev *idev, struct isdn_ppp_comp_data *data) static int isdn_ppp_open(isdn_net_local *lp) { - lp->mpppcfg = 0; /* mppp configuration */ - lp->mp_seqno = 0; /* MP sequence number */ + struct inl_ppp *inl_ppp; -#ifdef CONFIG_ISDN_PPP_VJ - lp->slcomp = slhc_init(16, 16); -#endif - lp->ccp = ippp_ccp_alloc(); - if (!lp->ccp) + inl_ppp = kmalloc(sizeof(*inl_ppp), GFP_KERNEL); + if (!inl_ppp) return -ENOMEM; - lp->ccp->proto = PPP_COMP; - lp->ccp->priv = lp; - lp->ccp->alloc_skb = isdn_ppp_lp_alloc_skb; - lp->ccp->push_header = isdn_ppp_lp_push_header; - lp->ccp->xmit = isdn_ppp_lp_xmit; - lp->ccp->kick_up = isdn_ppp_lp_kick_up; + lp->inl_priv = inl_ppp; + + inl_ppp->slcomp = ippp_vj_alloc(); + if (!inl_ppp->slcomp) + goto err; + + inl_ppp->ccp = ippp_ccp_alloc(); + if (!inl_ppp->ccp) + goto err_vj; + + inl_ppp->ccp->proto = PPP_COMP; + inl_ppp->ccp->priv = lp; + inl_ppp->ccp->alloc_skb = isdn_ppp_lp_alloc_skb; + inl_ppp->ccp->xmit = isdn_ppp_lp_xmit; + inl_ppp->ccp->kick_up = isdn_ppp_lp_kick_up; + return 0; + + err_vj: + ippp_vj_free(inl_ppp->slcomp); + err: + kfree(inl_ppp); + lp->inl_priv = NULL; + return -ENOMEM; } static void isdn_ppp_close(isdn_net_local *lp) { -#ifdef CONFIG_ISDN_PPP_VJ - slhc_free(lp->slcomp); - lp->slcomp = NULL; -#endif - ippp_ccp_free(lp->ccp); - lp->ccp = NULL; + struct inl_ppp *inl_ppp = lp->inl_priv; + + ippp_ccp_free(inl_ppp->ccp); + ippp_vj_free(inl_ppp->slcomp); + + kfree(inl_ppp); + lp->inl_priv = NULL; } struct isdn_netif_ops isdn_ppp_ops = { @@ -2037,3 +1344,4 @@ struct isdn_netif_ops isdn_ppp_ops = { .open = isdn_ppp_open, .close = isdn_ppp_close, }; + diff --git a/drivers/isdn/i4l/isdn_ppp.h b/drivers/isdn/i4l/isdn_ppp.h index 20745b31ef1d..ea7b8eb0aeef 100644 --- a/drivers/isdn/i4l/isdn_ppp.h +++ b/drivers/isdn/i4l/isdn_ppp.h @@ -1,16 +1,13 @@ -/* $Id: isdn_ppp.h,v 1.17.6.1 2001/09/23 22:24:32 kai Exp $ - * - * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel). +/* Linux ISDN subsystem, functions for synchronous PPP (linklevel). * * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ -#include <linux/ppp_defs.h> /* for PPP_PROTOCOL */ -#include <linux/isdn_ppp.h> /* for isdn_ppp info */ +#include "isdn_net_lib.h" extern struct file_operations isdn_ppp_fops; extern struct isdn_netif_ops isdn_ppp_ops; @@ -20,10 +17,41 @@ void isdn_ppp_cleanup(void); int isdn_ppp_dial_slave(char *); int isdn_ppp_hangup_slave(char *); +struct inl_ppp { + unsigned long debug; + struct slcompress *slcomp; + struct ippp_ccp *ccp; /* CCP for this channel */ + unsigned int mp_cfg; + struct sk_buff_head mp_frags; /* fragments list */ + u32 mp_rxseq; /* last processed packet seq # */ + u32 mp_txseq; /* current tx seq # */ +}; + +struct ind_ppp { + struct ipppd *ipppd; /* /dev/ipppX which controls us */ + unsigned int pppcfg; + unsigned long debug; + struct ippp_ccp *ccp; /* CCP for this channel (multilink) */ + u32 mp_rxseq; /* last seq no seen on this channel */ +}; + void isdn_ppp_frame_log(char *info, char *data, int len, int maxlen, int unit, int slot); + int -isdn_ppp_strip_proto(struct sk_buff *skb); +isdn_ppp_strip_proto(struct sk_buff *skb, u16 *proto); + +void +ippp_push_proto(struct ind_ppp *ind_ppp, struct sk_buff *skb, u16 proto); + +void +ippp_xmit(isdn_net_dev *idev, struct sk_buff *skb); + +void +ippp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto); + +struct sk_buff * +isdn_ppp_dev_alloc_skb(void *priv, int len, int gfp_mask); #define IPPP_MAX_HEADER 10 diff --git a/drivers/isdn/i4l/isdn_ppp_ccp.c b/drivers/isdn/i4l/isdn_ppp_ccp.c index ab573e7a6376..5a8f2dc7e01b 100644 --- a/drivers/isdn/i4l/isdn_ppp_ccp.c +++ b/drivers/isdn/i4l/isdn_ppp_ccp.c @@ -1,10 +1,50 @@ +/* Linux ISDN subsystem, PPP CCP support + * + * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ #include "isdn_ppp_ccp.h" #include "isdn_common.h" -#include "isdn_net.h" +#include "isdn_net_lib.h" #include "isdn_ppp.h" #include <linux/ppp-comp.h> +/* ====================================================================== */ +enum ippp_ccp_reset_states { + CCPResetIdle, + CCPResetSentReq, + CCPResetRcvdReq, + CCPResetSentAck, + CCPResetRcvdAck +}; + +struct ippp_ccp_reset_state { + enum ippp_ccp_reset_states state;/* State of this transaction */ + struct ippp_ccp *ccp; /* Backlink */ + unsigned char id; /* id index */ + unsigned char ta:1; /* The timer is active (flag) */ + unsigned char expra:1; /* We expect a ResetAck at all */ + int dlen; /* Databytes stored in data */ + struct timer_list timer; /* For timeouts/retries */ + /* This is a hack but seems sufficient for the moment. We do not want + to have this be yet another allocation for some bytes, it is more + memory management overhead than the whole mess is worth. */ + unsigned char data[IPPP_RESET_MAXDATABYTES]; +}; + +/* The data structure keeping track of the currently outstanding CCP Reset + transactions. */ +struct ippp_ccp_reset { + struct ippp_ccp_reset_state *rs[256]; /* One per possible id */ + unsigned char lastid; /* Last id allocated */ +}; + /* In-kernel handling of CCP Reset-Request and Reset-Ack is necessary, but absolutely nontrivial. The most abstruse problem we are facing is that the generation, reception and all the handling of timeouts and @@ -62,7 +102,6 @@ do_xmit_reset(struct ippp_ccp *ccp, unsigned char code, unsigned char id, u16 proto = ccp->proto == PPP_COMP ? PPP_CCP : PPP_CCPFRAG; skb = ccp->alloc_skb(ccp->priv, 4 + len, GFP_ATOMIC); - ccp->push_header(ccp->priv, skb, proto); p = skb_put(skb, 4); p += put_u8 (p, code); @@ -74,7 +113,7 @@ do_xmit_reset(struct ippp_ccp *ccp, unsigned char code, unsigned char id, isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, -1, -1); - ccp->xmit(ccp->priv, skb); + ccp->xmit(ccp->priv, skb, proto); } /* The timer callback function which is called when a ResetReq has timed out, @@ -250,7 +289,7 @@ ippp_ccp_get_flags(struct ippp_ccp *ccp) * and a new skb otherwise */ struct sk_buff * -ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb_in, int *proto) +ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb_in, u16 *proto) { struct sk_buff *skb; @@ -260,7 +299,7 @@ ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb_in, int *proto) return skb_in; } /* we do not compress control protocols */ - if (*proto < 0 || *proto > 0x3fff) { + if (*proto > 0x3fff) { return skb_in; } if (!ccp->compressor || !ccp->comp_stat) { @@ -294,7 +333,7 @@ ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb_in, int *proto) */ struct sk_buff * -ippp_ccp_decompress(struct ippp_ccp *ccp, struct sk_buff *skb_in, int *proto) +ippp_ccp_decompress(struct ippp_ccp *ccp, struct sk_buff *skb_in, u16 *proto) { struct sk_buff *skb; struct isdn_ppp_resetparams rsparm; @@ -344,8 +383,7 @@ ippp_ccp_decompress(struct ippp_ccp *ccp, struct sk_buff *skb_in, int *proto) kfree_skb(skb); return NULL; } - *proto = isdn_ppp_strip_proto(skb); - if (*proto < 0) { + if (isdn_ppp_strip_proto(skb, proto)) { kfree_skb(skb); return NULL; } diff --git a/drivers/isdn/i4l/isdn_ppp_ccp.h b/drivers/isdn/i4l/isdn_ppp_ccp.h index d9ece852d24f..7d4a89639818 100644 --- a/drivers/isdn/i4l/isdn_ppp_ccp.h +++ b/drivers/isdn/i4l/isdn_ppp_ccp.h @@ -1,3 +1,13 @@ +/* Linux ISDN subsystem, PPP CCP support + * + * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ #include <linux/kernel.h> #include <linux/isdn_ppp.h> @@ -16,7 +26,7 @@ */ struct ippp_ccp { - int proto; + u16 proto; struct isdn_ppp_compressor *compressor; struct isdn_ppp_compressor *decompressor; void *comp_stat; @@ -26,9 +36,8 @@ struct ippp_ccp { int mru; int debug; void *priv; - void (*xmit)(void *priv, struct sk_buff *skb); + void (*xmit)(void *priv, struct sk_buff *skb, u16 proto); void (*kick_up)(void *priv); - void (*push_header)(void *priv, struct sk_buff *skb, u16); struct sk_buff *(*alloc_skb)(void *priv, int len, int gfp_mask); }; @@ -45,10 +54,10 @@ unsigned int ippp_ccp_get_flags(struct ippp_ccp *ccp); struct sk_buff * -ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb, int *proto); +ippp_ccp_compress(struct ippp_ccp *ccp, struct sk_buff *skb, u16 *proto); struct sk_buff * -ippp_ccp_decompress(struct ippp_ccp *ccp, struct sk_buff *skb, int *proto); +ippp_ccp_decompress(struct ippp_ccp *ccp, struct sk_buff *skb, u16 *proto); void ippp_ccp_send_ccp(struct ippp_ccp *ccp, struct sk_buff *skb); diff --git a/drivers/isdn/i4l/isdn_ppp_mp.c b/drivers/isdn/i4l/isdn_ppp_mp.c new file mode 100644 index 000000000000..e0a702e0973a --- /dev/null +++ b/drivers/isdn/i4l/isdn_ppp_mp.c @@ -0,0 +1,352 @@ +/* Linux ISDN subsystem, PPP CCP support + * + * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include "isdn_ppp_mp.h" +#include "isdn_ppp_ccp.h" +#include "isdn_common.h" +#include "isdn_net_lib.h" +#include "isdn_ppp.h" + +/* ====================================================================== */ + +#define MP_END_FRAG 0x40 +#define MP_BEGIN_FRAG 0x80 + +#define MP_MAX_QUEUE_LEN 16 + +/* ====================================================================== */ + +int +ippp_mp_bind(isdn_net_dev *idev) +{ + struct ind_ppp *ind_ppp = idev->ind_priv; + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + + /* seq no last seen, maybe set to bundle min, when joining? */ + ind_ppp->mp_rxseq = 0; + + if (!list_empty(&idev->mlp->online)) + return 0; + + /* first channel for this link, do some setup */ + + inl_ppp->mp_cfg = 0; /* MPPP configuration */ + inl_ppp->mp_txseq = 0; /* MPPP tx sequence number */ + inl_ppp->mp_rxseq = (u32) -1; + skb_queue_head_init(&inl_ppp->mp_frags); + + return 0; +} + +int +ippp_mp_bundle(isdn_net_dev *idev, int unit) +{ + isdn_net_local *lp = idev->mlp; + char ifn[IFNAMSIZ + 1]; + isdn_net_dev *n_idev; + struct ind_ppp *ind_ppp; + + printk(KERN_DEBUG "%s: %s: slave unit: %d\n", + __FUNCTION__, idev->name, unit); + + sprintf(ifn, "ippp%d", unit); + list_for_each_entry(n_idev, &lp->slaves, slaves) { + if (strcmp(n_idev->name, ifn) == 0) + goto found; + } + + printk(KERN_INFO "%s: cannot find %s\n", __FUNCTION__, ifn); + return -ENODEV; + + found: + ind_ppp = n_idev->ind_priv; + if (!ind_ppp->ipppd) { + printk(KERN_INFO "%s: no ipppd?\n", __FUNCTION__); + return -ENXIO; + } + ind_ppp->pppcfg |= SC_ENABLE_IP; + isdn_net_online(n_idev); + + return 0; +} + +void +ippp_mp_disconnected(isdn_net_dev *idev) +{ + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + + if (!list_empty(&idev->mlp->online)) + return; + + /* we're the last link going down */ + skb_queue_purge(&inl_ppp->mp_frags); +} + +void +ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +{ + struct ind_ppp *ind_ppp = idev->ind_priv; + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + unsigned char *p; + long txseq; + + if (!(inl_ppp->mp_cfg & SC_MP_PROT)) { + return ippp_xmit(idev, skb); + } + + /* we could do something smarter than just sending + * the complete packet as fragment... */ + + txseq = inl_ppp->mp_txseq++; + + if (inl_ppp->mp_cfg & SC_OUT_SHORT_SEQ) { + /* sequence number: 12bit */ + p = skb_push(skb, 2); + p[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((txseq >> 8) & 0xf); + p[1] = txseq & 0xff; + } else { + /* sequence number: 24bit */ + p = skb_push(skb, 4); + p[0] = MP_BEGIN_FRAG | MP_END_FRAG; + p[1] = (txseq >> 16) & 0xff; + p[2] = (txseq >> 8) & 0xff; + p[3] = (txseq >> 0) & 0xff; + } + proto = PPP_MP; + skb = ippp_ccp_compress(ind_ppp->ccp, skb, &proto); + ippp_push_proto(ind_ppp, skb, proto); + ippp_xmit(idev, skb); +} + +static void mp_receive(isdn_net_dev *idev, struct sk_buff *skb); + +void +ippp_mp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +{ + struct ind_ppp *ind_ppp = idev->ind_priv; + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + + if (inl_ppp->mp_cfg & SC_REJ_MP_PROT) + goto out; + + skb = ippp_ccp_decompress(ind_ppp->ccp, skb, &proto); + if (!skb) + goto drop; + + if (proto == PPP_MP) + return mp_receive(idev, skb); + + out: + return ippp_receive(idev, skb, proto); + + drop: + idev->mlp->stats.rx_errors++; + kfree_skb(skb); +} + +#define MP_LONGSEQ_MASK 0x00ffffff +#define MP_SHORTSEQ_MASK 0x00000fff +#define MP_LONGSEQ_MAX MP_LONGSEQ_MASK +#define MP_SHORTSEQ_MAX MP_SHORTSEQ_MASK +#define MP_LONGSEQ_MAXBIT ((MP_LONGSEQ_MASK+1)>>1) +#define MP_SHORTSEQ_MAXBIT ((MP_SHORTSEQ_MASK+1)>>1) + +/* sequence-wrap safe comparisions (for long sequence)*/ +#define MP_LT(a,b) ((a-b)&MP_LONGSEQ_MAXBIT) +#define MP_LE(a,b) !((b-a)&MP_LONGSEQ_MAXBIT) +#define MP_GT(a,b) ((b-a)&MP_LONGSEQ_MAXBIT) +#define MP_GE(a,b) !((a-b)&MP_LONGSEQ_MAXBIT) + +#define MP_SEQUENCE(skb) (skb)->priority +#define MP_FLAGS(skb) (skb)->cb[0] + +static u32 +get_seq(struct sk_buff *skb, u32 last_seq, int short_seq) +{ + u32 seq; + u16 shseq; + u8 flags; + int delta; + + get_u8(skb->data, &flags); + if (short_seq) { + /* convert 12-bit short seq number to 24-bit long one */ + get_u16(skb->data, &shseq); + delta = (shseq & MP_SHORTSEQ_MASK) - + (last_seq & MP_SHORTSEQ_MASK); + /* check for seqence wrap */ + if (delta < 0) + delta += MP_SHORTSEQ_MAX + 1; + + seq = last_seq + delta; + skb_pull(skb, 2); + } else { + get_u32(skb->data, &seq); + skb_pull(skb, 4); + } + seq &= MP_LONGSEQ_MASK; + MP_SEQUENCE(skb) = seq; + MP_FLAGS(skb) = flags; + return seq; +} + +static int +mp_insert_frag(struct sk_buff_head *frags, struct sk_buff *skb) +{ + struct sk_buff *p; + + /* If our queue of not yet reassembled fragments grows too + large, throw away the oldest fragment */ + if (skb_queue_len(frags) > MP_MAX_QUEUE_LEN) + kfree_skb(skb_dequeue(frags)); + + for (p = frags->next; p != (struct sk_buff *) frags; p = p->next) { + if (MP_LE(MP_SEQUENCE(skb), MP_SEQUENCE(p))) + break; + } + /* duplicate ? */ + if (MP_SEQUENCE(skb) == MP_SEQUENCE(p)) + return -EBUSY; + + __skb_insert(skb, p->prev, p, frags); + return 0; +} + +struct sk_buff * +mp_complete_seq(isdn_net_local *lp, struct sk_buff *b, struct sk_buff *e) +{ + struct sk_buff *p, *n, *skb; + int len = 0; + + if (b->next == e) { + /* sequence with only one frag */ + skb_unlink(b); + return b; + } + for (p = b, n = p->next; p != e; p = n, n = p->next ) { + len += p->len; + } + // FIXME check against mrru? + skb = dev_alloc_skb(len); + if (!skb) + lp->stats.rx_errors++; + + for (p = b, n = p->next; p != e; p = n, n = p->next ) { + if (skb) + memcpy(skb_put(skb, p->len), p->data, p->len); + + skb_unlink(p); + kfree_skb(p); + } + return skb; +} + +struct sk_buff * +mp_reassemble(isdn_net_local *lp) +{ + struct inl_ppp *inl_ppp = lp->inl_priv; + struct sk_buff_head *frags = &inl_ppp->mp_frags; + struct sk_buff *p, *n, *pp, *start; + u32 min_seq = inl_ppp->mp_rxseq; + u32 next_seq = 0; + + again: + start = NULL; + for (p = frags->next, n = p->next; p != (struct sk_buff *) frags; p = n, n = p->next ) { + if (!start) { + if (MP_FLAGS(p) & MP_BEGIN_FRAG) { + start = p; + next_seq = MP_SEQUENCE(p); + } else { + /* start frag is missing */ + goto frag_missing; + } + } + /* we've seen the first fragment of this series */ + if (MP_SEQUENCE(p) != next_seq) { + /* previous frag is missing */ + goto frag_missing; + } + if (MP_FLAGS(p) & MP_END_FRAG) { + /* we got a full sequence */ + return mp_complete_seq(lp, start, p->next); + } + next_seq = MP_SEQUENCE(p) + 1; + } + return NULL; + + frag_missing: + if (MP_SEQUENCE(p) - 1 > min_seq) + /* may come later */ + return NULL; + + /* for all fragments up to p */ + p = p->next; + for (pp = frags->next, n = pp->next; pp != p; pp = n, n = pp->next ) { + skb_unlink(pp); + kfree_skb(pp); + lp->stats.rx_errors++; + } + goto again; + +} + +static void +mp_receive(isdn_net_dev *idev, struct sk_buff *skb) +{ + isdn_net_local *lp = idev->mlp; + struct inl_ppp *inl_ppp = lp->inl_priv; + struct ind_ppp *ind_ppp = idev->ind_priv; + isdn_net_dev *qdev; + struct sk_buff_head *frags = &inl_ppp->mp_frags; + u32 seq; + u16 proto; + + if (skb->len < (inl_ppp->mp_cfg & SC_IN_SHORT_SEQ ? 2 : 4)) + goto drop; + + seq = get_seq(skb, ind_ppp->mp_rxseq, inl_ppp->mp_cfg & SC_IN_SHORT_SEQ); + ind_ppp->mp_rxseq = seq; + + if (inl_ppp->mp_rxseq == (u32) -1) { + /* first packet */ + inl_ppp->mp_rxseq = seq; + } + if (MP_LT(seq, inl_ppp->mp_rxseq)) { + goto drop; + } + /* Find the minimum sequence number received over all channels. + * No fragments with numbers lower than this will arrive later. */ + inl_ppp->mp_rxseq = seq; + list_for_each_entry(qdev, &lp->online, online) { + struct ind_ppp *ind_ppp = qdev->ind_priv; + if (MP_LT(ind_ppp->mp_rxseq, inl_ppp->mp_rxseq)) + inl_ppp->mp_rxseq = ind_ppp->mp_rxseq; + } + + /* Insert the skb into the list of received fragments, ordered by + * sequence number */ + if (mp_insert_frag(frags, skb)) + goto drop; + + while ((skb = mp_reassemble(lp))) { + if (isdn_ppp_strip_proto(skb, &proto)) { + kfree_skb(skb); + continue; + } + ippp_receive(idev, skb, proto); + } + return; + + drop: + lp->stats.rx_errors++; + kfree_skb(skb); +} diff --git a/drivers/isdn/i4l/isdn_ppp_mp.h b/drivers/isdn/i4l/isdn_ppp_mp.h new file mode 100644 index 000000000000..e684edebcd07 --- /dev/null +++ b/drivers/isdn/i4l/isdn_ppp_mp.h @@ -0,0 +1,58 @@ +/* Linux ISDN subsystem, PPP CCP support + * + * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de) + * 1995,96 by Thinking Objects Software GmbH Wuerzburg + * 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef __ISDN_PPP_MP_H__ +#define __ISDN_PPP_MP_H__ + +#include "isdn_net_lib.h" + +#ifdef CONFIG_ISDN_MPP + +int ippp_mp_bind(isdn_net_dev *idev); +void ippp_mp_disconnected(isdn_net_dev *idev); +int ippp_mp_bundle(isdn_net_dev *idev, int val); +void ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto); +void ippp_mp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto); + +#else + +static inline int +ippp_mp_bind(isdn_net_dev *idev) +{ + return 0; +} + +static void +ippp_mp_disconnected(isdn_net_dev *idev) +{ +} + +static inline int +ippp_mp_bundle(isdn_net_dev *idev, int val) +{ + return -EINVAL; +} + +static inline void +ippp_mp_xmit(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +{ + ippp_xmit(idev, skb, proto); +} + +static inline void +ippp_mp_receive(isdn_net_dev *idev, struct sk_buff *skb, u16 proto) +{ + ippp_receive(idev, skb, proto); +} + +#endif + +#endif diff --git a/drivers/isdn/i4l/isdn_ppp_vj.c b/drivers/isdn/i4l/isdn_ppp_vj.c new file mode 100644 index 000000000000..ff48fa7f35e2 --- /dev/null +++ b/drivers/isdn/i4l/isdn_ppp_vj.c @@ -0,0 +1,128 @@ +/* Linux ISDN subsystem, PPP VJ header compression + * + * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include "isdn_ppp_vj.h" +#include "isdn_common.h" +#include "isdn_net_lib.h" +#include "isdn_ppp.h" + +struct slcompress * +ippp_vj_alloc(void) +{ + return slhc_init(16, 16); +} + +void +ippp_vj_free(struct slcompress *slcomp) +{ + slhc_free(slcomp); +} + +int +ippp_vj_set_maxcid(isdn_net_dev *idev, int val) +{ + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + struct slcompress *sltmp; + + sltmp = slhc_init(16, val + 1); + if (!sltmp) + return -ENOMEM; + + if (inl_ppp->slcomp) + slhc_free(inl_ppp->slcomp); + + inl_ppp->slcomp = sltmp; + return 0; +} + +void +ippp_vj_decompress(isdn_net_dev *idev, struct sk_buff *skb_old, u16 proto) +{ + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + struct slcompress *slcomp = inl_ppp->slcomp; + struct sk_buff *skb; + int len; + + switch (proto) { + case PPP_VJC_UNCOMP: + if (slhc_remember(slcomp, skb_old->data, skb_old->len) <= 0) + goto drop; + + skb = skb_old; + break; + case PPP_VJC_COMP: + skb = dev_alloc_skb(skb_old->len + 128); + if (!skb) + goto drop; + + memcpy(skb->data, skb_old->data, skb_old->len); + len = slhc_uncompress(slcomp, skb->data, skb_old->len); + if (len < 0) + goto drop_both; + + skb_put(skb, len); + kfree_skb(skb_old); + break; + default: + isdn_BUG(); + goto drop; + } + isdn_netif_rx(idev, skb, htons(ETH_P_IP)); + return; + + drop_both: + kfree_skb(skb); + drop: + kfree_skb(skb_old); + idev->mlp->stats.rx_dropped++; +} + +struct sk_buff * +ippp_vj_compress(isdn_net_dev *idev, struct sk_buff *skb_old, u16 *proto) +{ + struct inl_ppp *inl_ppp = idev->mlp->inl_priv; + struct ind_ppp *ind_ppp = idev->ind_priv; + struct slcompress *slcomp = inl_ppp->slcomp; + struct sk_buff *skb; + unsigned char *buf; + int len; + + if (!(ind_ppp->pppcfg & SC_COMP_TCP) || *proto != PPP_IP) + return skb_old; + + skb = isdn_ppp_dev_alloc_skb(idev, skb_old->len, GFP_ATOMIC); + if (!skb) + return skb_old; + + skb_put(skb, skb_old->len); + buf = skb_old->data; + // FIXME flag should be per bundle + len = slhc_compress(slcomp, skb_old->data, skb_old->len, skb->data, + &buf, !(ind_ppp->pppcfg & SC_NO_TCP_CCID)); + + if (buf == skb_old->data) { + kfree_skb(skb); + skb = skb_old; + } else { + kfree_skb(skb_old); + } + skb_trim(skb, len); + + /* cslip style -> PPP */ + if ((skb->data[0] & SL_TYPE_COMPRESSED_TCP) == SL_TYPE_COMPRESSED_TCP) { + skb->data[0] &= ~SL_TYPE_COMPRESSED_TCP; + *proto = PPP_VJC_COMP; + } else if ((skb->data[0] & SL_TYPE_UNCOMPRESSED_TCP) == SL_TYPE_UNCOMPRESSED_TCP) { + skb->data[0] &= ~SL_TYPE_UNCOMPRESSED_TCP; + skb->data[0] |= SL_TYPE_IP; + *proto = PPP_VJC_UNCOMP; + } + return skb; +} + diff --git a/drivers/isdn/i4l/isdn_ppp_vj.h b/drivers/isdn/i4l/isdn_ppp_vj.h new file mode 100644 index 000000000000..e1fdeac199b7 --- /dev/null +++ b/drivers/isdn/i4l/isdn_ppp_vj.h @@ -0,0 +1,61 @@ +/* Linux ISDN subsystem, PPP VJ header compression + * + * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * 1999-2002 by Kai Germaschewski <kai@germaschewski.name> + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef __ISDN_PPP_VJ_H__ +#define __ISDN_PPP_VJ_H__ + +#include "isdn_net_lib.h" + +#ifdef CONFIG_ISDN_PPP_VJ + + +struct slcompress * +ippp_vj_alloc(void); + +void +ippp_vj_free(struct slcompress *slcomp); + +int +ippp_vj_set_maxcid(isdn_net_dev *idev, int val); + +void +ippp_vj_decompress(isdn_net_dev *idev, struct sk_buff *skb_old, u16 proto); + +struct sk_buff * +ippp_vj_compress(isdn_net_dev *idev, struct sk_buff *skb_old, u16 *proto); + + +#else + + +static inline struct slcompress * +ippp_vj_alloc(void) +{ return (struct slcompress *) !NULL; } + +static inline void +ippp_vj_free(struct slcompress *slcomp) +{ } + +static inline int +ippp_vj_set_maxcid(isdn_net_dev *idev, int val) +{ return -EINVAL; } + +static inline struct sk_buff * +ippp_vj_decompress(struct slcompress *slcomp, struct sk_buff *skb_old, + u16 proto) +{ return skb_old; } + +static inline struct sk_buff * +ippp_vj_compress(isdn_net_dev *idev, struct sk_buff *skb_old, u16 *proto) +{ return skb_old; } + + +#endif + +#endif diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index c7b3f8ce4c71..32fe087ce1a2 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1,17 +1,20 @@ -/* $Id: isdn_tty.c,v 1.94.6.9 2001/11/06 20:58:29 kai Exp $ - * - * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). +/* Linux ISDN subsystem, tty functions and AT-command emulator * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ -#undef ISDN_TTY_STAT_DEBUG -#include <linux/config.h> +#define ISDN_TTY_STAT_DEBUG +#define ISDN_DEBUG_MODEM_HUP +#define ISDN_DEBUG_MODEM_VOICE +#define ISDN_DEBUG_MODEM_OPEN +#define ISDN_DEBUG_MODEM_IOCTL +#define ISDN_DEBUG_MODEM_ICALL + +#include <linux/module.h> #include <linux/isdn.h> #include "isdn_common.h" #include "isdn_tty.h" @@ -21,21 +24,40 @@ #define VBUFX (VBUF/16) #endif +#define RING_TIMEOUT (5*HZ) /* repeat RING every 5 secs */ #define FIX_FILE_TRANSFER #define DUMMY_HAYES_AT /* Prototypes */ +static void isdn_tty_modem_xmit(struct modem_info *info); static int isdn_tty_edit_at(const char *, int, modem_info *, int); -static void isdn_tty_check_esc(const u_char *, u_char, int, int *, int *, int); +static void isdn_tty_escape_timer(unsigned long data); +static void isdn_tty_ring_timer(unsigned long data); +static void isdn_tty_connect_timer(unsigned long data); +static void isdn_tty_check_esc(struct modem_info *info, + const unsigned char *p, int count); static void isdn_tty_modem_reset_regs(modem_info *, int); static void isdn_tty_cmd_ATA(modem_info *); static void isdn_tty_flush_buffer(struct tty_struct *); static void isdn_tty_modem_result(int, modem_info *); +static int isdn_tty_stat_callback(struct isdn_slot *slot, isdn_ctrl *c); +static int isdn_tty_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb); #ifdef CONFIG_ISDN_AUDIO static int isdn_tty_countDLE(unsigned char *, int); #endif +static int +isdn_tty_event_callback(struct isdn_slot *slot, int pr, void *arg) +{ + switch (pr) { + case EV_DATA_IND: + return isdn_tty_rcv_skb(slot, arg); + default: + return isdn_tty_stat_callback(slot, arg); + } +} + /* Leave this unchanged unless you know what you do! */ #define MODEM_PARANOIA_CHECK #define MODEM_DO_RESTART @@ -48,14 +70,13 @@ static char *isdn_ttyname_ttyI = "ttyI"; static char *isdn_ttyname_cui = "cui"; #endif +struct isdn_modem isdn_mdm; + static int bit2si[8] = {1, 5, 7, 7, 7, 7, 7, 7}; static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.94.6.9 $"; - - /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() * to stuff incoming data directly into a tty's flip-buffer. This * is done to speed up tty-receiving if the receive-queue is empty. @@ -111,82 +132,166 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) return 0; } +/* + * isdn_slot_readbchan() tries to get data from the read-queue. + * It MUST be called with interrupts off. + */ +static int +isdn_tty_readbchan(struct modem_info *info, u_char * buf, u_char * fp, int len) +{ + int count; + int count_pull; + int count_put; + int dflag; + struct sk_buff *skb; + u_char *cp; + + if (skb_queue_empty(&info->rpqueue)) + return 0; + + if (len > info->rcvcount) + len = info->rcvcount; + cp = buf; + count = 0; + while (len) { + if (!(skb = skb_peek(&info->rpqueue))) + break; +#ifdef CONFIG_ISDN_AUDIO + if (ISDN_AUDIO_SKB_LOCK(skb)) + break; + ISDN_AUDIO_SKB_LOCK(skb) = 1; + if (ISDN_AUDIO_SKB_DLECOUNT(skb) || info->DLEflag) { + char *p = skb->data; + + dflag = 0; + count_pull = count_put = 0; + while ((count_pull < skb->len) && (len > 0)) { + len--; + if (info->DLEflag) { + *cp++ = DLE; + info->DLEflag = 0; + } else { + *cp++ = *p; + if (*p == DLE) { + info->DLEflag = 1; + (ISDN_AUDIO_SKB_DLECOUNT(skb))--; + } + p++; + count_pull++; + } + count_put++; + } + if (count_pull >= skb->len) + dflag = 1; + } else { +#endif + /* No DLE's in buff, so simply copy it */ + dflag = 1; + if ((count_pull = skb->len) > len) { + count_pull = len; + dflag = 0; + } + count_put = count_pull; + memcpy(cp, skb->data, count_put); + cp += count_put; + len -= count_put; +#ifdef CONFIG_ISDN_AUDIO + } +#endif + count += count_put; + if (fp) { + memset(fp, 0, count_put); + fp += count_put; + } + if (dflag) { + /* We got all the data in this buff. + * Now we can dequeue it. + */ + if (fp) + *(fp - 1) = 0xff; +#ifdef CONFIG_ISDN_AUDIO + ISDN_AUDIO_SKB_LOCK(skb) = 0; +#endif + skb = skb_dequeue(&info->rpqueue); + dev_kfree_skb(skb); + } else { + /* Not yet emptied this buff, so it + * must stay in the queue, for further calls + * but we pull off the data we got until now. + */ + skb_pull(skb, count_pull); +#ifdef CONFIG_ISDN_AUDIO + ISDN_AUDIO_SKB_LOCK(skb) = 0; +#endif + } + info->rcvcount -= count_put; + } + return count; +} + /* isdn_tty_readmodem() is called periodically from within timer-interrupt. * It tries getting received data from the receive queue an stuff it into * the tty's flip-buffer. */ -void -isdn_tty_readmodem(void) +static void +isdn_tty_readmodem(unsigned long data) { - int resched = 0; - int midx; - int i; + struct modem_info *info = (struct modem_info *) data; int c; int r; ulong flags; struct tty_struct *tty; - modem_info *info; - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - if ((midx = isdn_slot_m_idx(i)) >= 0) { - info = &dev->mdm.info[midx]; - if (info->online) { - r = 0; + if (!info->online) + return; + + r = 0; #ifdef CONFIG_ISDN_AUDIO - isdn_audio_eval_dtmf(info); - if ((info->vonline & 1) && (info->emu.vpar[1])) - isdn_audio_eval_silence(info); -#endif - if ((tty = info->tty)) { - if (info->mcr & UART_MCR_RTS) { - c = TTY_FLIPBUF_SIZE - tty->flip.count; - if (c > 0) { - save_flags(flags); - cli(); - r = isdn_slot_readbchan(info->isdn_slot, - tty->flip.char_buf_ptr, - tty->flip.flag_buf_ptr, c); - /* CISCO AsyncPPP Hack */ - if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) - memset(tty->flip.flag_buf_ptr, 0, r); - tty->flip.count += r; - tty->flip.flag_buf_ptr += r; - tty->flip.char_buf_ptr += r; - if (r) - schedule_delayed_work(&tty->flip.work, 1); - restore_flags(flags); - } - } else - r = 1; - } else - r = 1; - if (r) { - info->rcvsched = 0; - resched = 1; - } else - info->rcvsched = 1; + isdn_audio_eval_dtmf(info); + if ((info->vonline & 1) && (info->emu.vpar[1])) + isdn_audio_eval_silence(info); +#endif + if ((tty = info->tty)) { + if (info->mcr & UART_MCR_RTS) { + c = TTY_FLIPBUF_SIZE - tty->flip.count; + if (c > 0) { + save_flags(flags); + cli(); + r = isdn_tty_readbchan(info, + tty->flip.char_buf_ptr, + tty->flip.flag_buf_ptr, c); + /* CISCO AsyncPPP Hack */ + if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) + memset(tty->flip.flag_buf_ptr, 0, r); + tty->flip.count += r; + tty->flip.flag_buf_ptr += r; + tty->flip.char_buf_ptr += r; + if (r) + schedule_delayed_work(&tty->flip.work, 1); + restore_flags(flags); } - } - } - if (!resched) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0); + } else + r = 1; + } else + r = 1; + + if (r) { + info->rcvsched = 0; + mod_timer(&info->read_timer, jiffies + 4); + } else + info->rcvsched = 1; } -int -isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) +static int +isdn_tty_rcv_skb(struct isdn_slot *slot, struct sk_buff *skb) { ulong flags; - int midx; #ifdef CONFIG_ISDN_AUDIO int ifmt; #endif modem_info *info; - if ((midx = isdn_slot_m_idx(i)) < 0) { - /* if midx is invalid, packet is not for tty */ - return 0; - } - info = &dev->mdm.info[midx]; + info = slot->priv; #ifdef CONFIG_ISDN_AUDIO ifmt = 1; @@ -269,7 +374,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 */ save_flags(flags); cli(); - if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) + if (skb_queue_empty(&info->rpqueue)) if (isdn_tty_try_read(info, skb)) { restore_flags(flags); return 1; @@ -277,17 +382,15 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) /* Direct deliver failed or queue wasn't empty. * Queue up for later dequeueing via timer-irq. */ - __skb_queue_tail(&dev->drv[di]->rpqueue[channel], skb); - dev->drv[di]->rcvcount[channel] += - (skb->len + isdn_tty_queue_tail(info, skb, skb->len #ifdef CONFIG_ISDN_AUDIO + ISDN_AUDIO_SKB_DLECOUNT(skb) #endif - ); + ); restore_flags(flags); /* Schedule dequeuing */ - if ((dev->modempoll) && (info->rcvsched)) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); + if (dev->modempoll && info->rcvsched) + mod_timer(&info->read_timer, jiffies + 4); return 1; } @@ -627,7 +730,7 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m) int si = 7; int l2 = m->mdmreg[REG_L2PROT]; ulong flags; - int i; + struct isdn_slot *slot; int j; for (j = 7; j >= 0; j--) @@ -650,8 +753,8 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m) m->mdmreg[REG_SI1I] = si2bit[si]; save_flags(flags); cli(); - i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); - if (i < 0) { + slot = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); + if (!slot) { restore_flags(flags); isdn_tty_modem_result(RESULT_NO_DIALTONE, info); } else { @@ -663,8 +766,11 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m) .msn = m->msn, .phone = n, }; - info->isdn_slot = i; - isdn_slot_set_m_idx(i, info->line); + + info->isdn_slot = slot; + slot->usage |= ISDN_USAGE_MODEM; + slot->priv = info; + slot->event_cb = isdn_tty_event_callback; info->last_dir = 1; info->last_l2 = l2; strcpy(info->last_num, n); @@ -676,9 +782,8 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m) } #endif info->dialing = 1; - info->emu.carrierwait = 0; isdn_slot_dial(info->isdn_slot, &dial); - isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); + mod_timer(&info->connect_timer, jiffies + info->emu.mdmreg[REG_WAITC] * HZ); } } @@ -690,13 +795,13 @@ void isdn_tty_modem_hup(modem_info * info, int local) { isdn_ctrl cmd; - int slot; + struct isdn_slot *slot; if (!info) return; slot = info->isdn_slot; - if (slot < 0) + if (!slot) return; #ifdef ISDN_DEBUG_MODEM_HUP @@ -743,11 +848,12 @@ isdn_tty_modem_hup(modem_info * info, int local) if (local) isdn_slot_command(slot, ISDN_CMD_HANGUP, &cmd); - isdn_slot_all_eaz(slot); info->emu.mdmreg[REG_RINGCNT] = 0; + skb_queue_purge(&info->rpqueue); + slot->priv = NULL; + slot->event_cb = NULL; isdn_slot_free(slot); - isdn_slot_set_m_idx(slot, -1); - info->isdn_slot = -1; + info->isdn_slot = NULL; } /* @@ -781,7 +887,6 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m) cmd.parm.cmsg.Length = l+18; cmd.parm.cmsg.Command = CAPI_FACILITY; cmd.parm.cmsg.Subcommand = CAPI_REQ; - cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1; cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */ cmd.parm.cmsg.para[1] = 0; cmd.parm.cmsg.para[2] = l + 3; @@ -808,7 +913,7 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m) int l2 = m->mdmreg[REG_L2PROT]; isdn_ctrl cmd; ulong flags; - int i; + struct isdn_slot *slot; int j; int l; @@ -833,14 +938,15 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m) m->mdmreg[REG_SI1I] = si2bit[si]; save_flags(flags); cli(); - i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); - if (i < 0) { + slot = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); + if (!slot) { restore_flags(flags); isdn_tty_modem_result(RESULT_NO_DIALTONE, info); } else { - info->isdn_slot = i; - isdn_slot_set_m_idx(i, info->line); - isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_OUTGOING); + info->isdn_slot = slot; + slot->usage |= ISDN_USAGE_MODEM; + slot->priv = info; + slot->event_cb = isdn_tty_event_callback; info->last_dir = 1; // strcpy(info->last_num, n); restore_flags(flags); @@ -852,7 +958,6 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m) cmd.parm.cmsg.Length = l+18; cmd.parm.cmsg.Command = CAPI_FACILITY; cmd.parm.cmsg.Subcommand = CAPI_REQ; - cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1; cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */ cmd.parm.cmsg.para[1] = 0; cmd.parm.cmsg.para[2] = l+3; @@ -864,7 +969,7 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m) // strcpy(dev->num[i], n); isdn_info_update(); isdn_slot_command(info->isdn_slot, CAPI_PUT_MESSAGE, &cmd); - isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); + mod_timer(&info->connect_timer, jiffies + info->emu.mdmreg[REG_WAITC] * HZ); } } @@ -880,7 +985,7 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg) int l2 = m->mdmreg[REG_L2PROT]; isdn_ctrl cmd; ulong flags; - int i; + struct isdn_slot *slot; int j; int l; @@ -909,14 +1014,15 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg) m->mdmreg[REG_SI1I] = si2bit[si]; save_flags(flags); cli(); - i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); - if (i < 0) { + slot = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn); + if (!slot) { restore_flags(flags); isdn_tty_modem_result(RESULT_NO_DIALTONE, info); } else { - info->isdn_slot = i; - isdn_slot_set_m_idx(i, info->line); - isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_OUTGOING); + info->isdn_slot = slot; + slot->usage |= ISDN_USAGE_MODEM; + slot->priv = info; + slot->event_cb = isdn_tty_event_callback; info->last_dir = 1; restore_flags(flags); info->last_l2 = l2; @@ -927,7 +1033,6 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg) cmd.parm.cmsg.Length = l+14; cmd.parm.cmsg.Command = CAPI_MANUFACTURER; cmd.parm.cmsg.Subcommand = CAPI_REQ; - cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1; cmd.parm.cmsg.para[0] = l+1; strncpy(&cmd.parm.cmsg.para[1], msg, l); cmd.parm.cmsg.para[l+1] = 0xd; @@ -1028,7 +1133,6 @@ isdn_tty_startup(modem_info * info) return 0; save_flags(flags); cli(); - isdn_MOD_INC_USE_COUNT(); #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "starting up ttyi%d ...\n", info->line); #endif @@ -1066,7 +1170,6 @@ isdn_tty_shutdown(modem_info * info) #endif save_flags(flags); cli(); /* Disable interrupts */ - isdn_MOD_DEC_USE_COUNT(); info->msr &= ~UART_MSR_RI; if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); @@ -1099,7 +1202,6 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co { int c; int total = 0; - int di; modem_info *info = (modem_info *) tty->driver_data; atemu *m = &info->emu; @@ -1113,9 +1215,8 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co c = count; if (c > info->xmit_size - info->xmit_count) c = info->xmit_size - info->xmit_count; - di = isdn_slot_driver(info->isdn_slot); - if (di >= 0 && c > dev->drv[di]->maxbufsize) - c = dev->drv[di]->maxbufsize; + if (info->isdn_slot && c > isdn_slot_maxbufsize(info->isdn_slot)) + c = isdn_slot_maxbufsize(info->isdn_slot); if (c <= 0) break; if ((info->online > 1) @@ -1123,13 +1224,6 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co || (info->vonline & 3) #endif ) { -#ifdef CONFIG_ISDN_AUDIO - if (!info->vonline) -#endif - isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c, - &(m->pluscount), - &(m->lastplus), - from_user); if (from_user) { if (copy_from_user(&(info->xmit_buf[info->xmit_count]), buf, c)) { total = -EFAULT; @@ -1138,6 +1232,10 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co } else memcpy(&(info->xmit_buf[info->xmit_count]), buf, c); #ifdef CONFIG_ISDN_AUDIO + if (!info->vonline) +#endif + isdn_tty_check_esc(info, &info->xmit_buf[info->xmit_count], c); +#ifdef CONFIG_ISDN_AUDIO if (info->vonline) { int cc = isdn_tty_handleDLEdown(info, m, c); if (info->vonline & 2) { @@ -1206,11 +1304,7 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co } atomic_dec(&info->xmit_lock); if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue))) { - if (m->mdmreg[REG_DXMT] & BIT_DXMT) { - isdn_tty_senddown(info); - isdn_tty_tint(info); - } - isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1); + isdn_tty_modem_xmit(info); } out: if (from_user) @@ -1278,7 +1372,7 @@ isdn_tty_flush_chars(struct tty_struct *tty) if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_flush_chars")) return; if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue))) - isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1); + isdn_tty_modem_xmit(info); } /* @@ -1666,13 +1760,16 @@ static int isdn_tty_open(struct tty_struct *tty, struct file *filp) { modem_info *info; - int retval, - line; + int retval, line; + + /* FIXME. This is not unload-race free AFAICS */ + + MOD_INC_USE_COUNT; line = minor(tty->device) - tty->driver.minor_start; if (line < 0 || line > ISDN_MAX_CHANNELS) return -ENODEV; - info = &dev->mdm.info[line]; + info = &isdn_mdm.info[line]; if (isdn_tty_paranoia_check(info, tty->device, "isdn_tty_open")) return -ENODEV; #ifdef ISDN_DEBUG_MODEM_OPEN @@ -1726,7 +1823,8 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) ulong timeout; if (!info || isdn_tty_paranoia_check(info, tty->device, "isdn_tty_close")) - return; + goto out; + save_flags(flags); cli(); if (tty_hung_up_p(filp)) { @@ -1734,7 +1832,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close return after tty_hung_up_p\n"); #endif - return; + goto out; } if ((tty->count == 1) && (info->count != 1)) { /* @@ -1758,7 +1856,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); #endif - return; + goto out; } info->flags |= ISDN_ASYNC_CLOSING; /* @@ -1813,6 +1911,8 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close normal exit\n"); #endif + out: + MOD_DEC_USE_COUNT; } /* @@ -1942,11 +2042,11 @@ modem_write_profile(atemu * m) int isdn_tty_init(void) { - modem *m; + struct isdn_modem *m; int i, retval; modem_info *info; - m = &dev->mdm; + m = &isdn_mdm; memset(&m->tty_modem, 0, sizeof(struct tty_driver)); m->tty_modem.magic = TTY_DRIVER_MAGIC; m->tty_modem.name = isdn_ttyname_ttyI; @@ -2025,7 +2125,22 @@ isdn_tty_init(void) info->normal_termios = m->tty_modem.init_termios; init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); - info->isdn_slot = -1; + info->isdn_slot = NULL; + init_timer(&info->escape_timer); + info->escape_timer.data = (unsigned long) info; + info->escape_timer.function = isdn_tty_escape_timer; + init_timer(&info->ring_timer); + info->ring_timer.data = (unsigned long) info; + info->ring_timer.function = isdn_tty_ring_timer; + init_timer(&info->connect_timer); + info->connect_timer.data = (unsigned long) info; + info->connect_timer.function = isdn_tty_connect_timer; + init_timer(&info->read_timer); + info->read_timer.data = (unsigned long) info; + info->read_timer.function = isdn_tty_readmodem; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + skb_queue_head_init(&info->rpqueue); info->xmit_size = ISDN_SERIAL_XMIT_SIZE; skb_queue_head_init(&info->xmit_queue); #ifdef CONFIG_ISDN_AUDIO @@ -2052,9 +2167,9 @@ isdn_tty_init(void) #endif kfree(info->xmit_buf - 4); } - tty_unregister_driver(&dev->mdm.cua_modem); + tty_unregister_driver(&isdn_mdm.cua_modem); err_unregister_tty: - tty_unregister_driver(&dev->mdm.tty_modem); + tty_unregister_driver(&isdn_mdm.tty_modem); err: return retval; } @@ -2062,20 +2177,20 @@ isdn_tty_init(void) void isdn_tty_exit(void) { - modem *m = &dev->mdm; modem_info *info; int i; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - info = &m->info[i]; + info = &isdn_mdm.info[i]; isdn_tty_cleanup_xmit(info); + skb_queue_purge(&info->rpqueue); #ifdef CONFIG_ISDN_TTY_FAX kfree(info->fax); #endif kfree(info->xmit_buf - 4); } - tty_unregister_driver(&dev->mdm.cua_modem); - tty_unregister_driver(&dev->mdm.tty_modem); + tty_unregister_driver(&isdn_mdm.cua_modem); + tty_unregister_driver(&isdn_mdm.tty_modem); } /* @@ -2141,12 +2256,11 @@ isdn_tty_match_icall(char *cid, atemu *emu, int di) * CID is longer. */ int -isdn_tty_find_icall(int di, int ch, setup_parm *setup) +isdn_tty_find_icall(struct isdn_slot *slot, setup_parm *setup) { char *eaz; int i; int wret; - int idx; int si1; int si2; char *nr; @@ -2171,16 +2285,15 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) save_flags(flags); cli(); for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - modem_info *info = &dev->mdm.info[i]; + modem_info *info = &isdn_mdm.info[i]; if (info->count == 0) continue; if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) && /* SI1 is matching */ (info->emu.mdmreg[REG_SI2] == si2)) { /* SI2 is matching */ - idx = isdn_dc2minor(di, ch); #ifdef ISDN_DEBUG_MODEM_ICALL printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret); - printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx, + printk(KERN_DEBUG "m_fi: sl=%d flags=%08lx drv=%d ch=%d usg=%d\n", sl, info->flags, info->isdn_driver, info->isdn_channel, dev->usage[idx]); #endif @@ -2188,27 +2301,27 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) #ifndef FIX_FILE_TRANSFER (info->flags & ISDN_ASYNC_NORMAL_ACTIVE) && #endif - (info->isdn_slot == -1) && - (USG_NONE(isdn_slot_usage(idx)))) { + (!info->isdn_slot)) { int matchret; - if ((matchret = isdn_tty_match_icall(eaz, &info->emu, di)) > wret) + if ((matchret = isdn_tty_match_icall(eaz, &info->emu, slot->di)) > wret) wret = matchret; if (!matchret) { /* EAZ is matching */ - info->isdn_slot = idx; - isdn_slot_set_m_idx(idx, info->line); - strcpy(isdn_slot_num(idx), nr); + info->isdn_slot = slot; + slot->usage |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); + slot->priv = info; + slot->event_cb = isdn_tty_event_callback; + strcpy(slot->num, nr); strcpy(info->emu.cpn, eaz); info->emu.mdmreg[REG_SI1I] = si2bit[si1]; info->emu.mdmreg[REG_PLAN] = setup->plan; info->emu.mdmreg[REG_SCREEN] = setup->screen; - isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT])); restore_flags(flags); printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr, info->line); info->msr |= UART_MSR_RI; isdn_tty_modem_result(RESULT_RING, info); - isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1); + mod_timer(&info->ring_timer, jiffies + RING_TIMEOUT); return 1; } } @@ -2216,24 +2329,22 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup) } restore_flags(flags); 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; } #define TTY_IS_ACTIVE(info) \ (info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) -int -isdn_tty_stat_callback(int i, isdn_ctrl *c) +static int +isdn_tty_stat_callback(struct isdn_slot *slot, isdn_ctrl *c) { - int mi; + isdn_ctrl cmd; modem_info *info; char *e; - if (i < 0) - return 0; - if ((mi = isdn_slot_m_idx(i)) >= 0) { - info = &dev->mdm.info[mi]; + info = slot->priv; + if (1) { switch (c->command) { case ISDN_STAT_CINF: printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num); @@ -2246,15 +2357,12 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) #ifdef ISDN_TTY_STAT_DEBUG printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line); #endif - if ((info->isdn_slot == isdn_dc2minor(c->driver, c->arg))) { - info->msr |= UART_MSR_CTS; - if (info->send_outstanding) - if (!(--info->send_outstanding)) - info->lsr |= UART_LSR_TEMT; - isdn_tty_tint(info); - return 1; - } - break; + info->msr |= UART_MSR_CTS; + if (info->send_outstanding) + if (!(--info->send_outstanding)) + info->lsr |= UART_LSR_TEMT; + isdn_tty_tint(info); + return 1; case ISDN_STAT_CAUSE: #ifdef ISDN_TTY_STAT_DEBUG printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line); @@ -2281,6 +2389,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) #endif if (TTY_IS_ACTIVE(info)) { if (info->dialing == 1) { + isdn_slot_command(info->isdn_slot, ISDN_CMD_ACCEPTB, &cmd); info->dialing = 2; return 1; } @@ -2330,14 +2439,14 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) info->last_dir = 0; info->dialing = 0; info->rcvsched = 1; - if (USG_MODEM(isdn_slot_usage(i))) { + if (USG_MODEM(slot->usage)) { if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) { strcpy(info->emu.connmsg, c->parm.num); isdn_tty_modem_result(RESULT_CONNECT, info); } else isdn_tty_modem_result(RESULT_CONNECT64000, info); } - if (USG_VOICE(isdn_slot_usage(i))) + if (USG_VOICE(slot->usage)) isdn_tty_modem_result(RESULT_VCON, info); return 1; } @@ -2354,34 +2463,6 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) return 1; } break; - case ISDN_STAT_NODCH: -#ifdef ISDN_TTY_STAT_DEBUG - printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line); -#endif - if (TTY_IS_ACTIVE(info)) { - if (info->dialing) { - info->dialing = 0; - info->last_l2 = -1; - info->last_si = 0; - sprintf(info->last_cause, "0000"); - isdn_tty_modem_result(RESULT_NO_DIALTONE, info); - } - isdn_tty_modem_hup(info, 0); - return 1; - } - break; - case ISDN_STAT_UNLOAD: -#ifdef ISDN_TTY_STAT_DEBUG - printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line); -#endif - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - info = &dev->mdm.info[i]; - if (isdn_slot_driver(info->isdn_slot) == c->driver) { - if (info->online) - isdn_tty_modem_hup(info, 1); - } - } - return 1; #ifdef CONFIG_ISDN_TTY_FAX case ISDN_STAT_FAXIND: if (TTY_IS_ACTIVE(info)) { @@ -2428,7 +2509,6 @@ isdn_tty_at_cout(char *msg, modem_info * info) ulong flags; struct sk_buff *skb = 0; char *sp = 0; - int di,ch; if (!msg) { printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); @@ -2444,9 +2524,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) /* use queue instead of direct flip, if online and */ /* data is in queue or flip buffer is full */ - 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) || - (!skb_queue_empty(&dev->drv[di]->rpqueue[ch])))) { + (!skb_queue_empty(&info->rpqueue)))) { skb = alloc_skb(strlen(msg) #ifdef CONFIG_ISDN_AUDIO + sizeof(isdn_audio_skb) @@ -2489,13 +2568,11 @@ isdn_tty_at_cout(char *msg, modem_info * info) } } if (skb) { - __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); - dev->drv[di]->rcvcount[ch] += skb->len; + isdn_tty_queue_tail(info, skb, skb->len); restore_flags(flags); /* Schedule dequeuing */ - if ((dev->modempoll) && (info->rcvsched)) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); - + if (dev->modempoll && info->rcvsched) + mod_timer(&info->read_timer, jiffies + 4); } else { restore_flags(flags); schedule_delayed_work(&tty->flip.work, 1); @@ -2508,7 +2585,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) static void isdn_tty_on_hook(modem_info * info) { - if (info->isdn_slot >= 0) { + if (info->isdn_slot) { #ifdef ISDN_DEBUG_MODEM_HUP printk(KERN_DEBUG "Mhup in isdn_tty_on_hook\n"); #endif @@ -2525,55 +2602,56 @@ isdn_tty_off_hook(void) #define PLUSWAIT1 (HZ/2) /* 0.5 sec. */ #define PLUSWAIT2 (HZ*3/2) /* 1.5 sec */ +static void +isdn_tty_escape_timer(unsigned long data) +{ + struct modem_info *info = (struct modem_info *) data; + + if (!info->online) + return; + + info->emu.pluscount = 0; + info->online = 0; + isdn_tty_modem_result(RESULT_OK, info); +} + /* * Check Buffer for Modem-escape-sequence, activate timer-callback to * isdn_tty_modem_escape() if sequence found. - * - * Parameters: - * p pointer to databuffer - * plus escape-character - * count length of buffer - * pluscount count of valid escape-characters so far - * lastplus timestamp of last character */ -static void -isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount, - int *lastplus, int from_user) +static void isdn_tty_check_esc(struct modem_info *info, + const unsigned char *p, int count) { - char cbuf[3]; + unsigned char plus = info->emu.mdmreg[REG_ESC]; if (plus > 127) return; + if (count > 3) { p += count - 3; count = 3; - *pluscount = 0; + info->emu.pluscount = 0; + info->emu.lastplus = jiffies; } - if (from_user) { - if (copy_from_user(cbuf, p, count)) - return; - p = cbuf; - } - while (count > 0) { - if (*(p++) == plus) { - if ((*pluscount)++) { - /* Time since last '+' > 0.5 sec. ? */ - if (time_after(jiffies, *lastplus + PLUSWAIT1)) - *pluscount = 1; - } else { - /* Time since last non-'+' < 1.5 sec. ? */ - if (time_before(jiffies, *lastplus + PLUSWAIT2)) - *pluscount = 0; - } - if ((*pluscount == 3) && (count == 1)) - isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, 1); - if (*pluscount > 3) - *pluscount = 1; - } else - *pluscount = 0; - *lastplus = jiffies; - count--; + for (; count > 0; info->emu.lastplus = jiffies, count--) { + if (*(p++) != plus) { + info->emu.pluscount = 0; + continue; + } + if (info->emu.pluscount == 0) { + if (time_after(jiffies, info->emu.lastplus + PLUSWAIT2)) + info->emu.pluscount = 1; + } else { + if (time_after(jiffies, info->emu.lastplus + PLUSWAIT1)) + info->emu.pluscount = 1; + else + info->emu.pluscount++; + } } + if (info->emu.pluscount == 3) + mod_timer(&info->escape_timer, jiffies + PLUSWAIT2); + else + del_timer(&info->escape_timer); } /* @@ -2668,7 +2746,7 @@ isdn_tty_modem_result(int code, modem_info * info) /* print CID, _before_ _every_ ring */ if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) { isdn_tty_at_cout("\r\nCALLER NUMBER: ", info); - isdn_tty_at_cout(isdn_slot_num(info->isdn_slot), info); + isdn_tty_at_cout(info->isdn_slot->num, info); if (m->mdmreg[REG_CDN] & BIT_CDN) { isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); isdn_tty_at_cout(info->emu.cpn, info); @@ -2697,7 +2775,7 @@ isdn_tty_modem_result(int code, modem_info * info) (m->mdmreg[REG_RINGCNT] == 1)) { isdn_tty_at_cout("\r\n", info); isdn_tty_at_cout("CALLER NUMBER: ", info); - isdn_tty_at_cout(isdn_slot_num(info->isdn_slot), info); + isdn_tty_at_cout(info->isdn_slot->num, info); if (m->mdmreg[REG_CDN] & BIT_CDN) { isdn_tty_at_cout("\r\nCALLED NUMBER: ", info); isdn_tty_at_cout(info->emu.cpn, info); @@ -3209,7 +3287,7 @@ isdn_tty_cmd_ATA(modem_info * info) if (info->msr & UART_MSR_RI) { /* Accept incoming call */ info->last_dir = 0; - strcpy(info->last_num, isdn_slot_num(info->isdn_slot)); + strcpy(info->last_num, info->isdn_slot->num); m->mdmreg[REG_RINGCNT] = 0; info->msr &= ~UART_MSR_RI; l2 = m->mdmreg[REG_L2PROT]; @@ -3235,9 +3313,8 @@ isdn_tty_cmd_ATA(modem_info * info) #endif isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL3, &cmd); info->dialing = 16; - info->emu.carrierwait = 0; isdn_slot_command(info->isdn_slot, ISDN_CMD_ACCEPTD, &cmd); - isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); + mod_timer(&info->connect_timer, jiffies + info->emu.mdmreg[REG_WAITC] * HZ); } else isdn_tty_modem_result(RESULT_NO_ANSWER, info); } @@ -3907,99 +3984,34 @@ isdn_tty_edit_at(const char *p, int count, modem_info * info, int user) return total; } -/* - * Switch all modem-channels who are online and got a valid - * escape-sequence 1.5 seconds ago, to command-mode. - * This function is called every second via timer-interrupt from within - * timer-dispatcher isdn_timer_function() - */ -void -isdn_tty_modem_escape(void) +static void +isdn_tty_ring_timer(unsigned long data) { - int ton = 0; - int i; - int midx; - - for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (USG_MODEM(isdn_slot_usage(i))) - if ((midx = isdn_slot_m_idx(i)) >= 0) { - modem_info *info = &dev->mdm.info[midx]; - if (info->online) { - ton = 1; - if ((info->emu.pluscount == 3) && - time_after(jiffies , info->emu.lastplus + PLUSWAIT2)) { - info->emu.pluscount = 0; - info->online = 0; - isdn_tty_modem_result(RESULT_OK, info); - } - } - } - isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, ton); -} + struct modem_info *info = (struct modem_info *) data; -/* - * Put a RING-message to all modem-channels who have the RI-bit set. - * This function is called every second via timer-interrupt from within - * timer-dispatcher isdn_timer_function() - */ -void -isdn_tty_modem_ring(void) -{ - int ton = 0; - int i; + if (!(info->msr & UART_MSR_RI)) + return; - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - modem_info *info = &dev->mdm.info[i]; - if (info->msr & UART_MSR_RI) { - ton = 1; - isdn_tty_modem_result(RESULT_RING, info); - } - } - isdn_timer_ctrl(ISDN_TIMER_MODEMRING, ton); + isdn_tty_modem_result(RESULT_RING, info); + mod_timer(&info->ring_timer, jiffies + RING_TIMEOUT); } - -/* - * For all online tty's, try sending data to - * the lower levels. - */ -void -isdn_tty_modem_xmit(void) + +static void +isdn_tty_modem_xmit(struct modem_info *info) { - int ton = 1; - int i; - - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - modem_info *info = &dev->mdm.info[i]; - if (info->online) { - ton = 1; - isdn_tty_senddown(info); - isdn_tty_tint(info); - } - } - isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, ton); + isdn_tty_senddown(info); + isdn_tty_tint(info); } -/* - * Check all channels if we have a 'no carrier' timeout. - * Timeout value is set by Register S7. - */ -void -isdn_tty_carrier_timeout(void) +static void +isdn_tty_connect_timer(unsigned long data) { - int ton = 0; - int i; + struct modem_info *info = (struct modem_info *) data; - for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - modem_info *info = &dev->mdm.info[i]; - if (info->dialing) { - if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) { - info->dialing = 0; - isdn_tty_modem_result(RESULT_NO_CARRIER, info); - isdn_tty_modem_hup(info, 1); - } - else - ton = 1; - } + if (info->dialing) { + info->dialing = 0; + isdn_tty_modem_result(RESULT_NO_CARRIER, info); + isdn_tty_modem_hup(info, 1); } - isdn_timer_ctrl(ISDN_TIMER_CARRIER, ton); } + diff --git a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h index 8cad26a3714a..2a902f74b586 100644 --- a/drivers/isdn/i4l/isdn_tty.h +++ b/drivers/isdn/i4l/isdn_tty.h @@ -1,13 +1,10 @@ -/* $Id: isdn_tty.h,v 1.22.6.2 2001/09/23 22:24:32 kai Exp $ - * - * header for Linux ISDN subsystem, tty related functions (linklevel). +/* Linux ISDN subsystem, tty related functions * * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #include <linux/config.h> @@ -101,16 +98,9 @@ ((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \ (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS2)) -extern void isdn_tty_modem_escape(void); -extern void isdn_tty_modem_ring(void); -extern void isdn_tty_carrier_timeout(void); -extern void isdn_tty_modem_xmit(void); extern int isdn_tty_init(void); -extern void isdn_tty_readmodem(void); -extern int isdn_tty_find_icall(int, int, setup_parm *); +extern int isdn_tty_find_icall(struct isdn_slot *slot, setup_parm *setup); extern void isdn_tty_cleanup_xmit(modem_info *); -extern int isdn_tty_stat_callback(int, isdn_ctrl *); -extern int isdn_tty_rcv_skb(int, int, int, struct sk_buff *); extern int isdn_tty_capi_facility(capi_msg *cm); extern void isdn_tty_at_cout(char *, modem_info *); extern void isdn_tty_modem_hup(modem_info *, int); @@ -122,3 +112,22 @@ extern void isdn_tty_fax_bitorder(modem_info *, struct sk_buff *); extern int isdn_tty_init(void); extern void isdn_tty_exit(void); + +struct isdn_modem { + int refcount; /* Number of opens */ + struct tty_driver tty_modem; /* tty-device */ + struct tty_driver cua_modem; /* cua-device */ + struct tty_struct *modem_table[ISDN_MAX_CHANNELS]; /* ?? copied from Orig */ + struct termios *modem_termios[ISDN_MAX_CHANNELS]; + struct termios *modem_termios_locked[ISDN_MAX_CHANNELS]; + modem_info info[ISDN_MAX_CHANNELS]; /* Private data */ +}; + +extern struct isdn_modem isdn_mdm; + +static inline void +isdn_tty_queue_tail(modem_info *info, struct sk_buff *skb, int len) +{ + __skb_queue_tail(&info->rpqueue, skb); + info->rcvcount += len; +} diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index 2f7a5a0f2b48..c216f92aaece 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c @@ -1,6 +1,4 @@ -/* $Id: isdn_ttyfax.c,v 1.7.6.2 2001/09/23 22:24:32 kai Exp $ - * - * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel). +/* Linux ISDN subsystem, tty_fax AT-command emulator * * Copyright 1999 by Armin Schindler (mac@melware.de) * Copyright 1999 by Ralf Spachmann (mel@melware.de) @@ -8,7 +6,6 @@ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #undef ISDN_TTY_FAX_STAT_DEBUG @@ -19,26 +16,8 @@ #include "isdn_tty.h" #include "isdn_ttyfax.h" - -static char *isdn_tty_fax_revision = "$Revision: 1.7.6.2 $"; - #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; } -static char * -isdn_getrev(const char *revision) -{ - char *rev; - char *p; - - if ((p = strchr(revision, ':'))) { - rev = p + 2; - p = strchr(rev, '$'); - *--p = 0; - } else - rev = "???"; - return rev; -} - /* * Fax Class 2 Modem results * @@ -74,7 +53,7 @@ isdn_tty_fax_modem_result(int code, modem_info * info) case 2: /* +FCON */ /* Append CPN, if enabled */ if ((m->mdmreg[REG_CPNFCON] & BIT_CPNFCON) && - (!(isdn_slot_usage(info->isdn_slot) & ISDN_USAGE_OUTGOING))) { + (!(info->isdn_slot->usage & ISDN_USAGE_OUTGOING))) { sprintf(rs, "/%s", m->cpn); isdn_tty_at_cout(rs, info); } @@ -322,7 +301,8 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info) static char *cmd[] = {"AE", "TS", "RS", "TM", "RM", "TH", "RH"}; isdn_ctrl c; - int par, i; + int par; + struct isdn_slot *slot; long flags; for (c.parm.aux.cmd = 0; c.parm.aux.cmd < 7; c.parm.aux.cmd++) @@ -364,7 +344,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info) printk(KERN_DEBUG "isdn_tty_cmd_FCLASS1 %d/%d/%d)\n", c.parm.aux.cmd, c.parm.aux.subcmd, c.parm.aux.para[0]); #endif - if (info->isdn_slot < 0) { + if (!info->isdn_slot) { save_flags(flags); cli(); if ((c.parm.aux.subcmd == AT_EQ_VALUE) || @@ -373,18 +353,16 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info) PARSE_ERROR1; } /* get a temporary connection to the first free fax driver */ - i = isdn_get_free_slot(ISDN_USAGE_FAX, ISDN_PROTO_L2_FAX, + slot = isdn_get_free_slot(ISDN_USAGE_FAX, ISDN_PROTO_L2_FAX, ISDN_PROTO_L3_FCLASS1, -1, -1, "00"); - if (i < 0) { + if (!slot) { restore_flags(flags); PARSE_ERROR1; } - info->isdn_slot = i; - isdn_slot_set_m_idx(i, info->line); - isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c); - isdn_slot_free(info->isdn_slot); - isdn_slot_set_m_idx(i, -1); - info->isdn_slot = -1; + info->isdn_slot = slot; + isdn_slot_command(slot, ISDN_CMD_FAXCMD, &c); + isdn_slot_free(slot); + info->isdn_slot = NULL; restore_flags(flags); } else { isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c); @@ -1065,8 +1043,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info) #ifdef ISDN_TTY_FAX_STAT_DEBUG printk(KERN_DEBUG "isdn_tty: FREV?\n"); #endif - strcpy(rss, isdn_tty_fax_revision); - sprintf(rs, "\r\nRev: %s", isdn_getrev(rss)); + sprintf(rs, "\r\nRev: 1.0"); isdn_tty_at_cout(rs, info); return 0; } diff --git a/drivers/isdn/i4l/isdn_ttyfax.h b/drivers/isdn/i4l/isdn_ttyfax.h index 244ada3ca127..3567899e4e88 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.h +++ b/drivers/isdn/i4l/isdn_ttyfax.h @@ -1,6 +1,4 @@ -/* $Id: isdn_ttyfax.h,v 1.2.6.1 2001/09/23 22:24:32 kai Exp $ - * - * header for Linux ISDN subsystem, tty_fax related functions (linklevel). +/* Linux ISDN subsystem, tty_fax related functions * * Copyright 1999 by Armin Schindler (mac@melware.de) * Copyright 1999 by Ralf Spachmann (mel@melware.de) @@ -8,7 +6,6 @@ * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c index 1676de4975cc..be702981df0e 100644 --- a/drivers/isdn/i4l/isdn_v110.c +++ b/drivers/isdn/i4l/isdn_v110.c @@ -1,12 +1,9 @@ -/* $Id: isdn_v110.c,v 1.5.6.4 2001/09/23 22:24:32 kai Exp $ - * - * Linux ISDN subsystem, V.110 related functions (linklevel). +/* Linux ISDN subsystem, V.110 * * Copyright by Thomas Pfeiffer (pfeiffer@pds.de) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #include <linux/string.h> @@ -16,11 +13,10 @@ #include <linux/isdn.h> #include "isdn_v110.h" +#include "isdn_common.h" #undef ISDN_V110_DEBUG -char *isdn_v110_revision = "$Revision: 1.5.6.4 $"; - #define V110_38400 255 #define V110_19200 15 #define V110_9600 3 @@ -86,7 +82,7 @@ FlipBits(unsigned char c, int keylen) * structures and returns a pointer to these. */ static isdn_v110_stream * -isdn_v110_open(unsigned char key, int hdrlen, int maxsize) +do_isdn_v110_open(unsigned char key, int hdrlen, int maxsize) { int i; isdn_v110_stream *v; @@ -131,8 +127,8 @@ isdn_v110_open(unsigned char key, int hdrlen, int maxsize) } /* isdn_v110_close frees private V.110 data structures */ -void -isdn_v110_close(isdn_v110_stream * v) +static void +do_isdn_v110_close(isdn_v110_stream * v) { if (v == NULL) return; @@ -514,99 +510,94 @@ buffer_full: return nskb; } + +void +isdn_v110_open(struct isdn_slot *slot, struct isdn_v110 *iv110) +{ + isdn_v110_stream *v; + int hdrlen = isdn_slot_hdrlen(slot); + int maxsize = isdn_slot_maxbufsize(slot); + + atomic_inc(&iv110->v110use); + switch (iv110->v110emu) { + case ISDN_PROTO_L2_V11096: + iv110->v110 = do_isdn_v110_open(V110_9600, hdrlen, maxsize); + break; + case ISDN_PROTO_L2_V11019: + iv110->v110 = do_isdn_v110_open(V110_19200, hdrlen, maxsize); + break; + case ISDN_PROTO_L2_V11038: + iv110->v110 = do_isdn_v110_open(V110_38400, hdrlen, maxsize); + break; + } + if ((v = iv110->v110)) { + while (v->SyncInit) { + struct sk_buff *skb = isdn_v110_sync(v); + if (isdn_slot_write(slot, skb) <= 0) { + dev_kfree_skb(skb); + /* Unable to send, try later */ + break; + } + v->SyncInit--; + v->skbidle++; + } + } else + printk(KERN_WARNING "isdn_v110: Couldn't open stream\n"); + atomic_dec(&iv110->v110use); +} + +void +isdn_v110_close(struct isdn_slot *slot, struct isdn_v110 *iv110) +{ + while (1) { + atomic_inc(&iv110->v110use); + if (atomic_dec_and_test(&iv110->v110use)) { + do_isdn_v110_close(iv110->v110); + iv110->v110 = NULL; + break; + } + } +} + int -isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c) +isdn_v110_bsent(struct isdn_slot *slot, struct isdn_v110 *iv110) { - isdn_v110_stream *v = NULL; - int i; - int ret; - - switch (c->command) { - case ISDN_STAT_BSENT: - /* Keep the send-queue of the driver filled - * with frames: - * If number of outstanding frames < 3, - * send down an Idle-Frame (or an Sync-Frame, if - * v->SyncInit != 0). - */ - if (!(v = iv110->v110)) - return 0; - atomic_inc(&iv110->v110use); - if (v->skbidle > 0) { - v->skbidle--; - ret = 1; + isdn_v110_stream *v = iv110->v110; + int i, ret; + + /* Keep the send-queue of the driver filled + * with frames: + * If number of outstanding frames < 3, + * send down an Idle-Frame (or an Sync-Frame, if + * v->SyncInit != 0). + */ + atomic_inc(&iv110->v110use); + if (v->skbidle > 0) { + v->skbidle--; + ret = 1; + } else { + if (v->skbuser > 0) + v->skbuser--; + ret = 0; + } + for (i = v->skbuser + v->skbidle; i < 2; i++) { + struct sk_buff *skb; + if (v->SyncInit > 0) + skb = isdn_v110_sync(v); + else + skb = isdn_v110_idle(v); + if (skb) { + if (isdn_slot_write(slot, skb) <= 0) { + dev_kfree_skb(skb); + break; } else { - if (v->skbuser > 0) - v->skbuser--; - ret = 0; - } - for (i = v->skbuser + v->skbidle; i < 2; i++) { - struct sk_buff *skb; - if (v->SyncInit > 0) - skb = isdn_v110_sync(v); - else - skb = isdn_v110_idle(v); - if (skb) { - if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) { - dev_kfree_skb(skb); - break; - } else { - if (v->SyncInit) - v->SyncInit--; - v->skbidle++; - } - } else - break; - } - atomic_dec(&iv110->v110use); - return ret; - case ISDN_STAT_DHUP: - case ISDN_STAT_BHUP: - while (1) { - atomic_inc(&iv110->v110use); - if (atomic_dec_and_test(&iv110->v110use)) { - isdn_v110_close(iv110->v110); - iv110->v110 = NULL; - break; - } - sti(); + if (v->SyncInit) + v->SyncInit--; + v->skbidle++; } + } else break; - case ISDN_STAT_BCONN: - if (iv110->v110emu && (iv110->v110 == NULL)) { - int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen; - int maxsize = dev->drv[c->driver]->interface->maxbufsize; - atomic_inc(&iv110->v110use); - switch (iv110->v110emu) { - case ISDN_PROTO_L2_V11096: - iv110->v110 = isdn_v110_open(V110_9600, hdrlen, maxsize); - break; - case ISDN_PROTO_L2_V11019: - iv110->v110 = isdn_v110_open(V110_19200, hdrlen, maxsize); - break; - case ISDN_PROTO_L2_V11038: - iv110->v110 = isdn_v110_open(V110_38400, hdrlen, maxsize); - break; - default:; - } - if ((v = iv110->v110)) { - while (v->SyncInit) { - struct sk_buff *skb = isdn_v110_sync(v); - if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) { - dev_kfree_skb(skb); - /* Unable to send, try later */ - break; - } - v->SyncInit--; - v->skbidle++; - } - } else - printk(KERN_WARNING "isdn_v110: Couldn't open stream\n"); - atomic_dec(&iv110->v110use); - } - break; - default: - return 0; } - return 0; + atomic_dec(&iv110->v110use); + return ret; } diff --git a/drivers/isdn/i4l/isdn_v110.h b/drivers/isdn/i4l/isdn_v110.h index b6563c259e44..36b404f56f48 100644 --- a/drivers/isdn/i4l/isdn_v110.h +++ b/drivers/isdn/i4l/isdn_v110.h @@ -1,12 +1,9 @@ -/* $Id: isdn_v110.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $ - * - * Linux ISDN subsystem, V.110 related functions (linklevel). +/* Linux ISDN subsystem, V.110 related functions * * Copyright by Thomas Pfeiffer (pfeiffer@pds.de) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #ifndef ISDN_V110_H @@ -29,7 +26,10 @@ extern struct sk_buff *isdn_v110_encode(isdn_v110_stream *, struct sk_buff *); */ extern struct sk_buff *isdn_v110_decode(isdn_v110_stream *, struct sk_buff *); -extern int isdn_v110_stat_callback(struct isdn_v110 *v110, isdn_ctrl *); -extern void isdn_v110_close(isdn_v110_stream * v); +extern void isdn_v110_open(struct isdn_slot *slot, struct isdn_v110 *iv110); + +extern void isdn_v110_close(struct isdn_slot *slot, struct isdn_v110 *iv110); + +extern int isdn_v110_bsent(struct isdn_slot *slot, struct isdn_v110 *iv110); #endif diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index edbf4eed016d..d394b4a39bd4 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c @@ -1,10 +1,10 @@ -/* $Id: isdn_x25iface.c,v 1.9.6.1 2001/09/23 22:24:32 kai Exp $ - * - * Linux ISDN subsystem, X.25 related functions +/* * Linux ISDN subsystem, X.25 related functions * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * + */ + +/* * stuff needed to support the Linux X.25 PLP code on top of devices that * can provide a lab_b service using the concap_proto mechanism. * This module supports a network interface wich provides lapb_sematics @@ -17,7 +17,6 @@ * */ -/* #include <linux/isdn.h> */ #include <linux/netdevice.h> #include <linux/concap.h> #include <linux/wanrouter.h> diff --git a/drivers/isdn/i4l/isdn_x25iface.h b/drivers/isdn/i4l/isdn_x25iface.h index ef69d3af9628..12fc46c471af 100644 --- a/drivers/isdn/i4l/isdn_x25iface.h +++ b/drivers/isdn/i4l/isdn_x25iface.h @@ -1,17 +1,16 @@ -/* $Id: isdn_x25iface.h,v 1.3.6.1 2001/09/23 22:24:32 kai Exp $ - * - * header for Linux ISDN subsystem, x.25 related functions +/* Linux ISDN subsystem, x.25 related functions * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #ifndef _LINUX_ISDN_X25IFACE_H #define _LINUX_ISDN_X25IFACE_H #define ISDN_X25IFACE_MAGIC 0x1e75a2b9 -/* #define DEBUG_ISDN_X25 if you want isdn_x25 debugging messages */ + +#undef DEBUG_ISDN_X25 + #ifdef DEBUG_ISDN_X25 # define IX25DEBUG(fmt,args...) printk(KERN_DEBUG fmt , ## args) #else @@ -26,8 +25,6 @@ extern struct concap_proto_ops * isdn_x25iface_concap_proto_ops_pt; extern struct concap_proto * isdn_x25iface_proto_new(void); - - #endif diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index fb1f030d9c92..ef49d7201cc2 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -424,7 +424,6 @@ static icn_stat icn_stat_table[] = {"AOC", ISDN_STAT_CINF, 6}, /* Charge-info, DSS1-type */ {"CAU", ISDN_STAT_CAUSE, 7}, /* Cause code */ {"TEI OK", ISDN_STAT_RUN, 0}, /* Card connected to wallplug */ - {"NO D-CHAN", ISDN_STAT_NODCH, 0}, /* No D-channel available */ {"E_L1: ACT FAIL", ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ {"E_L2: DATA LIN", ISDN_STAT_BHUP, 8}, /* Layer-2 data link lost */ {"E_L1: ACTIVATION FAILED", diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 612c7b19c85a..ce799f4cb3a7 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -71,9 +71,6 @@ isdnloop_bchan_send(isdnloop_card * card, int ch) printk(KERN_WARNING "isdnloop: no rcard, skb dropped\n"); dev_kfree_skb(skb); - cmd.command = ISDN_STAT_L1ERR; - cmd.parm.errcode = ISDN_STAT_L1ERR_SEND; - card->interface.statcallb(&cmd); }; cmd.command = ISDN_STAT_BSENT; cmd.parm.length = len; @@ -166,7 +163,6 @@ static isdnloop_stat isdnloop_stat_table[] = {"AOC", ISDN_STAT_CINF, 6}, /* Charge-info, DSS1-type */ {"CAU", ISDN_STAT_CAUSE, 7}, /* Cause code */ {"TEI OK", ISDN_STAT_RUN, 0}, /* Card connected to wallplug */ - {"NO D-CHAN", ISDN_STAT_NODCH, 0}, /* No D-channel available */ {"E_L1: ACT FAIL", ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */ {"E_L2: DATA LIN", ISDN_STAT_BHUP, 8}, /* Layer-2 data link lost */ {"E_L1: ACTIVATION FAILED", @@ -1339,6 +1335,9 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) case ISDN_PROTO_L2_HDLC: sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1); break; + case ISDN_PROTO_L2_TRANS: + sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1); + break; default: return -EINVAL; } diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 3a68e91717de..d49f8d0fe742 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -220,7 +220,7 @@ static int cpia_usb_open(void *privdata) urb->dev = ucpia->dev; urb->context = ucpia; urb->pipe = usb_rcvisocpipe(ucpia->dev, 1); - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ucpia->sbuf[0].data; urb->complete = cpia_usb_complete; urb->number_of_packets = FRAMES_PER_DESC; @@ -242,7 +242,7 @@ static int cpia_usb_open(void *privdata) urb->dev = ucpia->dev; urb->context = ucpia; urb->pipe = usb_rcvisocpipe(ucpia->dev, 1); - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ucpia->sbuf[1].data; urb->complete = cpia_usb_complete; urb->number_of_packets = FRAMES_PER_DESC; diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index cddfe9c33804..058f8024384b 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -41,7 +41,7 @@ * This driver has NOT been tested with the following drivers : * o ehci-hcd (USB 2.0 controllers) * - * Note that all HCD drivers do USB_ZERO_PACKET and timeout properly, + * Note that all HCD drivers do URB_ZERO_PACKET and timeout properly, * so we don't have to worry about that anymore. * One common problem is the failure to set the address on the dongle, * but this happens before the driver gets loaded... @@ -265,12 +265,12 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) irda_usb_build_header(self, frame, 1); /* Submit the 0 length IrDA frame to trigger new speed settings */ - FILL_BULK_URB(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), frame, IRDA_USB_SPEED_MTU, speed_bulk_callback, self); urb->transfer_buffer_length = USB_IRDA_HEADER; - urb->transfer_flags = USB_ASYNC_UNLINK; + urb->transfer_flags = URB_ASYNC_UNLINK; urb->timeout = MSECS_TO_JIFFIES(100); /* Irq disabled -> GFP_ATOMIC */ @@ -400,20 +400,20 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* FIXME: Make macro out of this one */ ((struct irda_skb_cb *)skb->cb)->context = self; - FILL_BULK_URB(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), skb->data, IRDA_USB_MAX_MTU, write_bulk_callback, skb); urb->transfer_buffer_length = skb->len; /* Note : unlink *must* be Asynchronous because of the code in * irda_usb_net_timeout() -> call in irq - Jean II */ - urb->transfer_flags = USB_ASYNC_UNLINK; - /* This flag (USB_ZERO_PACKET) indicates that what we send is not + urb->transfer_flags = URB_ASYNC_UNLINK; + /* This flag (URB_ZERO_PACKET) indicates that what we send is not * a continuous stream of data but separate packets. * In this case, the USB layer will insert an empty USB frame (TD) * after each of our packets that is exact multiple of the frame size. * This is how the dongle will detect the end of packet - Jean II */ - urb->transfer_flags |= USB_ZERO_PACKET; + urb->transfer_flags |= URB_ZERO_PACKET; /* Timeout need to be shorter than NET watchdog timer */ urb->timeout = MSECS_TO_JIFFIES(200); @@ -634,7 +634,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) * be -ENOENT. We will fix that at the next watchdog, * leaving more time to USB to recover... * Also, we are in interrupt, so we need to have - * USB_ASYNC_UNLINK to work properly... + * URB_ASYNC_UNLINK to work properly... * Jean II */ done = 1; break; @@ -729,7 +729,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc cb->context = self; /* Reinitialize URB */ - FILL_BULK_URB(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_rcvbulkpipe(self->usbdev, self->bulk_in_ep), skb->data, skb->truesize, irda_usb_receive, skb); @@ -1016,9 +1016,9 @@ static int irda_usb_net_close(struct net_device *netdev) } } /* Cancel Tx and speed URB - need to be synchronous to avoid races */ - self->tx_urb->transfer_flags &= ~USB_ASYNC_UNLINK; + self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK; usb_unlink_urb(self->tx_urb); - self->speed_urb->transfer_flags &= ~USB_ASYNC_UNLINK; + self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK; usb_unlink_urb(self->speed_urb); /* Stop and remove instance of IrLAP */ @@ -1258,7 +1258,7 @@ static inline int irda_usb_close(struct irda_usb_cb *self) * Most dongle have also an interrupt endpoint, that will be probably * documented in the next spec... */ -static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_endpoint_descriptor *endpoint, int ennum) +static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_host_endpoint *endpoint, int ennum) { int i; /* Endpoint index in table */ @@ -1277,10 +1277,10 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ __u16 psize; /* Endpoint max packet size in bytes */ /* Get endpoint address, direction and attribute */ - ep = endpoint[i].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - dir = endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK; - attr = endpoint[i].bmAttributes; - psize = endpoint[i].wMaxPacketSize; + ep = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + dir = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK; + attr = endpoint[i].desc.bmAttributes; + psize = endpoint[i].desc.wMaxPacketSize; /* Is it a bulk endpoint ??? */ if(attr == USB_ENDPOINT_XFER_BULK) { @@ -1366,7 +1366,7 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0), IU_REQ_GET_CLASS_DESC, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, intf->altsetting->bInterfaceNumber, desc, + 0, intf->altsetting->desc.bInterfaceNumber, desc, sizeof(*desc), MSECS_TO_JIFFIES(500)); IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret); @@ -1407,7 +1407,7 @@ static int irda_usb_probe(struct usb_interface *intf, { struct usb_device *dev = interface_to_usbdev(intf); struct irda_usb_cb *self = NULL; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct irda_class_desc *irda_desc; int ret; int i; @@ -1477,7 +1477,7 @@ static int irda_usb_probe(struct usb_interface *intf, } /* Is this really necessary? */ - if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) { + if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { err("set_configuration failed"); return -EIO; } @@ -1486,7 +1486,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Note : some driver do hardcode the interface number, some others * specify an alternate, but very few driver do like this. * Jean II */ - ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0); + ret = usb_set_interface(dev, intf->altsetting->desc.bInterfaceNumber, 0); IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret); switch (ret) { case 0: @@ -1504,7 +1504,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Find our endpoints */ interface = &intf->altsetting[0]; if(!irda_usb_parse_endpoints(self, interface->endpoint, - interface->bNumEndpoints)) { + interface->desc.bNumEndpoints)) { ERROR("%s(), Bogus endpoints...\n", __FUNCTION__); return -EIO; } @@ -1573,9 +1573,9 @@ static void irda_usb_disconnect(struct usb_interface *intf) usb_unlink_urb(self->rx_urb[i]); /* Cancel Tx and speed URB. * Toggle flags to make sure it's synchronous. */ - self->tx_urb->transfer_flags &= ~USB_ASYNC_UNLINK; + self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK; usb_unlink_urb(self->tx_urb); - self->speed_urb->transfer_flags &= ~USB_ASYNC_UNLINK; + self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK; usb_unlink_urb(self->speed_urb); } diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 9519d2c6d54e..950b424ce44b 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -124,16 +124,36 @@ static struct resource *resource_parent(unsigned long b, unsigned long n, return &ioport_resource; } +/* FIXME: Fundamentally racy. */ static inline int check_io_resource(unsigned long b, unsigned long n, struct pci_dev *dev) { - return check_resource(resource_parent(b, n, IORESOURCE_IO, dev), b, n); + struct resource *region; + + region = __request_region(resource_parent(b, n, IORESOURCE_IO, dev), + b, n, "check_io_resource"); + if (!region) + return -EBUSY; + + release_resource(region); + kfree(region); + return 0; } +/* FIXME: Fundamentally racy. */ static inline int check_mem_resource(unsigned long b, unsigned long n, struct pci_dev *dev) { - return check_resource(resource_parent(b, n, IORESOURCE_MEM, dev), b, n); + struct resource *region; + + region = __request_region(resource_parent(b, n, IORESOURCE_MEM, dev), + b, n, "check_mem_resource"); + if (!region) + return -EBUSY; + + release_resource(region); + kfree(region); + return 0; } static struct resource *make_resource(unsigned long b, unsigned long n, diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9a7766fc9c6b..c43ab0c28946 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -58,7 +58,7 @@ * Remaining dev_t-handling stuff */ #define SD_MAJORS 8 -#define SD_MAJOR(i) ((i) ? SCSI_DISK1_MAJOR+(i) : SCSI_DISK0_MAJOR) +#define SD_MAJOR(i) ((i) ? SCSI_DISK1_MAJOR-1+(i) : SCSI_DISK0_MAJOR) /* * Time out in seconds for disks and Magneto-opticals (which are slower). diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 41b049b9bd10..4517d61f925d 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -1049,7 +1049,7 @@ static int usbin_start(struct usb_audiodev *as) urb = u->durb[0].urb; urb->dev = dev; urb->pipe = u->datapipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbin_completed; @@ -1062,7 +1062,7 @@ static int usbin_start(struct usb_audiodev *as) urb = u->durb[1].urb; urb->dev = dev; urb->pipe = u->datapipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbin_completed; @@ -1076,7 +1076,7 @@ static int usbin_start(struct usb_audiodev *as) urb = u->surb[0].urb; urb->dev = dev; urb->pipe = u->syncpipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = SYNCFRAMES; urb->context = as; urb->complete = usbin_sync_completed; @@ -1090,7 +1090,7 @@ static int usbin_start(struct usb_audiodev *as) urb = u->surb[1].urb; urb->dev = dev; urb->pipe = u->syncpipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = SYNCFRAMES; urb->context = as; urb->complete = usbin_sync_completed; @@ -1416,7 +1416,7 @@ static int usbout_start(struct usb_audiodev *as) urb = u->durb[0].urb; urb->dev = dev; urb->pipe = u->datapipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbout_completed; @@ -1429,7 +1429,7 @@ static int usbout_start(struct usb_audiodev *as) urb = u->durb[1].urb; urb->dev = dev; urb->pipe = u->datapipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbout_completed; @@ -1443,7 +1443,7 @@ static int usbout_start(struct usb_audiodev *as) urb = u->surb[0].urb; urb->dev = dev; urb->pipe = u->syncpipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = SYNCFRAMES; urb->context = as; urb->complete = usbout_sync_completed; @@ -1457,7 +1457,7 @@ static int usbout_start(struct usb_audiodev *as) urb = u->surb[1].urb; urb->dev = dev; urb->pipe = u->syncpipe; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = SYNCFRAMES; urb->context = as; urb->complete = usbout_sync_completed; @@ -1512,8 +1512,8 @@ static int find_format(struct audioformat *afp, unsigned int nr, unsigned int fm static int set_format_in(struct usb_audiodev *as) { struct usb_device *dev = as->state->usbdev; - struct usb_config_descriptor *config = dev->actconfig; - struct usb_interface_descriptor *alts; + struct usb_host_config *config = dev->actconfig; + struct usb_host_interface *alts; struct usb_interface *iface; struct usbin *u = &as->usbin; struct dmabuf *d = &u->dma; @@ -1522,7 +1522,7 @@ static int set_format_in(struct usb_audiodev *as) unsigned char data[3]; int fmtnr, ret; - if (u->interface < 0 || u->interface >= config->bNumInterfaces) + if (u->interface < 0 || u->interface >= config->desc.bNumInterfaces) return 0; iface = &config->interface[u->interface]; @@ -1535,26 +1535,26 @@ static int set_format_in(struct usb_audiodev *as) fmt = as->fmtin + fmtnr; alts = &iface->altsetting[fmt->altsetting]; u->format = fmt->format; - u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf); + u->datapipe = usb_rcvisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf); u->syncpipe = u->syncinterval = 0; - if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x08) { - if (alts->bNumEndpoints < 2 || - alts->endpoint[1].bmAttributes != 0x01 || - alts->endpoint[1].bSynchAddress != 0 || - alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) { + if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x08) { + if (alts->desc.bNumEndpoints < 2 || + alts->endpoint[1].desc.bmAttributes != 0x01 || + alts->endpoint[1].desc.bSynchAddress != 0 || + alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress & 0x7f)) { printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); return -1; } - u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf); - u->syncinterval = alts->endpoint[1].bRefresh; + u->syncpipe = usb_sndisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].desc.bRefresh; } if (d->srate < fmt->sratelo) d->srate = fmt->sratelo; if (d->srate > fmt->sratehi) d->srate = fmt->sratehi; - dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting)); - if (usb_set_interface(dev, alts->bInterfaceNumber, fmt->altsetting) < 0) { + dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", alts->desc.bInterfaceNumber, fmt->altsetting)); + if (usb_set_interface(dev, alts->desc.bInterfaceNumber, fmt->altsetting) < 0) { printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", dev->devnum, u->interface, fmt->altsetting); return -1; @@ -1600,8 +1600,8 @@ static int set_format_in(struct usb_audiodev *as) static int set_format_out(struct usb_audiodev *as) { struct usb_device *dev = as->state->usbdev; - struct usb_config_descriptor *config = dev->actconfig; - struct usb_interface_descriptor *alts; + struct usb_host_config *config = dev->actconfig; + struct usb_host_interface *alts; struct usb_interface *iface; struct usbout *u = &as->usbout; struct dmabuf *d = &u->dma; @@ -1610,7 +1610,7 @@ static int set_format_out(struct usb_audiodev *as) unsigned char data[3]; int fmtnr, ret; - if (u->interface < 0 || u->interface >= config->bNumInterfaces) + if (u->interface < 0 || u->interface >= config->desc.bNumInterfaces) return 0; iface = &config->interface[u->interface]; @@ -1623,9 +1623,9 @@ static int set_format_out(struct usb_audiodev *as) fmt = as->fmtout + fmtnr; u->format = fmt->format; alts = &iface->altsetting[fmt->altsetting]; - u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].bEndpointAddress & 0xf); + u->datapipe = usb_sndisocpipe(dev, alts->endpoint[0].desc.bEndpointAddress & 0xf); u->syncpipe = u->syncinterval = 0; - if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x04) { + if ((alts->endpoint[0].desc.bmAttributes & 0x0c) == 0x04) { #if 0 printk(KERN_DEBUG "bNumEndpoints 0x%02x endpoint[1].bmAttributes 0x%02x\n" KERN_DEBUG "endpoint[1].bSynchAddress 0x%02x endpoint[1].bEndpointAddress 0x%02x\n" @@ -1633,22 +1633,22 @@ static int set_format_out(struct usb_audiodev *as) alts->endpoint[1].bmAttributes, alts->endpoint[1].bSynchAddress, alts->endpoint[1].bEndpointAddress, alts->endpoint[0].bSynchAddress); #endif - if (alts->bNumEndpoints < 2 || - alts->endpoint[1].bmAttributes != 0x01 || - alts->endpoint[1].bSynchAddress != 0 || - alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) { + if (alts->desc.bNumEndpoints < 2 || + alts->endpoint[1].desc.bmAttributes != 0x01 || + alts->endpoint[1].desc.bSynchAddress != 0 || + alts->endpoint[1].desc.bEndpointAddress != (alts->endpoint[0].desc.bSynchAddress | 0x80)) { printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); return -1; } - u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].bEndpointAddress & 0xf); - u->syncinterval = alts->endpoint[1].bRefresh; + u->syncpipe = usb_rcvisocpipe(dev, alts->endpoint[1].desc.bEndpointAddress & 0xf); + u->syncinterval = alts->endpoint[1].desc.bRefresh; } if (d->srate < fmt->sratelo) d->srate = fmt->sratelo; if (d->srate > fmt->sratehi) d->srate = fmt->sratehi; - dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting)); + dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", alts->desc.bInterfaceNumber, fmt->altsetting)); if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) { printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n", dev->devnum, u->interface, fmt->altsetting); @@ -2705,7 +2705,7 @@ static int usb_audio_release(struct inode *inode, struct file *file) usbout_stop(as); if (dev && as->usbout.interface >= 0) { iface = &dev->actconfig->interface[as->usbout.interface]; - usb_set_interface(dev, iface->altsetting->bInterfaceNumber, 0); + usb_set_interface(dev, iface->altsetting->desc.bInterfaceNumber, 0); } dmabuf_release(&as->usbout.dma); usbout_release(as); @@ -2714,7 +2714,7 @@ static int usb_audio_release(struct inode *inode, struct file *file) usbin_stop(as); if (dev && as->usbin.interface >= 0) { iface = &dev->actconfig->interface[as->usbin.interface]; - usb_set_interface(dev, iface->altsetting->bInterfaceNumber, 0); + usb_set_interface(dev, iface->altsetting->desc.bInterfaceNumber, 0); } dmabuf_release(&as->usbin.dma); usbin_release(as); @@ -2819,8 +2819,8 @@ static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *b { struct usb_device *dev = s->usbdev; struct usb_audiodev *as; - struct usb_config_descriptor *config = dev->actconfig; - struct usb_interface_descriptor *alts; + struct usb_host_config *config = dev->actconfig; + struct usb_host_interface *alts; struct usb_interface *iface; struct audioformat *fp; unsigned char *fmt, *csep; @@ -2868,17 +2868,17 @@ static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *b iface = &config->interface[asifin]; for (i = 0; i < iface->num_altsetting; i++) { alts = &iface->altsetting[i]; - if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) + if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2) continue; - if (alts->bNumEndpoints < 1) { + if (alts->desc.bNumEndpoints < 1) { if (i != 0) { /* altsetting 0 has no endpoints (Section B.3.4.1) */ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", dev->devnum, asifin, i); } continue; } - if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || - !(alts->endpoint[0].bEndpointAddress & 0x80)) { + if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 || + !(alts->endpoint[0].desc.bEndpointAddress & 0x80)) { printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous in\n", dev->devnum, asifin, i); continue; @@ -2949,15 +2949,15 @@ static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *b iface = &config->interface[asifout]; for (i = 0; i < iface->num_altsetting; i++) { alts = &iface->altsetting[i]; - if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) + if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || alts->desc.bInterfaceSubClass != 2) continue; - if (alts->bNumEndpoints < 1) { + if (alts->desc.bNumEndpoints < 1) { printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", dev->devnum, asifout, i); continue; } - if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || - (alts->endpoint[0].bEndpointAddress & 0x80)) { + if ((alts->endpoint[0].desc.bmAttributes & 0x03) != 0x01 || + (alts->endpoint[0].desc.bEndpointAddress & 0x80)) { printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous out\n", dev->devnum, asifout, i); continue; @@ -3642,10 +3642,13 @@ static void usb_audio_constructmixer(struct usb_audio_state *s, unsigned char *b list_add_tail(&ms->list, &s->mixerlist); } +/* arbitrary limit, we won't check more interfaces than this */ +#define USB_MAXINTERFACES 32 + static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) { struct usb_audio_state *s; - struct usb_config_descriptor *config = dev->actconfig; + struct usb_host_config *config = dev->actconfig; struct usb_interface *iface; unsigned char ifin[USB_MAXINTERFACES], ifout[USB_MAXINTERFACES]; unsigned char *p1; @@ -3675,23 +3678,23 @@ static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, un dev->devnum, ctrlif); for (i = 0; i < p1[7]; i++) { j = p1[8+i]; - if (j >= config->bNumInterfaces) { + if (j >= config->desc.bNumInterfaces) { printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u does not exist\n", dev->devnum, ctrlif, j); continue; } iface = &config->interface[j]; - if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO) { + if (iface->altsetting[0].desc.bInterfaceClass != USB_CLASS_AUDIO) { printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n", dev->devnum, ctrlif, j); continue; } - if (iface->altsetting[0].bInterfaceSubClass == 3) { + if (iface->altsetting[0].desc.bInterfaceSubClass == 3) { printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n", dev->devnum, ctrlif, j); continue; } - if (iface->altsetting[0].bInterfaceSubClass != 2) { + if (iface->altsetting[0].desc.bInterfaceSubClass != 2) { printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n", dev->devnum, ctrlif, j); continue; @@ -3704,25 +3707,25 @@ static struct usb_audio_state *usb_audio_parsecontrol(struct usb_device *dev, un printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u has only 1 altsetting.\n", dev->devnum, ctrlif); continue; } - if (iface->altsetting[0].bNumEndpoints > 0) { + if (iface->altsetting[0].desc.bNumEndpoints > 0) { /* Check all endpoints; should they all have a bandwidth of 0 ? */ - for (k = 0; k < iface->altsetting[0].bNumEndpoints; k++) { - if (iface->altsetting[0].endpoint[k].wMaxPacketSize > 0) { + for (k = 0; k < iface->altsetting[0].desc.bNumEndpoints; k++) { + if (iface->altsetting[0].endpoint[k].desc.wMaxPacketSize > 0) { printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u endpoint %d does not have 0 bandwidth at alt[0]\n", dev->devnum, ctrlif, k); break; } } - if (k < iface->altsetting[0].bNumEndpoints) + if (k < iface->altsetting[0].desc.bNumEndpoints) continue; } - if (iface->altsetting[1].bNumEndpoints < 1) { + if (iface->altsetting[1].desc.bNumEndpoints < 1) { printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n", dev->devnum, ctrlif, j); continue; } /* note: this requires the data endpoint to be ep0 and the optional sync ep to be ep1, which seems to be the case */ - if (iface->altsetting[1].endpoint[0].bEndpointAddress & USB_DIR_IN) { + if (iface->altsetting[1].endpoint[0].desc.bEndpointAddress & USB_DIR_IN) { if (numifin < USB_MAXINTERFACES) { ifin[numifin++] = j; usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); @@ -3769,7 +3772,7 @@ static int usb_audio_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev (intf); - struct usb_config_descriptor *config = dev->actconfig; + struct usb_host_config *config = dev->actconfig; struct usb_audio_state *s; unsigned char *buffer; unsigned char buf[8]; @@ -3778,8 +3781,8 @@ static int usb_audio_probe(struct usb_interface *intf, #if 0 printk(KERN_DEBUG "usbaudio: Probing if %i: IC %x, ISC %x\n", ifnum, - config->interface[ifnum].altsetting[0].bInterfaceClass, - config->interface[ifnum].altsetting[0].bInterfaceSubClass); + config->interface[ifnum].altsetting[0].desc.bInterfaceClass, + config->interface[ifnum].altsetting[0].desc.bInterfaceSubClass); #endif /* @@ -3788,8 +3791,8 @@ static int usb_audio_probe(struct usb_interface *intf, */ i = dev->actconfig - config; - if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { - printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue); + if (usb_set_configuration(dev, config->desc.bConfigurationValue) < 0) { + printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->desc.bConfigurationValue); return -EIO; } ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8); @@ -3810,7 +3813,7 @@ static int usb_audio_probe(struct usb_interface *intf, printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret); return -EIO; } - s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->bInterfaceNumber); + s = usb_audio_parsecontrol(dev, buffer, buflen, intf->altsetting->desc.bInterfaceNumber); if (s) { dev_set_drvdata (&intf->dev, s); return 0; diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c index b78fcb009ea4..9f2c5bf28cd2 100644 --- a/drivers/usb/class/bluetty.c +++ b/drivers/usb/class/bluetty.c @@ -328,7 +328,7 @@ static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int dr->wIndex = cpu_to_le16((u16) bluetooth->control_out_bInterfaceNum); dr->wLength = cpu_to_le16((u16) len); - FILL_CONTROL_URB (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0), + usb_fill_control_urb (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0), (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth); /* send it down the pipe */ @@ -382,7 +382,7 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp) #ifndef BTBUGGYHARDWARE /* Start reading from the device */ - FILL_BULK_URB (bluetooth->read_urb, bluetooth->dev, + usb_fill_bulk_urb (bluetooth->read_urb, bluetooth->dev, usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, @@ -391,7 +391,7 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp) if (result) dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result); #endif - FILL_INT_URB (bluetooth->interrupt_in_urb, bluetooth->dev, + usb_fill_int_urb (bluetooth->interrupt_in_urb, bluetooth->dev, usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size, @@ -535,7 +535,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign memcpy (urb->transfer_buffer, current_position, buffer_size); /* build up our urb */ - FILL_BULK_URB (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress), + usb_fill_bulk_urb (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress), urb->transfer_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth); /* send it down the pipe */ @@ -725,7 +725,7 @@ void btusb_enable_bulk_read(struct tty_struct *tty){ } if (bluetooth->read_urb) { - FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); @@ -933,7 +933,7 @@ static void bluetooth_read_bulk_callback (struct urb *urb) if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00) && (data[2] == 0x00) && (data[3] == 0x00)) { urb->actual_length = 0; - FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); @@ -994,7 +994,7 @@ exit: if (!bluetooth || !bluetooth->open_count) return; - FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, + usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); @@ -1053,7 +1053,7 @@ static int usb_bluetooth_probe (struct usb_interface *intf, { struct usb_device *dev = interface_to_usbdev (intf); struct usb_bluetooth *bluetooth = NULL; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *interrupt_in_endpoint[8]; struct usb_endpoint_descriptor *bulk_in_endpoint[8]; @@ -1068,11 +1068,11 @@ static int usb_bluetooth_probe (struct usb_interface *intf, int num_bulk_out = 0; interface = &intf->altsetting[0]; - control_out_endpoint = interface->bInterfaceNumber; + control_out_endpoint = interface->desc.bInterfaceNumber; /* find the endpoints that we need */ - for (i = 0; i < interface->bNumEndpoints; ++i) { - endpoint = &interface->endpoint[i]; + for (i = 0; i < interface->desc.bNumEndpoints; ++i) { + endpoint = &interface->endpoint[i].desc; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) { @@ -1160,7 +1160,7 @@ static int usb_bluetooth_probe (struct usb_interface *intf, err("Couldn't allocate bulk_in_buffer"); goto probe_error; } - FILL_BULK_URB(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), + usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth); endpoint = bulk_out_endpoint[0]; @@ -1196,7 +1196,7 @@ static int usb_bluetooth_probe (struct usb_interface *intf, err("Couldn't allocate interrupt_in_buffer"); goto probe_error; } - FILL_INT_URB(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), + usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback, bluetooth, endpoint->bInterval); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index bdc28ce6e3a4..16e189285585 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -166,7 +166,9 @@ static struct acm *acm_table[ACM_TTY_MINORS]; static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len) { int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), - request, USB_RT_ACM, value, acm->iface[0].altsetting[0].bInterfaceNumber, buf, len, HZ * 5); + request, USB_RT_ACM, value, + acm->iface[0].altsetting[0].desc.bInterfaceNumber, + buf, len, HZ * 5); dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request, value, len, retval); return retval < 0 ? retval : 0; } @@ -528,8 +530,8 @@ static int acm_probe (struct usb_interface *intf, { struct usb_device *dev; struct acm *acm; - struct usb_config_descriptor *cfacm; - struct usb_interface_descriptor *ifcom, *ifdata; + struct usb_host_config *cfacm; + struct usb_host_interface *ifcom, *ifdata; struct usb_endpoint_descriptor *epctrl, *epread, *epwrite; int readsize, ctrlsize, minor, i; unsigned char *buf; @@ -541,7 +543,7 @@ static int acm_probe (struct usb_interface *intf, dbg("probing config %d", cfacm->bConfigurationValue); - if (cfacm->bNumInterfaces != 2 || + if (cfacm->desc.bNumInterfaces != 2 || usb_interface_claimed(cfacm->interface + 0) || usb_interface_claimed(cfacm->interface + 1)) continue; @@ -549,20 +551,20 @@ static int acm_probe (struct usb_interface *intf, ifcom = cfacm->interface[0].altsetting + 0; ifdata = cfacm->interface[1].altsetting + 0; - if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints < 2) { + if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) { ifcom = cfacm->interface[1].altsetting + 0; ifdata = cfacm->interface[0].altsetting + 0; - if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints < 2) + if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) continue; } - if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 || - ifcom->bInterfaceProtocol != 1 || ifcom->bNumEndpoints < 1) + if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 || + ifcom->desc.bInterfaceProtocol != 1 || ifcom->desc.bNumEndpoints < 1) continue; - epctrl = ifcom->endpoint + 0; - epread = ifdata->endpoint + 0; - epwrite = ifdata->endpoint + 1; + epctrl = &ifcom->endpoint[0].desc; + epread = &ifdata->endpoint[0].desc; + epwrite = &ifdata->endpoint[1].desc; if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 || (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 || @@ -570,11 +572,11 @@ static int acm_probe (struct usb_interface *intf, continue; if ((epread->bEndpointAddress & 0x80) != 0x80) { - epread = ifdata->endpoint + 1; - epwrite = ifdata->endpoint + 0; + epread = &ifdata->endpoint[1].desc; + epwrite = &ifdata->endpoint[0].desc; } - usb_set_configuration(dev, cfacm->bConfigurationValue); + usb_set_configuration(dev, cfacm->desc.bConfigurationValue); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (acm_table[minor]) { @@ -630,11 +632,11 @@ static int acm_probe (struct usb_interface *intf, usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress), buf += ctrlsize, readsize, acm_read_bulk, acm); - acm->readurb->transfer_flags |= USB_NO_FSBR; + acm->readurb->transfer_flags |= URB_NO_FSBR; usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress), buf += readsize, acm->writesize, acm_write_bulk, acm); - acm->writeurb->transfer_flags |= USB_NO_FSBR; + acm->writeurb->transfer_flags |= URB_NO_FSBR; info("ttyACM%d: USB ACM device", minor); diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 87d65953ed88..586808aa0f4d 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c @@ -330,7 +330,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len d = ep->usbdev; pipe = usb_sndbulkpipe(d, ep->endpoint); - FILL_BULK_URB( ep->urb, d, pipe, (unsigned char*)buf, len, + usb_fill_bulk_urb( ep->urb, d, pipe, (unsigned char*)buf, len, (usb_complete_t)usb_write_callback, ep ); status = usb_submit_urb(ep->urb, GFP_KERNEL); @@ -1045,7 +1045,7 @@ static struct midi_in_endpoint *alloc_midi_in_endpoint( struct usb_device *d, in kfree(ep); return NULL; } - FILL_BULK_URB( ep->urb, d, + usb_fill_bulk_urb( ep->urb, d, usb_rcvbulkpipe(d, endPoint), (unsigned char *)ep->recvBuf, bufSize, (usb_complete_t)usb_bulk_read, ep ); @@ -1519,7 +1519,7 @@ static int on_bits( unsigned short v ) static int get_alt_setting( struct usb_device *d, int ifnum ) { int alts, alt=0; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *ep; int epin, epout; int i; @@ -1531,8 +1531,8 @@ static int get_alt_setting( struct usb_device *d, int ifnum ) epin = -1; epout = -1; - for ( i=0 ; i<interface->bNumEndpoints ; i++ ) { - ep = &interface->endpoint[i]; + for ( i=0 ; i<interface->desc.bNumEndpoints ; i++ ) { + ep = &interface->endpoint[i].desc; if ( (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ) { continue; } @@ -1778,8 +1778,8 @@ static int alloc_usb_midi_device( struct usb_device *d, struct usb_midi_state *s static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s) { - struct usb_config_descriptor *c = d->actconfig; - struct usb_interface_descriptor *interface; + struct usb_host_config *c = d->actconfig; + struct usb_host_interface *interface; struct usb_midi_device *u; unsigned char buf[USB_DT_CONFIG_SIZE], *buffer; int bufSize; @@ -1794,8 +1794,8 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc for ( i=0 ; i < c->interface[ifnum].num_altsetting; i++ ) { interface = c->interface[ifnum].altsetting + i; - if ( interface->bInterfaceClass != 255 || - interface->bInterfaceSubClass != 0 ) + if ( interface->desc.bInterfaceClass != 255 || + interface->desc.bInterfaceSubClass != 0 ) continue; alts = i; } @@ -1817,7 +1817,7 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc configfound: /* this may not be necessary. */ - if ( usb_set_configuration( d, c->bConfigurationValue ) < 0 ) { + if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) { printk(KERN_INFO "usb-midi: Could not set config.\n"); return -EINVAL; } @@ -1892,8 +1892,8 @@ static int detect_vendor_specific_device( struct usb_device *d, unsigned int ifn **/ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s) { - struct usb_config_descriptor *c = d->actconfig; - struct usb_interface_descriptor *interface; + struct usb_host_config *c = d->actconfig; + struct usb_host_interface *interface; struct usb_midi_device *u; unsigned char buf[USB_DT_CONFIG_SIZE], *buffer; int bufSize; @@ -1904,8 +1904,8 @@ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct for ( i=0 ; i < c->interface[ifnum].num_altsetting; i++ ) { interface = c->interface[ifnum].altsetting + i; - if ( interface->bInterfaceClass != USB_CLASS_AUDIO || - interface->bInterfaceSubClass != USB_SUBCLASS_MIDISTREAMING ) + if ( interface->desc.bInterfaceClass != USB_CLASS_AUDIO || + interface->desc.bInterfaceSubClass != USB_SUBCLASS_MIDISTREAMING ) continue; alts = i; } @@ -1927,7 +1927,7 @@ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct configfound: /* this may not be necessary. */ - if ( usb_set_configuration( d, c->bConfigurationValue ) < 0 ) { + if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) { printk(KERN_INFO "usb-midi: Could not set config.\n"); return -EINVAL; } @@ -2025,7 +2025,7 @@ static int usb_midi_probe(struct usb_interface *intf, { struct usb_midi_state *s; struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->bInterfaceNumber; + int ifnum = intf->altsetting->desc.bInterfaceNumber; s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL); if ( !s ) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 0d9719dffe22..2fa6283fc107 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -814,7 +814,7 @@ static int usblp_probe(struct usb_interface *intf, usblp->dev = dev; init_MUTEX (&usblp->sem); init_waitqueue_head(&usblp->wait); - usblp->ifnum = intf->altsetting->bInterfaceNumber; + usblp->ifnum = intf->altsetting->desc.bInterfaceNumber; retval = usb_register_dev(&usblp_fops, USBLP_MINOR_BASE, 1, &usblp->minor); if (retval) { @@ -931,7 +931,7 @@ abort: static int usblp_select_alts(struct usblp *usblp) { struct usb_interface *if_alt; - struct usb_interface_descriptor *ifd; + struct usb_host_interface *ifd; struct usb_endpoint_descriptor *epd, *epwrite, *epread; int p, i, e; @@ -944,17 +944,17 @@ static int usblp_select_alts(struct usblp *usblp) for (i = 0; i < if_alt->num_altsetting; i++) { ifd = &if_alt->altsetting[i]; - if (ifd->bInterfaceClass != 7 || ifd->bInterfaceSubClass != 1) + if (ifd->desc.bInterfaceClass != 7 || ifd->desc.bInterfaceSubClass != 1) continue; - if (ifd->bInterfaceProtocol < USBLP_FIRST_PROTOCOL || - ifd->bInterfaceProtocol > USBLP_LAST_PROTOCOL) + if (ifd->desc.bInterfaceProtocol < USBLP_FIRST_PROTOCOL || + ifd->desc.bInterfaceProtocol > USBLP_LAST_PROTOCOL) continue; /* Look for bulk OUT and IN endpoints. */ epwrite = epread = 0; - for (e = 0; e < ifd->bNumEndpoints; e++) { - epd = &ifd->endpoint[e]; + for (e = 0; e < ifd->desc.bNumEndpoints; e++) { + epd = &ifd->endpoint[e].desc; if ((epd->bmAttributes&USB_ENDPOINT_XFERTYPE_MASK)!= USB_ENDPOINT_XFER_BULK) @@ -969,12 +969,12 @@ static int usblp_select_alts(struct usblp *usblp) } /* Ignore buggy hardware without the right endpoints. */ - if (!epwrite || (ifd->bInterfaceProtocol > 1 && !epread)) + if (!epwrite || (ifd->desc.bInterfaceProtocol > 1 && !epread)) continue; /* Turn off reads for 7/1/1 (unidirectional) interfaces * and buggy bidirectional printers. */ - if (ifd->bInterfaceProtocol == 1) { + if (ifd->desc.bInterfaceProtocol == 1) { epread = NULL; } else if (usblp->quirks & USBLP_QUIRK_BIDIR) { info("Disabling reads from problem bidirectional " @@ -982,9 +982,9 @@ static int usblp_select_alts(struct usblp *usblp) epread = NULL; } - usblp->protocol[ifd->bInterfaceProtocol].alt_setting = i; - usblp->protocol[ifd->bInterfaceProtocol].epwrite = epwrite; - usblp->protocol[ifd->bInterfaceProtocol].epread = epread; + usblp->protocol[ifd->desc.bInterfaceProtocol].alt_setting = i; + usblp->protocol[ifd->desc.bInterfaceProtocol].epwrite = epwrite; + usblp->protocol[ifd->desc.bInterfaceProtocol].epread = epread; } /* If our requested protocol is supported, then use it. */ @@ -1018,7 +1018,7 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) return r; } - FILL_BULK_URB(usblp->writeurb, usblp->dev, + usb_fill_bulk_urb(usblp->writeurb, usblp->dev, usb_sndbulkpipe(usblp->dev, usblp->protocol[protocol].epwrite->bEndpointAddress), usblp->buf, 0, @@ -1026,7 +1026,7 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol) usblp->bidir = (usblp->protocol[protocol].epread != 0); if (usblp->bidir) - FILL_BULK_URB(usblp->readurb, usblp->dev, + usb_fill_bulk_urb(usblp->readurb, usblp->dev, usb_rcvbulkpipe(usblp->dev, usblp->protocol[protocol].epread->bEndpointAddress), usblp->buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 2598edc8d9c1..cdc0c665c63a 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -4,7 +4,16 @@ #include <linux/slab.h> #include <asm/byteorder.h> -static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size) + +#define USB_MAXALTSETTING 128 /* Hard limit */ +#define USB_MAXENDPOINTS 30 /* Hard limit */ + +/* these maximums are arbitrary */ +#define USB_MAXCONFIG 8 +#define USB_ALTSETTINGALLOC 4 +#define USB_MAXINTERFACES 32 + +static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size) { struct usb_descriptor_header *header; unsigned char *begin; @@ -20,17 +29,17 @@ static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned } if (header->bDescriptorType != USB_DT_ENDPOINT) { - warn("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X", - endpoint->bDescriptorType, USB_DT_ENDPOINT); + warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X", + header->bDescriptorType, USB_DT_ENDPOINT); return parsed; } if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) - memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE); + memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE); else - memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE); + memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE); - le16_to_cpus(&endpoint->wMaxPacketSize); + le16_to_cpus(&endpoint->desc.wMaxPacketSize); buffer += header->bLength; size -= header->bLength; @@ -93,7 +102,7 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b { int i, len, numskipped, retval, parsed = 0; struct usb_descriptor_header *header; - struct usb_interface_descriptor *ifp; + struct usb_host_interface *ifp; unsigned char *begin; interface->act_altsetting = 0; @@ -108,6 +117,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b } while (size > 0) { + struct usb_interface_descriptor *d; + if (interface->num_altsetting >= interface->max_altsetting) { void *ptr; int oldmas; @@ -141,9 +152,9 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE); /* Skip over the interface */ - buffer += ifp->bLength; - parsed += ifp->bLength; - size -= ifp->bLength; + buffer += ifp->desc.bLength; + parsed += ifp->desc.bLength; + size -= ifp->desc.bLength; begin = buffer; numskipped = 0; @@ -196,23 +207,23 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b (header->bDescriptorType == USB_DT_DEVICE))) return parsed; - if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { + if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) { warn("too many endpoints"); return -1; } - ifp->endpoint = (struct usb_endpoint_descriptor *) - kmalloc(ifp->bNumEndpoints * - sizeof(struct usb_endpoint_descriptor), GFP_KERNEL); + ifp->endpoint = (struct usb_host_endpoint *) + kmalloc(ifp->desc.bNumEndpoints * + sizeof(struct usb_host_endpoint), GFP_KERNEL); if (!ifp->endpoint) { err("out of memory"); return -1; } - memset(ifp->endpoint, 0, ifp->bNumEndpoints * - sizeof(struct usb_endpoint_descriptor)); + memset(ifp->endpoint, 0, ifp->desc.bNumEndpoints * + sizeof(struct usb_host_endpoint)); - for (i = 0; i < ifp->bNumEndpoints; i++) { + for (i = 0; i < ifp->desc.bNumEndpoints; i++) { header = (struct usb_descriptor_header *)buffer; if (header->bLength > size) { @@ -230,49 +241,49 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b } /* We check to see if it's an alternate to this one */ - ifp = (struct usb_interface_descriptor *)buffer; - if (size < USB_DT_INTERFACE_SIZE || - ifp->bDescriptorType != USB_DT_INTERFACE || - !ifp->bAlternateSetting) + d = (struct usb_interface_descriptor *)buffer; + if (size < USB_DT_INTERFACE_SIZE + || d->bDescriptorType != USB_DT_INTERFACE + || !d->bAlternateSetting) return parsed; } return parsed; } -int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer) +int usb_parse_configuration(struct usb_host_config *config, char *buffer) { int i, retval, size; struct usb_descriptor_header *header; - memcpy(config, buffer, USB_DT_CONFIG_SIZE); - le16_to_cpus(&config->wTotalLength); - size = config->wTotalLength; + memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + le16_to_cpus(&config->desc.wTotalLength); + size = config->desc.wTotalLength; - if (config->bNumInterfaces > USB_MAXINTERFACES) { + if (config->desc.bNumInterfaces > USB_MAXINTERFACES) { warn("too many interfaces"); return -1; } config->interface = (struct usb_interface *) - kmalloc(config->bNumInterfaces * + kmalloc(config->desc.bNumInterfaces * sizeof(struct usb_interface), GFP_KERNEL); - dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces); + dbg("kmalloc IF %p, numif %i", config->interface, config->desc.bNumInterfaces); if (!config->interface) { err("out of memory"); return -1; } memset(config->interface, 0, - config->bNumInterfaces * sizeof(struct usb_interface)); + config->desc.bNumInterfaces * sizeof(struct usb_interface)); - buffer += config->bLength; - size -= config->bLength; + buffer += config->desc.bLength; + size -= config->desc.bLength; config->extra = NULL; config->extralen = 0; - for (i = 0; i < config->bNumInterfaces; i++) { + for (i = 0; i < config->desc.bNumInterfaces; i++) { int numskipped, len; char *begin; @@ -351,12 +362,12 @@ void usb_destroy_configuration(struct usb_device *dev) } for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { - struct usb_config_descriptor *cf = &dev->config[c]; + struct usb_host_config *cf = &dev->config[c]; if (!cf->interface) break; - for (i = 0; i < cf->bNumInterfaces; i++) { + for (i = 0; i < cf->desc.bNumInterfaces; i++) { struct usb_interface *ifp = &cf->interface[i]; @@ -364,7 +375,7 @@ void usb_destroy_configuration(struct usb_device *dev) break; for (j = 0; j < ifp->num_altsetting; j++) { - struct usb_interface_descriptor *as = + struct usb_host_interface *as = &ifp->altsetting[j]; if(as->extra) { @@ -374,7 +385,7 @@ void usb_destroy_configuration(struct usb_device *dev) if (!as->endpoint) break; - for(k = 0; k < as->bNumEndpoints; k++) { + for(k = 0; k < as->desc.bNumEndpoints; k++) { if(as->endpoint[k].extra) { kfree(as->endpoint[k].extra); } @@ -410,15 +421,15 @@ int usb_get_configuration(struct usb_device *dev) return -EINVAL; } - dev->config = (struct usb_config_descriptor *) + dev->config = (struct usb_host_config *) kmalloc(dev->descriptor.bNumConfigurations * - sizeof(struct usb_config_descriptor), GFP_KERNEL); + sizeof(struct usb_host_config), GFP_KERNEL); if (!dev->config) { err("out of memory"); return -ENOMEM; } memset(dev->config, 0, dev->descriptor.bNumConfigurations * - sizeof(struct usb_config_descriptor)); + sizeof(struct usb_host_config)); dev->rawdescriptors = (char **)kmalloc(sizeof(char *) * dev->descriptor.bNumConfigurations, GFP_KERNEL); diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 1e819db95786..3d4c29b579b4 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -234,7 +234,7 @@ static char *usb_dump_endpoint_descriptor ( static char *usb_dump_interface_descriptor(char *start, char *end, const struct usb_interface *iface, int setno) { - struct usb_interface_descriptor *desc = &iface->altsetting[setno]; + struct usb_interface_descriptor *desc = &iface->altsetting[setno].desc; if (start > end) return start; @@ -259,15 +259,15 @@ static char *usb_dump_interface( const struct usb_interface *iface, int setno ) { - struct usb_interface_descriptor *desc = &iface->altsetting[setno]; + struct usb_host_interface *desc = &iface->altsetting[setno]; int i; start = usb_dump_interface_descriptor(start, end, iface, setno); - for (i = 0; i < desc->bNumEndpoints; i++) { + for (i = 0; i < desc->desc.bNumEndpoints; i++) { if (start > end) return start; start = usb_dump_endpoint_descriptor(speed, - start, end, desc->endpoint + i); + start, end, &desc->endpoint[i].desc); } return start; } @@ -288,7 +288,7 @@ static char *usb_dump_config_descriptor(char *start, char *end, const struct usb desc->bNumInterfaces, desc->bConfigurationValue, desc->bmAttributes, - desc->MaxPower * 2); + desc->bMaxPower * 2); return start; } @@ -296,7 +296,7 @@ static char *usb_dump_config ( int speed, char *start, char *end, - const struct usb_config_descriptor *config, + const struct usb_host_config *config, int active ) { @@ -307,8 +307,8 @@ static char *usb_dump_config ( return start; if (!config) /* getting these some in 2.3.7; none in 2.3.6 */ return start + sprintf(start, "(null Cfg. desc.)\n"); - start = usb_dump_config_descriptor(start, end, config, active); - for (i = 0; i < config->bNumInterfaces; i++) { + start = usb_dump_config_descriptor(start, end, &config->desc, active); + for (i = 0; i < config->desc.bNumInterfaces; i++) { interface = config->interface + i; if (!interface) break; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 22596da570cd..3770a6a0d270 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -337,7 +337,8 @@ static int claimintf(struct dev_state *ps, unsigned int intf) struct usb_interface *iface; int err; - if (intf >= 8*sizeof(ps->ifclaimed) || !dev || intf >= dev->actconfig->bNumInterfaces) + if (intf >= 8*sizeof(ps->ifclaimed) || !dev + || intf >= dev->actconfig->desc.bNumInterfaces) return -EINVAL; /* already claimed */ if (test_bit(intf, &ps->ifclaimed)) @@ -390,17 +391,17 @@ static int findintfep(struct usb_device *dev, unsigned int ep) { unsigned int i, j, e; struct usb_interface *iface; - struct usb_interface_descriptor *alts; + struct usb_host_interface *alts; struct usb_endpoint_descriptor *endpt; if (ep & ~(USB_DIR_IN|0xf)) return -EINVAL; - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { iface = &dev->actconfig->interface[i]; for (j = 0; j < iface->num_altsetting; j++) { alts = &iface->altsetting[j]; - for (e = 0; e < alts->bNumEndpoints; e++) { - endpt = &alts->endpoint[e]; + for (e = 0; e < alts->desc.bNumEndpoints; e++) { + endpt = &alts->endpoint[e].desc; if (endpt->bEndpointAddress == ep) return i; } @@ -413,15 +414,15 @@ static int findintfif(struct usb_device *dev, unsigned int ifn) { unsigned int i, j; struct usb_interface *iface; - struct usb_interface_descriptor *alts; + struct usb_host_interface *alts; if (ifn & ~0xff) return -EINVAL; - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { iface = &dev->actconfig->interface[i]; for (j = 0; j < iface->num_altsetting; j++) { alts = &iface->altsetting[j]; - if (alts->bInterfaceNumber == ifn) + if (alts->desc.bInterfaceNumber == ifn) return i; } } @@ -693,7 +694,7 @@ static int proc_resetdevice(struct dev_state *ps) if (ret < 0) return ret; - for (i = 0; i < ps->dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < ps->dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = &ps->dev->actconfig->interface[i]; /* Don't simulate interfaces we've claimed */ @@ -755,7 +756,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg) if (copy_from_user(&uurb, arg, sizeof(uurb))) return -EFAULT; if (uurb.flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| - USB_NO_FSBR|USB_ZERO_PACKET)) + URB_NO_FSBR|URB_ZERO_PACKET)) return -EINVAL; if (!uurb.buffer) return -EINVAL; diff --git a/drivers/usb/core/driverfs.c b/drivers/usb/core/driverfs.c index 14b049f547fd..f0b821df7eea 100644 --- a/drivers/usb/core/driverfs.c +++ b/drivers/usb/core/driverfs.c @@ -33,14 +33,14 @@ show_##field (struct device *dev, char *buf, size_t count, loff_t off) \ return 0; \ \ udev = to_usb_device (dev); \ - return sprintf (buf, format_string, udev->actconfig->field); \ + return sprintf (buf, format_string, udev->actconfig->desc.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); usb_actconfig_attr (bNumInterfaces, "%2d\n") usb_actconfig_attr (bConfigurationValue, "%2d\n") usb_actconfig_attr (bmAttributes, "%2x\n") -usb_actconfig_attr (MaxPower, "%3dmA\n") +usb_actconfig_attr (bMaxPower, "%3dmA\n") /* String fields */ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off) @@ -157,7 +157,7 @@ void usb_create_driverfs_dev_files (struct usb_device *udev) device_create_file (dev, &dev_attr_bNumInterfaces); device_create_file (dev, &dev_attr_bConfigurationValue); device_create_file (dev, &dev_attr_bmAttributes); - device_create_file (dev, &dev_attr_MaxPower); + device_create_file (dev, &dev_attr_bMaxPower); device_create_file (dev, &dev_attr_idVendor); device_create_file (dev, &dev_attr_idProduct); device_create_file (dev, &dev_attr_bcdDevice); @@ -188,7 +188,7 @@ show_##field (struct device *dev, char *buf, size_t count, loff_t off) \ intf = to_usb_interface (dev); \ alt = intf->act_altsetting; \ \ - return sprintf (buf, format_string, intf->altsetting[alt].field); \ + return sprintf (buf, format_string, intf->altsetting[alt].desc.field); \ } \ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4d48c311f1b0..bd3467543386 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1110,7 +1110,7 @@ static int hcd_unlink_urb (struct urb *urb) */ spin_lock_irqsave (&urb->lock, flags); spin_lock (&hcd_data_lock); - if (!urb->hcpriv || urb->transfer_flags & USB_TIMEOUT_KILLED) { + if (!urb->hcpriv || urb->transfer_flags & URB_TIMEOUT_KILLED) { retval = -EINVAL; goto done; } @@ -1150,9 +1150,9 @@ static int hcd_unlink_urb (struct urb *urb) * lower level hcd code is always async, locking on urb->status * updates; an intercepted completion unblocks us. */ - if ((urb->transfer_flags & USB_TIMEOUT_KILLED)) + if ((urb->transfer_flags & URB_TIMEOUT_KILLED)) urb->status = -ETIMEDOUT; - else if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) { + else if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) { if (in_interrupt ()) { dbg ("non-async unlink in_interrupt"); retval = -EWOULDBLOCK; @@ -1182,13 +1182,13 @@ if (retval && urb->status == -ENOENT) err ("whoa! retval %d", retval); } /* block till giveback, if needed */ - if (!(urb->transfer_flags & (USB_ASYNC_UNLINK|USB_TIMEOUT_KILLED)) + if (!(urb->transfer_flags & (URB_ASYNC_UNLINK|URB_TIMEOUT_KILLED)) && HCD_IS_RUNNING (hcd->state) && !retval) { dbg ("%s: wait for giveback urb %p", hcd->self.bus_name, urb); wait_for_completion (&splice.done); - } else if ((urb->transfer_flags & USB_ASYNC_UNLINK) && retval == 0) { + } else if ((urb->transfer_flags & URB_ASYNC_UNLINK) && retval == 0) { return -EINPROGRESS; } goto bye; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 28712be6a473..cf4e9236724c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -418,7 +418,7 @@ static int usb_hub_configure(struct usb_hub *hub, return -1; } - FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, + usb_fill_int_urb(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); ret = usb_submit_urb(hub->urb, GFP_KERNEL); if (ret) { @@ -478,7 +478,7 @@ static void hub_disconnect(struct usb_interface *intf) static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_interface_descriptor *desc; + struct usb_host_interface *desc; struct usb_endpoint_descriptor *endpoint; struct usb_device *dev; struct usb_hub *hub; @@ -489,21 +489,21 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ - if ((desc->bInterfaceSubClass != 0) && - (desc->bInterfaceSubClass != 1)) { + if ((desc->desc.bInterfaceSubClass != 0) && + (desc->desc.bInterfaceSubClass != 1)) { err("invalid subclass (%d) for USB hub device #%d", - desc->bInterfaceSubClass, dev->devnum); + desc->desc.bInterfaceSubClass, dev->devnum); return -EIO; } /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (desc->bNumEndpoints != 1) { + if (desc->desc.bNumEndpoints != 1) { err("invalid bNumEndpoints (%d) for USB hub device #%d", - desc->bNumEndpoints, dev->devnum); + desc->desc.bNumEndpoints, dev->devnum); return -EIO; } - endpoint = &desc->endpoint[0]; + endpoint = &desc->endpoint[0].desc; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { @@ -1244,18 +1244,18 @@ int usb_reset_device(struct usb_device *dev) return 1; } - ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue); + ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue); if (ret < 0) { err("failed to set dev %s active configuration (error=%d)", dev->devpath, ret); return ret; } - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = &dev->actconfig->interface[i]; struct usb_interface_descriptor *as; - as = &intf->altsetting[intf->act_altsetting]; + as = &intf->altsetting[intf->act_altsetting].desc; ret = usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting); if (ret < 0) { diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 16e3e8b43f2b..18a0c6493483 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -92,7 +92,7 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, if (!urb) return -ENOMEM; - FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, + usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, usb_api_blocking_completion, 0); retv = usb_start_wait_urb(urb, timeout, &length); @@ -190,7 +190,7 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, if (!urb) return -ENOMEM; - FILL_BULK_URB(urb, usb_dev, pipe, data, len, + usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, 0); return usb_start_wait_urb(urb,timeout,actual_length); @@ -324,7 +324,7 @@ int usb_sg_init ( if (!io->urbs) goto nomem; - urb_flags = USB_ASYNC_UNLINK | URB_NO_DMA_MAP | URB_NO_INTERRUPT; + urb_flags = URB_ASYNC_UNLINK | URB_NO_DMA_MAP | URB_NO_INTERRUPT; if (usb_pipein (pipe)) urb_flags |= URB_SHORT_NOT_OK; @@ -640,31 +640,33 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data) // hub-only!! ... and only exported for reset/reinit path. -// otherwise used internally, for config/altsetting reconfig. +// otherwise used internally, when setting up a config void usb_set_maxpacket(struct usb_device *dev) { int i, b; - for (i=0; i<dev->actconfig->bNumInterfaces; i++) { + for (i=0; i<dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *ifp = dev->actconfig->interface + i; - struct usb_interface_descriptor *as = ifp->altsetting + ifp->act_altsetting; - struct usb_endpoint_descriptor *ep = as->endpoint; + struct usb_host_interface *as = ifp->altsetting + ifp->act_altsetting; + struct usb_host_endpoint *ep = as->endpoint; int e; - for (e=0; e<as->bNumEndpoints; e++) { - b = ep[e].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - if ((ep[e].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + for (e=0; e<as->desc.bNumEndpoints; e++) { + struct usb_endpoint_descriptor *d; + d = &ep [e].desc; + b = d->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + if ((d->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */ - dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; - dev->epmaxpacketin [b] = ep[e].wMaxPacketSize; + dev->epmaxpacketout[b] = d->wMaxPacketSize; + dev->epmaxpacketin [b] = d->wMaxPacketSize; } - else if (usb_endpoint_out(ep[e].bEndpointAddress)) { - if (ep[e].wMaxPacketSize > dev->epmaxpacketout[b]) - dev->epmaxpacketout[b] = ep[e].wMaxPacketSize; + else if (usb_endpoint_out(d->bEndpointAddress)) { + if (d->wMaxPacketSize > dev->epmaxpacketout[b]) + dev->epmaxpacketout[b] = d->wMaxPacketSize; } else { - if (ep[e].wMaxPacketSize > dev->epmaxpacketin [b]) - dev->epmaxpacketin [b] = ep[e].wMaxPacketSize; + if (d->wMaxPacketSize > dev->epmaxpacketin [b]) + dev->epmaxpacketin [b] = d->wMaxPacketSize; } } } @@ -764,7 +766,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe) int usb_set_interface(struct usb_device *dev, int interface, int alternate) { struct usb_interface *iface; - struct usb_interface_descriptor *iface_as; + struct usb_host_interface *iface_as; int i, ret; iface = usb_ifnum_to_if(dev, interface); @@ -786,7 +788,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, - iface->altsetting[alternate].bAlternateSetting, + iface->altsetting[alternate] + .desc.bAlternateSetting, interface, NULL, 0, HZ * 5)) < 0) return ret; @@ -798,8 +801,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) /* prevent submissions using previous endpoint settings */ iface_as = iface->altsetting + iface->act_altsetting; - for (i = 0; i < iface_as->bNumEndpoints; i++) { - u8 ep = iface_as->endpoint [i].bEndpointAddress; + for (i = 0; i < iface_as->desc.bNumEndpoints; i++) { + u8 ep = iface_as->endpoint [i].desc.bEndpointAddress; int out = !(ep & USB_DIR_IN); ep &= USB_ENDPOINT_NUMBER_MASK; @@ -821,14 +824,14 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) */ iface_as = &iface->altsetting[alternate]; - for (i = 0; i < iface_as->bNumEndpoints; i++) { - u8 ep = iface_as->endpoint[i].bEndpointAddress; + for (i = 0; i < iface_as->desc.bNumEndpoints; i++) { + u8 ep = iface_as->endpoint[i].desc.bEndpointAddress; int out = !(ep & USB_DIR_IN); ep &= USB_ENDPOINT_NUMBER_MASK; usb_settoggle (dev, ep, out, 0); (out ? dev->epmaxpacketout : dev->epmaxpacketin) [ep] - = iface_as->endpoint [i].wMaxPacketSize; + = iface_as->endpoint [i].desc.wMaxPacketSize; } return 0; @@ -867,10 +870,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) int usb_set_configuration(struct usb_device *dev, int configuration) { int i, ret; - struct usb_config_descriptor *cp = NULL; + struct usb_host_config *cp = NULL; for (i=0; i<dev->descriptor.bNumConfigurations; i++) { - if (dev->config[i].bConfigurationValue == configuration) { + if (dev->config[i].desc.bConfigurationValue == configuration) { cp = &dev->config[i]; break; } diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 929fc66270ff..dd125b117124 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -272,23 +272,23 @@ int usb_submit_urb(struct urb *urb, int mem_flags) unsigned int allowed; /* enforce simple/standard policy */ - allowed = USB_ASYNC_UNLINK; // affects later unlinks + allowed = URB_ASYNC_UNLINK; // affects later unlinks allowed |= URB_NO_DMA_MAP; allowed |= URB_NO_INTERRUPT; switch (temp) { case PIPE_BULK: if (is_out) - allowed |= USB_ZERO_PACKET; + allowed |= URB_ZERO_PACKET; /* FALLTHROUGH */ case PIPE_CONTROL: - allowed |= USB_NO_FSBR; /* only affects UHCI */ + allowed |= URB_NO_FSBR; /* only affects UHCI */ /* FALLTHROUGH */ default: /* all non-iso endpoints */ if (!is_out) allowed |= URB_SHORT_NOT_OK; break; case PIPE_ISOCHRONOUS: - allowed |= USB_ISO_ASAP; + allowed |= URB_ISO_ASAP; break; } urb->transfer_flags &= allowed; @@ -360,7 +360,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) * that the request has been canceled, and that control of the URB * has been returned to that device driver. * - * When the USB_ASYNC_UNLINK transfer flag for the URB is clear, this + * When the URB_ASYNC_UNLINK transfer flag for the URB is clear, this * request is synchronous. Success is indicated by returning zero, * at which time the urb will have been unlinked, * and the completion function will see status -ENOENT. Failure is @@ -368,7 +368,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) * when unlinking an urb from an interrupt context, such as a bottom * half or a completion handler, * - * When the USB_ASYNC_UNLINK transfer flag for the URB is set, this + * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this * request is asynchronous. Success is indicated by returning -EINPROGRESS, * at which time the urb will normally not have been unlinked, * and the completion function will see status -ECONNRESET. Failure is diff --git a/drivers/usb/core/usb-debug.c b/drivers/usb/core/usb-debug.c index a29393e06dcb..c3e29a37665e 100644 --- a/drivers/usb/core/usb-debug.c +++ b/drivers/usb/core/usb-debug.c @@ -16,28 +16,28 @@ #endif #include <linux/usb.h> -static void usb_show_endpoint(struct usb_endpoint_descriptor *endpoint) +static void usb_show_endpoint(struct usb_host_endpoint *endpoint) { - usb_show_endpoint_descriptor(endpoint); + usb_show_endpoint_descriptor(&endpoint->desc); } -static void usb_show_interface(struct usb_interface_descriptor *altsetting) +static void usb_show_interface(struct usb_host_interface *altsetting) { int i; - usb_show_interface_descriptor(altsetting); + usb_show_interface_descriptor(&altsetting->desc); - for (i = 0; i < altsetting->bNumEndpoints; i++) + for (i = 0; i < altsetting->desc.bNumEndpoints; i++) usb_show_endpoint(altsetting->endpoint + i); } -static void usb_show_config(struct usb_config_descriptor *config) +static void usb_show_config(struct usb_host_config *config) { int i, j; struct usb_interface *ifp; - usb_show_config_descriptor(config); - for (i = 0; i < config->bNumInterfaces; i++) { + usb_show_config_descriptor(&config->desc); + for (i = 0; i < config->desc.bNumInterfaces; i++) { ifp = config->interface + i; if (!ifp) @@ -124,7 +124,7 @@ void usb_show_config_descriptor(struct usb_config_descriptor *desc) printk(" bConfigurationValue = %02x\n", desc->bConfigurationValue); printk(" iConfiguration = %02x\n", desc->iConfiguration); printk(" bmAttributes = %02x\n", desc->bmAttributes); - printk(" MaxPower = %4dmA\n", desc->MaxPower * 2); + printk(" bMaxPower = %4dmA\n", desc->bMaxPower * 2); } void usb_show_interface_descriptor(struct usb_interface_descriptor *desc) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b217ba001e45..eb00740a20de 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -233,8 +233,9 @@ struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) { int i; - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) - if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum) + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) + if (dev->actconfig->interface[i].altsetting[0] + .desc.bInterfaceNumber == ifnum) return &dev->actconfig->interface[i]; return NULL; @@ -254,15 +255,21 @@ struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) * the first endpoint in that descriptor corresponds to interface zero. * This routine helps device drivers avoid such mistakes. */ -struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum) +struct usb_endpoint_descriptor * +usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum) { int i, j, k; - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) for (j = 0; j < dev->actconfig->interface[i].num_altsetting; j++) - for (k = 0; k < dev->actconfig->interface[i].altsetting[j].bNumEndpoints; k++) - if (epnum == dev->actconfig->interface[i].altsetting[j].endpoint[k].bEndpointAddress) - return &dev->actconfig->interface[i].altsetting[j].endpoint[k]; + for (k = 0; k < dev->actconfig->interface[i] + .altsetting[j].desc.bNumEndpoints; k++) + if (epnum == dev->actconfig->interface[i] + .altsetting[j].endpoint[k] + .desc.bEndpointAddress) + return &dev->actconfig->interface[i] + .altsetting[j].endpoint[k] + .desc; return NULL; } @@ -408,7 +415,7 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac const struct usb_device_id * usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_interface_descriptor *intf; + struct usb_host_interface *intf; struct usb_device *dev; /* proc_connectinfo in devio.c may call us with id == NULL. */ @@ -457,15 +464,15 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && - (id->bInterfaceClass != intf->bInterfaceClass)) + (id->bInterfaceClass != intf->desc.bInterfaceClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && - (id->bInterfaceSubClass != intf->bInterfaceSubClass)) + (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) continue; if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && - (id->bInterfaceProtocol != intf->bInterfaceProtocol)) + (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) continue; return id; @@ -604,10 +611,10 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, */ envp [i++] = scratch; length += snprintf (scratch, buffer_size - length, - "INTERFACE=%d/%d/%d", - intf->altsetting[alt].bInterfaceClass, - intf->altsetting[alt].bInterfaceSubClass, - intf->altsetting[alt].bInterfaceProtocol); + "INTERFACE=%d/%d/%d", + intf->altsetting[alt].desc.bInterfaceClass, + intf->altsetting[alt].desc.bInterfaceSubClass, + intf->altsetting[alt].desc.bInterfaceProtocol); if ((buffer_size - length <= 0) || (i >= num_envp)) return -ENOMEM; ++length; @@ -792,7 +799,7 @@ void usb_disconnect(struct usb_device **pdev) dbg ("unregistering interfaces on device %d", dev->devnum); if (dev->actconfig) { - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; /* remove this interface */ @@ -1026,7 +1033,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) } /* we set the default configuration here */ - err = usb_set_configuration(dev, dev->config[0].bConfigurationValue); + err = usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue); if (err) { err("failed to set device %d default configuration (error=%d)", dev->devnum, err); @@ -1065,16 +1072,17 @@ int usb_new_device(struct usb_device *dev, struct device *parent) /* Register all of the interfaces for this device with the driver core. * Remember, interfaces get bound to drivers, not devices. */ - for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; - struct usb_interface_descriptor *desc = interface->altsetting; + struct usb_interface_descriptor *desc; + desc = &interface->altsetting [interface->act_altsetting].desc; interface->dev.parent = &dev->dev; interface->dev.driver = NULL; interface->dev.bus = &usb_bus_type; sprintf (&interface->dev.bus_id[0], "%d-%s:%d", dev->bus->busnum, dev->devpath, - interface->altsetting->bInterfaceNumber); + desc->bInterfaceNumber); if (!desc->iInterface || usb_string (dev, desc->iInterface, interface->dev.name, @@ -1087,7 +1095,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) sprintf (&interface->dev.name[0], "usb-%s-%s interface %d", dev->bus->bus_name, dev->devpath, - interface->altsetting->bInterfaceNumber); + desc->bInterfaceNumber); } dbg ("%s - registering %s", __FUNCTION__, interface->dev.bus_id); device_register (&interface->dev); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 514b628c68f9..6f0d36dd2cae 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -463,7 +463,7 @@ qh_urb_transaction ( token ^= 0x0100; /* "in" <--> "out" */ token |= QTD_TOGGLE; /* force DATA1 */ } else if (usb_pipebulk (urb->pipe) - && (urb->transfer_flags & USB_ZERO_PACKET) + && (urb->transfer_flags & URB_ZERO_PACKET) && !(urb->transfer_buffer_length % maxpacket)) { one_more = 1; } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d1d6346fe54f..62abde4c9908 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -738,7 +738,7 @@ static int get_iso_range ( } /* explicit start frame? */ - if (!(urb->transfer_flags & USB_ISO_ASAP)) { + if (!(urb->transfer_flags & URB_ISO_ASAP)) { unsigned temp; /* sanity check: must be in range */ diff --git a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c index 570267835101..ce06daad48b8 100644 --- a/drivers/usb/host/hc_simple.c +++ b/drivers/usb/host/hc_simple.c @@ -219,7 +219,7 @@ static int hci_unlink_urb (struct urb * urb) if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) { /* URB active? */ - if (urb->transfer_flags & (USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED)) { + if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) { /* asynchronous with callback */ /* relink the urb to the del list */ list_move (&urb->urb_list, &hci->del_list); @@ -251,7 +251,7 @@ static int hci_unlink_urb (struct urb * urb) /* hcd does not own URB but we keep the driver happy anyway */ spin_unlock_irqrestore (&usb_urb_lock, flags); - if (urb->complete && (urb->transfer_flags & USB_ASYNC_UNLINK)) { + if (urb->complete && (urb->transfer_flags & URB_ASYNC_UNLINK)) { urb->status = -ENOENT; urb->actual_length = 0; urb->complete (urb); @@ -388,7 +388,7 @@ static void qu_urb_timeout (unsigned long lurb) struct urb *urb = (struct urb *) lurb; DBGFUNC ("enter qu_urb_timeout\n"); - urb->transfer_flags |= USB_TIMEOUT_KILLED; + urb->transfer_flags |= URB_TIMEOUT_KILLED; hci_unlink_urb (urb); } #endif @@ -472,7 +472,7 @@ static inline void qu_queue_active_urb (hci_t * hci, struct urb * urb, epd_t * e case PIPE_BULK: list_add (&urb->urb_list, &hci->bulk_list); - if ((urb->transfer_flags & USB_ZERO_PACKET) + if ((urb->transfer_flags & URB_ZERO_PACKET) && urb->transfer_buffer_length > 0 && ((urb->transfer_buffer_length % @@ -523,7 +523,7 @@ static int qu_queue_urb (hci_t * hci, struct urb * urb) /* for ISOC transfers calculate start frame index */ - if (usb_pipeisoc (urb->pipe) && urb->transfer_flags & USB_ISO_ASAP) { + if (usb_pipeisoc (urb->pipe) && urb->transfer_flags & URB_ISO_ASAP) { urb->start_frame = ((ed->pipe_head) ? (ed->last_iso + 1) : hci_get_current_frame_number (urb-> dev) + 1) & 0xffff; } diff --git a/drivers/usb/host/hc_sl811_rh.c b/drivers/usb/host/hc_sl811_rh.c index e2ce511ebdb6..da6d30214359 100644 --- a/drivers/usb/host/hc_sl811_rh.c +++ b/drivers/usb/host/hc_sl811_rh.c @@ -534,7 +534,7 @@ static int rh_unlink_urb (struct urb * urb) urb->hcpriv = NULL; usb_put_dev (urb->dev); urb->dev = NULL; - if (urb->transfer_flags & USB_ASYNC_UNLINK) { + if (urb->transfer_flags & URB_ASYNC_UNLINK) { urb->status = -ECONNRESET; if (urb->complete) { urb->complete (urb); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f3e21ed3ad80..c86ecea5fdc6 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -29,7 +29,7 @@ * * 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes * from post-2.4.5 patches. - * 2001/09/20 USB_ZERO_PACKET support; hcca_dma portability, OPTi warning + * 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning * 2001/09/07 match PCI PM changes, errnos from Linus' tree * 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify; * pbook pci quirks gone (please fix pbook pci sw!) (db) @@ -185,7 +185,7 @@ static int ohci_urb_enqueue ( /* ... and maybe a zero length packet to wrap it up */ if (size == 0) size++; - else if ((urb->transfer_flags & USB_ZERO_PACKET) != 0 + else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 && (urb->transfer_buffer_length % usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe))) == 0) @@ -239,7 +239,7 @@ static int ohci_urb_enqueue ( frame |= ed->branch; urb->start_frame = frame; - /* yes, only USB_ISO_ASAP is supported, and + /* yes, only URB_ISO_ASAP is supported, and * urb->start_frame is never used as input. */ } diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 2415f9c26554..11d4bac4a19c 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -176,13 +176,6 @@ td_alloc (struct ohci_hcd *hc, int mem_flags) pci_pool_free (hc->td_cache, td, dma); return NULL; } - // DEBUG ONLY want to see if these tds are really getting - // allocated. the last one in a page shouldn't be getting - // allocated during these tests! - if ((dma & 0x0fff) == 0x0fc0) { - dbg ("td = %p", td); - dump_stack (); - } } return td; } diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 46b056c879fb..621841baef5f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -575,7 +575,7 @@ static void td_submit_urb ( info |= TD_R; td_fill (info, data, data_len, urb, cnt); cnt++; - if ((urb->transfer_flags & USB_ZERO_PACKET) + if ((urb->transfer_flags & URB_ZERO_PACKET) && cnt < urb_priv->length) { td_fill (info, 0, 0, urb, cnt); cnt++; @@ -736,42 +736,39 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) */ ed->hwINFO |= ED_SKIP; wmb (); - td->ed->hwHeadP &= ~ED_H; + ed->hwHeadP &= ~ED_H; + /* put any later tds from this urb onto the donelist, after 'td', + * order won't matter here: no errors, and nothing was transferred. + * also patch the ed so it looks as if those tds completed normally. + */ while (tmp != &ed->td_list) { struct td *next; + u32 info; next = list_entry (tmp, struct td, td_list); tmp = next->td_list.next; - /* move other tds from this urb to the donelist, after 'td'. - * order won't matter here: no errors, nothing transferred. - * - * NOTE: this "knows" short control reads won't need fixup: - * hc went from the (one) data TD to the status td. that'll - * change if multi-td control DATA segments are supported, - * and we want to send the status packet. + if (next->urb != urb) + break; + + /* NOTE: if multi-td control DATA segments get supported, + * this urb had one of them, this td wasn't the last td + * in that segment (TD_R clear), this ed halted because + * of a short read, _and_ URB_SHORT_NOT_OK is clear ... + * then we need to leave the control STATUS packet queued + * and clear ED_SKIP. */ - if (next->urb == urb) { - u32 info = next->hwINFO; - - info |= cpu_to_le32 (TD_DONE); - info &= ~cpu_to_le32 (TD_CC); - next->hwINFO = info; - next->next_dl_td = rev; - rev = next; - continue; - } + info = next->hwINFO; + info |= cpu_to_le32 (TD_DONE); + info &= ~cpu_to_le32 (TD_CC); + next->hwINFO = info; - /* restart ed with first td of this next urb */ - ed->hwHeadP = cpu_to_le32 (next->td_dma) | toggle; - tmp = 0; - break; - } + next->next_dl_td = rev; + rev = next; - /* no urbs queued? then ED is empty. */ - if (tmp) - ed->hwHeadP = cpu_to_le32 (ed->dummy->td_dma) | toggle; + ed->hwHeadP = next->hwNextTD | toggle; + } /* help for troubleshooting: */ dbg ("urb %p usb-%s-%s ep-%d-%s cc %d --> status %d", diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index f23a9cf91a9e..c5d574ea947c 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -739,7 +739,7 @@ static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) spin_lock_irqsave(&uhci->frame_list_lock, flags); - if ((!(urb->transfer_flags & USB_NO_FSBR)) && !urbp->fsbr) { + if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) { urbp->fsbr = 1; if (!uhci->fsbr++ && !uhci->fsbrtimeout) uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_hs_control_qh->dma_handle) | UHCI_PTR_QH; @@ -755,7 +755,7 @@ static void uhci_dec_fsbr(struct uhci_hcd *uhci, struct urb *urb) spin_lock_irqsave(&uhci->frame_list_lock, flags); - if ((!(urb->transfer_flags & USB_NO_FSBR)) && urbp->fsbr) { + if ((!(urb->transfer_flags & URB_NO_FSBR)) && urbp->fsbr) { urbp->fsbr = 0; if (!--uhci->fsbr) uhci->fsbrtimeout = jiffies + FSBR_DELAY; @@ -1124,13 +1124,13 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb } while (len > 0); /* - * USB_ZERO_PACKET means adding a 0-length packet, if direction + * URB_ZERO_PACKET means adding a 0-length packet, if direction * is OUT and the transfer_length was an exact multiple of maxsze, * hence (len = transfer_length - N * maxsze) == 0 * however, if transfer_length == 0, the zero packet was already * prepared above. */ - if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) && + if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) && !len && urb->transfer_buffer_length) { td = uhci_alloc_td(uhci, urb->dev); if (!td) @@ -1306,7 +1306,7 @@ static int isochronous_find_start(struct uhci_hcd *uhci, struct urb *urb) limits = isochronous_find_limits(uhci, urb, &start, &end); - if (urb->transfer_flags & USB_ISO_ASAP) { + if (urb->transfer_flags & URB_ISO_ASAP) { if (limits) { int curframe; @@ -1752,7 +1752,7 @@ static void stall_callback(unsigned long ptr) tmp = tmp->next; - u->transfer_flags |= USB_TIMEOUT_KILLED; + u->transfer_flags |= URB_TIMEOUT_KILLED; uhci_urb_dequeue(hcd, u); } diff --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index 543120598118..00bb26a79802 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -35,14 +35,14 @@ hpusbscsi_usb_probe (struct usb_interface *intf, { struct hpusbscsi *new; struct usb_device *dev = interface_to_usbdev (intf); - struct usb_interface_descriptor *altsetting = + struct usb_host_interface *altsetting = &(intf->altsetting[0]); int i, result; /* basic check */ - if (altsetting->bNumEndpoints != 3) { + if (altsetting->desc.bNumEndpoints != 3) { printk (KERN_ERR "Wrong number of endpoints\n"); return -ENODEV; } @@ -76,34 +76,34 @@ hpusbscsi_usb_probe (struct usb_interface *intf, /* finding endpoints */ - for (i = 0; i < altsetting->bNumEndpoints; i++) { + for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { if ( - (altsetting->endpoint[i]. + (altsetting->endpoint[i].desc. bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { - if (altsetting->endpoint[i]. + if (altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN) { new->ep_in = - altsetting->endpoint[i]. + altsetting->endpoint[i].desc. bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; } else { new->ep_out = - altsetting->endpoint[i]. + altsetting->endpoint[i].desc. bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; } } else { new->ep_int = - altsetting->endpoint[i]. + altsetting->endpoint[i].desc. bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - new->interrupt_interval= altsetting->endpoint[i].bInterval; + new->interrupt_interval= altsetting->endpoint[i].desc.bInterval; } } /* USB initialisation magic for the simple case */ - result = usb_set_interface (dev, altsetting->bInterfaceNumber, 0); + result = usb_set_interface (dev, altsetting->desc.bInterfaceNumber, 0); switch (result) { case 0: /* no error */ @@ -244,7 +244,7 @@ hpusbscsi_scsi_detect (struct SHT *sht) sht->proc_dir = NULL; /* build and submit an interrupt URB for status byte handling */ - FILL_INT_URB(desc->controlurb, + usb_fill_int_urb(desc->controlurb, desc->dev, usb_rcvintpipe(desc->dev,desc->ep_int), &desc->scsi_state_byte, @@ -321,7 +321,7 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) TRACE_STATE; /* We prepare the urb for writing out the scsi command */ - FILL_BULK_URB( + usb_fill_bulk_urb( hpusbscsi->dataurb, hpusbscsi->dev, usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out), @@ -477,7 +477,7 @@ static void scatter_gather_callback(struct urb *u) hpusbscsi->state = HP_STATE_WORKING; TRACE_STATE; - FILL_BULK_URB( + usb_fill_bulk_urb( u, hpusbscsi->dev, hpusbscsi->current_data_pipe, @@ -531,7 +531,7 @@ static void simple_payload_callback (struct urb *u) return; } - FILL_BULK_URB( + usb_fill_bulk_urb( u, hpusbscsi->dev, hpusbscsi->current_data_pipe, @@ -562,7 +562,7 @@ static void request_sense_callback (struct urb *u) return; } - FILL_BULK_URB( + usb_fill_bulk_urb( u, hpusbscsi->dev, hpusbscsi->current_data_pipe, @@ -582,7 +582,7 @@ static void request_sense_callback (struct urb *u) static void issue_request_sense (struct hpusbscsi *hpusbscsi) { - FILL_BULK_URB( + usb_fill_bulk_urb( hpusbscsi->dataurb, hpusbscsi->dev, usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out), diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 12aafe9b9eb7..571c72615cab 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -410,7 +410,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { int i,j; - struct usb_interface_descriptor *intf_desc; + struct usb_host_interface *intf_desc; struct usb_device *dev = interface_to_usbdev (intf); int irq_interval=0; int retval; @@ -432,10 +432,10 @@ static int mdc800_usb_probe (struct usb_interface *intf, intf_desc = &intf->altsetting[0]; if ( - ( intf_desc->bInterfaceClass != 0xff ) - || ( intf_desc->bInterfaceSubClass != 0 ) - || ( intf_desc->bInterfaceProtocol != 0 ) - || ( intf_desc->bNumEndpoints != 4) + ( intf_desc->desc.bInterfaceClass != 0xff ) + || ( intf_desc->desc.bInterfaceSubClass != 0 ) + || ( intf_desc->desc.bInterfaceProtocol != 0 ) + || ( intf_desc->desc.bNumEndpoints != 4) ) { err ("probe fails -> wrong Interface"); @@ -448,12 +448,12 @@ static int mdc800_usb_probe (struct usb_interface *intf, mdc800->endpoint[i]=-1; for (j=0; j<4; j++) { - if (mdc800_endpoint_equals (&intf_desc->endpoint [j],&mdc800_ed [i])) + if (mdc800_endpoint_equals (&intf_desc->endpoint [j].desc,&mdc800_ed [i])) { - mdc800->endpoint[i]=intf_desc->endpoint [j].bEndpointAddress ; + mdc800->endpoint[i]=intf_desc->endpoint [j].desc.bEndpointAddress ; if (i==1) { - irq_interval=intf_desc->endpoint [j].bInterval; + irq_interval=intf_desc->endpoint [j].desc.bInterval; } continue; @@ -468,7 +468,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, usb_driver_claim_interface (&mdc800_usb_driver, intf, mdc800); - if (usb_set_interface (dev, intf_desc->bInterfaceNumber, 0) < 0) + if (usb_set_interface (dev, intf_desc->desc.bInterfaceNumber, 0) < 0) { err ("MDC800 Configuration fails."); return -ENODEV; @@ -488,7 +488,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, mdc800->open=0; /* Setup URB Structs */ - FILL_INT_URB ( + usb_fill_int_urb ( mdc800->irq_urb, mdc800->dev, usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]), @@ -499,7 +499,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, irq_interval ); - FILL_BULK_URB ( + usb_fill_bulk_urb ( mdc800->write_urb, mdc800->dev, usb_sndbulkpipe (mdc800->dev, mdc800->endpoint[0]), @@ -509,7 +509,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, mdc800 ); - FILL_BULK_URB ( + usb_fill_bulk_urb ( mdc800->download_urb, mdc800->dev, usb_rcvbulkpipe (mdc800->dev, mdc800->endpoint [3]), diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index b4c63efc381a..9d9cfe6f7f60 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -487,7 +487,7 @@ void mts_int_submit_urb (struct urb* transfer, MTS_INT_INIT(); - FILL_BULK_URB(transfer, + usb_fill_bulk_urb(transfer, context->instance->usb_dev, pipe, data, @@ -715,7 +715,7 @@ int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) } - FILL_BULK_URB(desc->urb, + usb_fill_bulk_urb(desc->urb, desc->usb_dev, usb_sndbulkpipe(desc->usb_dev,desc->ep_out), srb->cmnd, @@ -851,7 +851,7 @@ static int mts_usb_probe (struct usb_interface *intf, struct usb_device *dev = interface_to_usbdev (intf); /* the altsettting 0 on the interface we're probing */ - struct usb_interface_descriptor *altsetting; + struct usb_host_interface *altsetting; MTS_DEBUG_GOT_HERE(); MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev ); @@ -877,23 +877,23 @@ static int mts_usb_probe (struct usb_interface *intf, /* Check if the config is sane */ - if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) { + if ( altsetting->desc.bNumEndpoints != MTS_EP_TOTAL ) { MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n", - (int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints ); + (int)MTS_EP_TOTAL, (int)altsetting->desc.bNumEndpoints ); return -ENODEV; } - for( i = 0; i < altsetting->bNumEndpoints; i++ ) { - if ((altsetting->endpoint[i].bmAttributes & + for( i = 0; i < altsetting->desc.bNumEndpoints; i++ ) { + if ((altsetting->endpoint[i].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n", - (int)altsetting->endpoint[i].bEndpointAddress ); + (int)altsetting->endpoint[i].desc.bEndpointAddress ); } else { - if (altsetting->endpoint[i].bEndpointAddress & + if (altsetting->endpoint[i].desc.bEndpointAddress & USB_DIR_IN) *ep_in_current++ - = altsetting->endpoint[i].bEndpointAddress & + = altsetting->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; else { if ( ep_out != -1 ) { @@ -901,7 +901,7 @@ static int mts_usb_probe (struct usb_interface *intf, return -ENODEV; } - ep_out = altsetting->endpoint[i].bEndpointAddress & + ep_out = altsetting->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; } } @@ -914,7 +914,7 @@ static int mts_usb_probe (struct usb_interface *intf, return -ENODEV; } - result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0); + result = usb_set_interface(dev, altsetting->desc.bInterfaceNumber, 0); MTS_DEBUG("usb_set_interface returned %d.\n",result); switch( result ) diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index 0e0ae383acd5..bc7affeedff6 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -839,7 +839,7 @@ probe_scanner(struct usb_interface *intf, { struct usb_device *dev = interface_to_usbdev (intf); struct scn_usb_data *scn; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; int ep_cnt; @@ -905,13 +905,13 @@ probe_scanner(struct usb_interface *intf, return -ENODEV; } - if (dev->config[0].bNumInterfaces != 1) { + if (dev->config[0].desc.bNumInterfaces != 1) { info("probe_scanner: Only one device interface is supported."); return -ENODEV; } interface = intf->altsetting; - endpoint = interface->endpoint; + endpoint = &interface->endpoint[0].desc; /* * Start checking for two bulk endpoints OR two bulk endpoints *and* one @@ -919,16 +919,16 @@ probe_scanner(struct usb_interface *intf, * setup the handler. FIXME: This is a future enhancement... */ - dbg("probe_scanner: Number of Endpoints:%d", (int) interface->bNumEndpoints); + dbg("probe_scanner: Number of Endpoints:%d", (int) interface->desc.bNumEndpoints); - if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) { + if ((interface->desc.bNumEndpoints != 2) && (interface->desc.bNumEndpoints != 3)) { info("probe_scanner: Only two or three endpoints supported."); return -ENODEV; } ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0; - while (ep_cnt < interface->bNumEndpoints) { + while (ep_cnt < interface->desc.bNumEndpoints) { if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_cnt])) { ep_cnt++; @@ -960,7 +960,7 @@ probe_scanner(struct usb_interface *intf, * should have. */ - switch(interface->bNumEndpoints) { + switch(interface->desc.bNumEndpoints) { case 2: if (!have_bulk_in || !have_bulk_out) { info("probe_scanner: Two bulk endpoints required."); @@ -1024,7 +1024,7 @@ probe_scanner(struct usb_interface *intf, /* Ok, if we detected an interrupt EP, setup a handler for it */ if (have_intr) { dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", scn_minor, have_intr); - FILL_INT_URB(scn->scn_irq, dev, + usb_fill_int_urb(scn->scn_irq, dev, usb_rcvintpipe(dev, have_intr), &scn->button, 1, irq_scanner, scn, // endpoint[(int)have_intr].bInterval); diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index e558134bae9d..fe5ccf692f2b 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -313,7 +313,7 @@ aiptek_probe(struct usb_interface *intf, aiptek->dev.id.version = dev->descriptor.bcdDevice; aiptek->usbdev = dev; - endpoint = intf->altsetting[0].endpoint + 0; + endpoint = &intf->altsetting[0].endpoint[0].desc; if (aiptek->features->pktlen > 10) BUG(); diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 7331d93da09a..2fa6ce372ab2 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1386,7 +1386,7 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) static struct hid_device *usb_hid_configure(struct usb_interface *intf) { - struct usb_interface_descriptor *interface = intf->altsetting + intf->act_altsetting; + struct usb_host_interface *interface = intf->altsetting + intf->act_altsetting; struct usb_device *dev = interface_to_usbdev (intf); struct hid_descriptor *hdesc; struct hid_device *hid; @@ -1402,7 +1402,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if (quirks & HID_QUIRK_IGNORE) return NULL; - if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) || + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { dbg("class descriptor not present\n"); return NULL; @@ -1422,7 +1422,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) return NULL; } - if ((n = hid_get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { + if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { dbg("reading report descriptor failed"); kfree(rdesc); return NULL; @@ -1449,11 +1449,12 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) goto fail; } - for (n = 0; n < interface->bNumEndpoints; n++) { + for (n = 0; n < interface->desc.bNumEndpoints; n++) { - struct usb_endpoint_descriptor *endpoint = &interface->endpoint[n]; + struct usb_endpoint_descriptor *endpoint; int pipe; + endpoint = &interface->endpoint[n].desc; if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ continue; @@ -1493,7 +1494,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; hid->dev = dev; - hid->ifnum = interface->bInterfaceNumber; + hid->ifnum = interface->desc.bInterfaceNumber; hid->name[0] = 0; @@ -1510,7 +1511,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) snprintf(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); usb_make_path(dev, buf, 64); - snprintf(hid->phys, 64, "%s/input%d", buf, intf->altsetting[0].bInterfaceNumber); + snprintf(hid->phys, 64, "%s/input%d", buf, + intf->altsetting[0].desc.bInterfaceNumber); if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 47fb5fd3c852..6e0c7557678d 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -290,14 +290,14 @@ static void powermate_free_buffers(struct usb_device *udev, struct powermate_dev static int powermate_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct powermate_device *pm; int pipe, maxp; char path[64]; interface = intf->altsetting + 0; - endpoint = interface->endpoint + 0; + endpoint = &interface->endpoint[0].desc; if (!(endpoint->bEndpointAddress & 0x80)) return -EIO; if ((endpoint->bmAttributes & 3) != 3) @@ -305,7 +305,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, interface->bInterfaceNumber, NULL, 0, + 0, interface->desc.bInterfaceNumber, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL))) diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index a92742d3fa5e..2b5ebb8c4a3f 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -228,7 +228,7 @@ static int usb_kbd_probe(struct usb_interface *iface, const struct usb_device_id *id) { struct usb_device * dev = interface_to_usbdev(iface); - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; int i, pipe, maxp; @@ -237,10 +237,10 @@ static int usb_kbd_probe(struct usb_interface *iface, interface = &iface->altsetting[iface->act_altsetting]; - if (interface->bNumEndpoints != 1) + if (interface->desc.bNumEndpoints != 1) return -ENODEV; - endpoint = interface->endpoint + 0; + endpoint = &interface->endpoint[0].desc; if (!(endpoint->bEndpointAddress & 0x80)) return -ENODEV; if ((endpoint->bmAttributes & 3) != 3) @@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface, kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; kbd->cr->bRequest = 0x09; kbd->cr->wValue = cpu_to_le16(0x200); - kbd->cr->wIndex = cpu_to_le16(interface->bInterfaceNumber); + kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); kbd->cr->wLength = cpu_to_le16(1); usb_make_path(dev, path, 64); diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 5728136ca14d..15a88e2e11e5 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -121,7 +121,7 @@ static void usb_mouse_close(struct input_dev *dev) static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) { struct usb_device * dev = interface_to_usbdev(intf); - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; int pipe, maxp; @@ -130,10 +130,10 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ interface = &intf->altsetting[intf->act_altsetting]; - if (interface->bNumEndpoints != 1) + if (interface->desc.bNumEndpoints != 1) return -ENODEV; - endpoint = interface->endpoint + 0; + endpoint = &interface->endpoint[0].desc; if (!(endpoint->bEndpointAddress & 0x80)) return -ENODEV; if ((endpoint->bmAttributes & 3) != 3) diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 2f5ef39b4630..5efae4d7b0ab 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -561,7 +561,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->dev.id.version = dev->descriptor.bcdDevice; wacom->usbdev = dev; - endpoint = intf->altsetting[0].endpoint + 0; + endpoint = &intf->altsetting[0].endpoint[0].desc; if (wacom->features->pktlen > 10) BUG(); diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index e3eab2783fd9..1f41067695fe 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -249,7 +249,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id return -ENOMEM; } - ep_irq_in = intf->altsetting[0].endpoint + 0; + ep_irq_in = &intf->altsetting[0].endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index eaa447b2cfaf..ad0c2e2c86a5 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -251,7 +251,7 @@ static int dabusb_alloc_buffers (pdabusb_t s) b->purb->context = b; b->purb->dev = s->usbdev; b->purb->pipe = pipe; - b->purb->transfer_flags = USB_ISO_ASAP; + b->purb->transfer_flags = URB_ISO_ASAP; for (i = 0; i < packets; i++) { b->purb->iso_frame_desc[i].offset = i * pipesize; @@ -728,7 +728,7 @@ static int dabusb_probe (struct usb_interface *intf, if (usbdev->descriptor.bNumConfigurations != 1) return -ENODEV; - if (intf->altsetting->bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999) + if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999) return -ENODEV; retval = usb_register_dev (&dabusb_fops, DABUSB_MINOR, 1, &devnum); @@ -742,7 +742,7 @@ static int dabusb_probe (struct usb_interface *intf, s->usbdev = usbdev; s->devnum = devnum; - if (usb_set_configuration (usbdev, usbdev->config[0].bConfigurationValue) < 0) { + if (usb_set_configuration (usbdev, usbdev->config[0].desc.bConfigurationValue) < 0) { err("set_configuration failed"); goto reject; } diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index 74b1c5303374..1630ba673fde 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c @@ -3662,7 +3662,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * struct uvd *uvd = NULL; int i, nas, model=0, canvasX=0, canvasY=0; int actInterface=-1, inactInterface=-1, maxPS=0; - __u8 ifnum = intf->altsetting->bInterfaceNumber; + __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; unsigned char video_ep = 0; if (debug >= 1) @@ -3740,16 +3740,16 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * } /* Validate all alternate settings */ for (i=0; i < nas; i++) { - const struct usb_interface_descriptor *interface; + const struct usb_host_interface *interface; const struct usb_endpoint_descriptor *endpoint; interface = &dev->actconfig->interface[ifnum].altsetting[i]; - if (interface->bNumEndpoints != 1) { + if (interface->desc.bNumEndpoints != 1) { err("Interface %d. has %u. endpoints!", - ifnum, (unsigned)(interface->bNumEndpoints)); + ifnum, (unsigned)(interface->desc.bNumEndpoints)); return -ENODEV; } - endpoint = &interface->endpoint[0]; + endpoint = &interface->endpoint[0].desc; if (video_ep == 0) video_ep = endpoint->bEndpointAddress; else if (video_ep != endpoint->bEndpointAddress) { diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 89825b4ff9f7..190743d30b2f 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c @@ -381,10 +381,10 @@ static int konicawc_start_data(struct uvd *uvd) int i, errFlag; struct konicawc *cam = (struct konicawc *)uvd->user_data; int pktsz; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; interface = &dev->actconfig->interface[uvd->iface].altsetting[spd_to_iface[cam->speed]]; - pktsz = interface->endpoint[1].wMaxPacketSize; + pktsz = interface->endpoint[1].desc.wMaxPacketSize; DEBUG(1, "pktsz = %d", pktsz); if (!CAMERA_IS_OPERATIONAL(uvd)) { err("Camera is not operational"); @@ -408,7 +408,7 @@ static int konicawc_start_data(struct uvd *uvd) urb->context = uvd; urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); urb->interval = 1; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = uvd->sbuf[i].data; urb->complete = konicawc_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; @@ -423,7 +423,7 @@ static int konicawc_start_data(struct uvd *uvd) urb->context = uvd; urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1); urb->interval = 1; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = cam->sts_buf[i]; urb->complete = konicawc_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; @@ -742,17 +742,17 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id } /* Validate all alternate settings */ for (i=0; i < nas; i++) { - const struct usb_interface_descriptor *interface; + const struct usb_host_interface *interface; const struct usb_endpoint_descriptor *endpoint; interface = &intf->altsetting[i]; - if (interface->bNumEndpoints != 2) { + if (interface->desc.bNumEndpoints != 2) { err("Interface %d. has %u. endpoints!", - interface->bInterfaceNumber, - (unsigned)(interface->bNumEndpoints)); + interface->desc.bInterfaceNumber, + (unsigned)(interface->desc.bNumEndpoints)); return -ENODEV; } - endpoint = &interface->endpoint[1]; + endpoint = &interface->endpoint[1].desc; DEBUG(1, "found endpoint: addr: 0x%2.2x maxps = 0x%4.4x", endpoint->bEndpointAddress, endpoint->wMaxPacketSize); if (video_ep == 0) @@ -763,12 +763,12 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id } if ((endpoint->bmAttributes & 0x03) != 0x01) { err("Interface %d. has non-ISO endpoint!", - interface->bInterfaceNumber); + interface->desc.bInterfaceNumber); return -ENODEV; } if ((endpoint->bEndpointAddress & 0x80) == 0) { err("Interface %d. has ISO OUT endpoint!", - interface->bInterfaceNumber); + interface->desc.bInterfaceNumber); return -ENODEV; } if (endpoint->wMaxPacketSize == 0) { @@ -819,7 +819,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id uvd->flags = 0; uvd->debug = debug; uvd->dev = dev; - uvd->iface = intf->altsetting->bInterfaceNumber; + uvd->iface = intf->altsetting->desc.bInterfaceNumber; uvd->ifaceAltInactive = inactInterface; uvd->ifaceAltActive = actInterface; uvd->video_endp = video_ep; diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index f968afc3d5c6..0f8f81143f61 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c @@ -3949,7 +3949,7 @@ ov51x_init_isoc(struct usb_ov511 *ov) urb->dev = ov->dev; urb->context = &ov->sbuf[n]; urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS); - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ov->sbuf[n].data; urb->complete = ov51x_isoc_irq; urb->number_of_packets = FRAMES_PER_DESC; @@ -5988,7 +5988,7 @@ ov518_configure(struct usb_ov511 *ov) if (ov->bridge == BRG_OV518) { struct usb_interface *ifp = &ov->dev->config[0].interface[0]; - __u16 mxps = ifp->altsetting[7].endpoint[0].wMaxPacketSize; + __u16 mxps = ifp->altsetting[7].endpoint[0].desc.wMaxPacketSize; /* Some OV518s have packet numbering by default, some don't */ if (mxps == 897) @@ -6083,7 +6083,7 @@ ov51x_probe(struct usb_interface *intf, if (dev->descriptor.bNumConfigurations != 1) return -ENODEV; - interface = &intf->altsetting[0]; + interface = &intf->altsetting[0].desc; /* Checking vendor/product should be enough, but what the hell */ if (interface->bInterfaceClass != 0xFF) diff --git a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c index 3f871469997e..f630ff649fd4 100644 --- a/drivers/usb/media/pwc-if.c +++ b/drivers/usb/media/pwc-if.c @@ -761,7 +761,7 @@ static int pwc_isoc_init(struct pwc_device *pdev) struct urb *urb; int i, j, ret; - struct usb_interface_descriptor *idesc; + struct usb_host_interface *idesc; int cur_alt; if (pdev == NULL) @@ -781,9 +781,9 @@ static int pwc_isoc_init(struct pwc_device *pdev) /* Search video endpoint */ pdev->vmax_packet_size = -1; - for (i = 0; i < idesc->bNumEndpoints; i++) - if ((idesc->endpoint[i].bEndpointAddress & 0xF) == pdev->vendpoint) { - pdev->vmax_packet_size = idesc->endpoint[i].wMaxPacketSize; + for (i = 0; i < idesc->desc.bNumEndpoints; i++) + if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) { + pdev->vmax_packet_size = idesc->endpoint[i].desc.wMaxPacketSize; break; } @@ -821,7 +821,7 @@ static int pwc_isoc_init(struct pwc_device *pdev) urb->interval = 1; // devik urb->dev = udev; urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = pdev->sbuf[i].data; urb->transfer_buffer_length = ISO_BUFFER_SIZE; urb->complete = pwc_isoc_handler; @@ -1552,13 +1552,15 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id free_mem_leak(); /* Check if we can handle this device */ - Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, intf->altsetting->bInterfaceNumber); + Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", + udev->descriptor.idVendor, udev->descriptor.idProduct, + intf->altsetting->desc.bInterfaceNumber); /* the interfaces are probed one by one. We are only interested in the video interface (0) now. Interface 1 is the Audio Control, and interface 2 Audio itself. */ - if (intf->altsetting->bInterfaceNumber > 0) + if (intf->altsetting->desc.bInterfaceNumber > 0) return -ENODEV; vendor_id = udev->descriptor.idVendor; diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index 87029897b56d..fd090f2fd147 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c @@ -609,7 +609,7 @@ static int se401_start_stream(struct usb_se401 *se401) if(!urb) return -ENOMEM; - FILL_BULK_URB(urb, se401->dev, + usb_fill_bulk_urb(urb, se401->dev, usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT), se401->sbuf[i].data, SE401_PACKETSIZE, se401_video_irq, @@ -1420,7 +1420,7 @@ static int se401_init(struct usb_se401 *se401, int button) info("Allocation of inturb failed"); return 1; } - FILL_INT_URB(se401->inturb, se401->dev, + usb_fill_int_urb(se401->inturb, se401->dev, usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT), &se401->button, sizeof(se401->button), se401_button_irq, @@ -1456,7 +1456,7 @@ static int se401_probe(struct usb_interface *intf, if (dev->descriptor.bNumConfigurations != 1) return -ENODEV; - interface = &intf->altsetting[0]; + interface = &intf->altsetting[0].desc; /* Is it an se401? */ if (dev->descriptor.idVendor == 0x03e8 && diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 3b048bd3152a..4e341c3b94cb 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c @@ -1451,7 +1451,7 @@ static struct video_device stv680_template = { static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct usb_stv *stv680; char *camera_name = NULL; diff --git a/drivers/usb/media/ultracam.c b/drivers/usb/media/ultracam.c index 75fe954716be..f0f3a8e9d60a 100644 --- a/drivers/usb/media/ultracam.c +++ b/drivers/usb/media/ultracam.c @@ -569,17 +569,17 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id } /* Validate all alternate settings */ for (i=0; i < nas; i++) { - const struct usb_interface_descriptor *interface; + const struct usb_host_interface *interface; const struct usb_endpoint_descriptor *endpoint; interface = &intf->altsetting[i]; - if (interface->bNumEndpoints != 1) { + if (interface->desc.bNumEndpoints != 1) { err("Interface %d. has %u. endpoints!", - interface->bInterfaceNumber, - (unsigned)(interface->bNumEndpoints)); + interface->desc.bInterfaceNumber, + (unsigned)(interface->desc.bNumEndpoints)); return -ENODEV; } - endpoint = &interface->endpoint[0]; + endpoint = &interface->endpoint[0].desc; if (video_ep == 0) video_ep = endpoint->bEndpointAddress; else if (video_ep != endpoint->bEndpointAddress) { @@ -588,12 +588,12 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id } if ((endpoint->bmAttributes & 0x03) != 0x01) { err("Interface %d. has non-ISO endpoint!", - interface->bInterfaceNumber); + interface->desc.bInterfaceNumber); return -ENODEV; } if ((endpoint->bEndpointAddress & 0x80) == 0) { err("Interface %d. has ISO OUT endpoint!", - interface->bInterfaceNumber); + interface->desc.bInterfaceNumber); return -ENODEV; } if (endpoint->wMaxPacketSize == 0) { @@ -636,7 +636,7 @@ static int ultracam_probe(struct usb_interface *intf, const struct usb_device_id uvd->flags = flags; uvd->debug = debug; uvd->dev = dev; - uvd->iface = intf->altsetting->bInterfaceNumber; + uvd->iface = intf->altsetting->desc.bInterfaceNumber; uvd->ifaceAltInactive = inactInterface; uvd->ifaceAltActive = actInterface; uvd->video_endp = video_ep; diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 4f5061d1a657..9aeffc958b04 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c @@ -1914,7 +1914,7 @@ static int usbvideo_StartDataPump(struct uvd *uvd) urb->context = uvd; urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp); urb->interval = 1; - urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = uvd->sbuf[i].data; urb->complete = usbvideo_IsocIrq; urb->number_of_packets = FRAMES_PER_DESC; diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index fa2ca5098877..178228860c7f 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -1253,7 +1253,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); int bulkEndpoint = 0; - const struct usb_interface_descriptor *interface; + const struct usb_host_interface *interface; const struct usb_endpoint_descriptor *endpoint; struct vicam_camera *cam; @@ -1268,8 +1268,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) interface = &intf->altsetting[0]; DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n", - ifnum, (unsigned) (interface->bNumEndpoints)); - endpoint = &interface->endpoint[0]; + ifnum, (unsigned) (interface->desc.bNumEndpoints)); + endpoint = &interface->endpoint[0].desc; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) { diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index beac2aba435f..c245ee3d455c 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -445,7 +445,7 @@ static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb) /* cancel an urb which is submitted to the chain the result is 0 if the urb is cancelled, or -EINPROGRESS if - USB_ASYNC_UNLINK is set and the function is successfully started. + URB_ASYNC_UNLINK is set and the function is successfully started. */ static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) { @@ -534,7 +534,7 @@ static void auerchain_unlink_all (pauerchain_t acp) acep = acp->active; if (acep) { urbp = acep->urbp; - urbp->transfer_flags &= ~USB_ASYNC_UNLINK; + urbp->transfer_flags &= ~URB_ASYNC_UNLINK; dbg ("unlink active urb"); usb_unlink_urb (urbp); } @@ -717,7 +717,7 @@ static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsi dr->wIndex = cpu_to_le16 (index); dr->wLength = cpu_to_le16 (size); - FILL_CONTROL_URB (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */ + usb_fill_control_urb (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */ (usb_complete_t)auerchain_blocking_completion,0); ret = auerchain_start_wait_urb (acp, urb, timeout, &length); @@ -919,7 +919,7 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) bp->dr->wLength = bp->dr->wValue; /* temporary stored */ bp->dr->wValue = cpu_to_le16 (1); /* Retry Flag */ /* bp->dr->index = channel id; remains */ - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), + usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->wLength), (usb_complete_t)auerswald_ctrlread_complete,bp); @@ -967,7 +967,7 @@ static void auerswald_ctrlread_complete (struct urb * urb) bp->dr->wValue = bp->dr->wLength; /* temporary storage */ // bp->dr->wIndex channel ID remains bp->dr->wLength = cpu_to_le16 (32); /* >= 8 bytes */ - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), + usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), (unsigned char*)bp->dr, bp->bufp, 32, (usb_complete_t)auerswald_ctrlread_wretcomplete,bp); @@ -1095,7 +1095,7 @@ static void auerswald_int_complete (struct urb * urb) bp->dr->wValue = cpu_to_le16 (0); bp->dr->wIndex = cpu_to_le16 (channelid | AUH_DIRECT | AUH_UNSPLIT); bp->dr->wLength = cpu_to_le16 (bytecount); - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), + usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0), (unsigned char*)bp->dr, bp->bufp, bytecount, (usb_complete_t)auerswald_ctrlread_complete,bp); @@ -1164,7 +1164,7 @@ static int auerswald_int_open (pauerswald_t cp) } } /* setup urb */ - FILL_INT_URB (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); + usb_fill_int_urb (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); /* start the urb */ cp->inturbp->status = 0; /* needed! */ ret = usb_submit_urb (cp->inturbp, GFP_KERNEL); @@ -1830,7 +1830,7 @@ write_again: bp->dr->wValue = cpu_to_le16 (0); bp->dr->wIndex = cpu_to_le16 (ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT); bp->dr->wLength = cpu_to_le16 (len+AUH_SIZE); - FILL_CONTROL_URB (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), + usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0), (unsigned char*)bp->dr, bp->bufp, len+AUH_SIZE, auerchar_ctrlwrite_complete, bp); /* up we go */ @@ -1943,7 +1943,7 @@ static int auerswald_probe (struct usb_interface *intf, return -ENODEV; /* we use only the first -and only- interface */ - if (intf->altsetting->bInterfaceNumber != 0) + if (intf->altsetting->desc.bInterfaceNumber != 0) return -ENODEV; /* prevent module unloading while sleeping */ diff --git a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c index 88634bd49162..db226465bf9c 100644 --- a/drivers/usb/misc/brlvger.c +++ b/drivers/usb/misc/brlvger.c @@ -290,7 +290,7 @@ brlvger_probe (struct usb_interface *intf, int i; int retval; struct usb_endpoint_descriptor *endpoint; - struct usb_interface_descriptor *actifsettings; + struct usb_host_interface *actifsettings; /* protects against reentrance: once we've found a free slot we reserve it.*/ static DECLARE_MUTEX(reserve_sem); @@ -299,13 +299,13 @@ brlvger_probe (struct usb_interface *intf, actifsettings = dev->actconfig->interface->altsetting; if( dev->descriptor.bNumConfigurations != 1 - || dev->config->bNumInterfaces != 1 - || actifsettings->bNumEndpoints != 1 ) { + || dev->config->desc.bNumInterfaces != 1 + || actifsettings->desc.bNumEndpoints != 1 ) { err ("Bogus braille display config info"); return -ENODEV; } - endpoint = actifsettings->endpoint; + endpoint = &actifsettings->endpoint [0].desc; if (!(endpoint->bEndpointAddress & 0x80) || ((endpoint->bmAttributes & 3) != 0x03)) { err ("Bogus braille display config info, wrong endpoints"); @@ -514,7 +514,7 @@ brlvger_open(struct inode *inode, struct file *file) err("Unable to allocate URB"); goto error; } - FILL_INT_URB( priv->intr_urb, priv->dev, + usb_fill_int_urb( priv->intr_urb, priv->dev, usb_rcvintpipe(priv->dev, priv->in_interrupt->bEndpointAddress), priv->intr_buff, sizeof(priv->intr_buff), diff --git a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c index 45bdd24700b2..50118caa0e44 100644 --- a/drivers/usb/misc/speedtouch.c +++ b/drivers/usb/misc/speedtouch.c @@ -592,7 +592,7 @@ static void udsl_usb_send_data_complete (struct urb *urb) ctx->skb = skb_dequeue (&(instance->sndqueue)); ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc; spin_unlock_irqrestore (&instance->sndqlock, flags); - FILL_BULK_URB (urb, + usb_fill_bulk_urb (urb, instance->usb_dev, usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), (unsigned char *) ctx->skb->data, @@ -673,7 +673,7 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc spin_unlock_irqrestore (&instance->sndqlock, flags); /* submit packet */ - FILL_BULK_URB (urb, + usb_fill_bulk_urb (urb, instance->usb_dev, usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), (unsigned char *) skb->data, @@ -742,7 +742,7 @@ void udsl_usb_data_receive (struct urb *urb) return; } - FILL_BULK_URB (urb, + usb_fill_bulk_urb (urb, instance->usb_dev, usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), (unsigned char *) ctx->skb->data, @@ -790,7 +790,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance) break; }; - FILL_BULK_URB (ctx->urb, + usb_fill_bulk_urb (ctx->urb, instance->usb_dev, usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), (unsigned char *) ctx->skb->data, @@ -917,7 +917,7 @@ static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void * static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->bInterfaceNumber; + int ifnum = intf->altsetting->desc.bInterfaceNumber; int i; unsigned char mac[6]; unsigned char mac_str[13]; diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c index 6dada5ddf6f4..c535d28da923 100644 --- a/drivers/usb/misc/tiglusb.c +++ b/drivers/usb/misc/tiglusb.c @@ -64,7 +64,7 @@ static devfs_handle_t devfs_handle; static inline int clear_device (struct usb_device *dev) { - if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) { + if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { err ("clear_device failed"); return -1; } @@ -351,7 +351,7 @@ tiglusb_probe (struct usb_interface *intf, && (dev->descriptor.idVendor != 0x451)) return -ENODEV; - if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) { + if (usb_set_configuration (dev, dev->config[0].desc.bConfigurationValue) < 0) { err ("tiglusb_probe: set_configuration failed"); return -ENODEV; } diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 504be379b594..faa2ee6d40bb 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -290,7 +290,7 @@ static int get_altsetting (struct usbtest_dev *dev) retval = usb_control_msg (udev, usb_rcvctrlpipe (udev, 0), USB_REQ_GET_INTERFACE, USB_DIR_IN|USB_RECIP_INTERFACE, - 0, iface->altsetting [0].bInterfaceNumber, + 0, iface->altsetting [0].desc.bInterfaceNumber, dev->buf, 1, HZ * USB_CTRL_GET_TIMEOUT); switch (retval) { case 1: @@ -308,7 +308,7 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) { struct usb_interface *iface = dev->intf; struct usb_device *udev; - struct usb_interface_descriptor *iface_as; + struct usb_host_interface *iface_as; int i, ret; if (alternate < 0 || alternate >= iface->num_altsetting) @@ -317,8 +317,8 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) udev = interface_to_usbdev (iface); if ((ret = usb_control_msg (udev, usb_sndctrlpipe (udev, 0), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, - iface->altsetting [alternate].bAlternateSetting, - iface->altsetting [alternate].bInterfaceNumber, + alternate, + iface->altsetting->desc.bInterfaceNumber, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) return ret; @@ -328,8 +328,8 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) /* prevent requests using previous endpoint settings */ iface_as = iface->altsetting + iface->act_altsetting; - for (i = 0; i < iface_as->bNumEndpoints; i++) { - u8 ep = iface_as->endpoint [i].bEndpointAddress; + for (i = 0; i < iface_as->desc.bNumEndpoints; i++) { + u8 ep = iface_as->endpoint [i].desc.bEndpointAddress; int out = !(ep & USB_DIR_IN); ep &= USB_ENDPOINT_NUMBER_MASK; @@ -340,14 +340,14 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) /* reset toggles and maxpacket for all endpoints affected */ iface_as = iface->altsetting + iface->act_altsetting; - for (i = 0; i < iface_as->bNumEndpoints; i++) { - u8 ep = iface_as->endpoint [i].bEndpointAddress; + for (i = 0; i < iface_as->desc.bNumEndpoints; i++) { + u8 ep = iface_as->endpoint [i].desc.bEndpointAddress; int out = !(ep & USB_DIR_IN); ep &= USB_ENDPOINT_NUMBER_MASK; usb_settoggle (udev, ep, out, 0); (out ? udev->epmaxpacketout : udev->epmaxpacketin ) [ep] - = iface_as->endpoint [i].wMaxPacketSize; + = iface_as->endpoint [i].desc.wMaxPacketSize; } return 0; @@ -415,10 +415,10 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* 9.2.3 constrains the range here, and Linux ensures * they're ordered meaningfully in this array */ - if (iface->altsetting [i].bAlternateSetting != i) { + if (iface->altsetting [i].desc.bAlternateSetting != i) { dbg ("%s, illegal alt [%d].bAltSetting = %d", dev->id, i, - iface->altsetting [i] + iface->altsetting [i].desc .bAlternateSetting); return -EDOM; } @@ -447,7 +447,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [real world] get_config unimplemented if there's only one */ if (udev->descriptor.bNumConfigurations != 1) { - int expected = udev->actconfig->bConfigurationValue; + int expected = udev->actconfig->desc.bConfigurationValue; /* [9.4.2] get_configuration always works * ... although some cheap devices (like one TI Hub I've got) @@ -534,7 +534,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) // the device's remote wakeup feature ... if we can, test that here retval = usb_get_status (udev, USB_RECIP_INTERFACE, - iface->altsetting [0].bInterfaceNumber, dev->buf); + iface->altsetting [0].desc.bInterfaceNumber, dev->buf); if (retval != 2) { dbg ("%s get interface status --> %d", dev->id, retval); return (retval < 0) ? retval : -EDOM; @@ -591,7 +591,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b if (dev->info->alt >= 0) { int res; - if (intf->altsetting->bInterfaceNumber) + if (intf->altsetting->desc.bInterfaceNumber) return -ENODEV; res = set_altsetting (dev, dev->info->alt); if (res) { @@ -823,7 +823,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) /* use the same kind of id the hid driver shows */ snprintf (dev->id, sizeof dev->id, "%s-%s:%d", udev->bus->bus_name, udev->devpath, - intf->altsetting [0].bInterfaceNumber); + intf->altsetting [0].desc.bInterfaceNumber); dev->intf = intf; /* cacheline-aligned scratch for i/o */ diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 36efa886c9e0..3756af894c20 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -549,8 +549,8 @@ static int uss720_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usbdev = interface_to_usbdev(intf); - struct usb_interface_descriptor *interface; - struct usb_endpoint_descriptor *endpoint; + struct usb_host_interface *interface; + struct usb_host_endpoint *endpoint; struct parport_uss720_private *priv; struct parport *pp; int i; @@ -562,7 +562,7 @@ static int uss720_probe(struct usb_interface *intf, if (intf->num_altsetting != 3) return -ENODEV; - i = usb_set_interface(usbdev, intf->altsetting->bInterfaceNumber, 2); + i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); printk(KERN_DEBUG "uss720: set inteface result %d\n", i); interface = &intf->altsetting[2]; @@ -593,7 +593,7 @@ static int uss720_probe(struct usb_interface *intf, priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], priv->reg[4], priv->reg[5], priv->reg[6]); endpoint = &interface->endpoint[2]; - printk(KERN_DEBUG "uss720: epaddr %d interval %d\n", endpoint->bEndpointAddress, endpoint->bInterval); + printk(KERN_DEBUG "uss720: epaddr %d interval %d\n", endpoint->desc.bEndpointAddress, endpoint->desc.bInterval); #if 0 priv->irqpipe = usb_rcvctrlpipe(usbdev, endpoint->bEndpointAddress); i = usb_request_irq(usbdev, priv->irqpipe, diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 84cf473b7bed..57c249c3eb5e 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c @@ -381,7 +381,7 @@ static void catc_tx_done(struct urb *urb) if (urb->status == -ECONNRESET) { dbg("Tx Reset."); - urb->transfer_flags &= ~USB_ASYNC_UNLINK; + urb->transfer_flags &= ~URB_ASYNC_UNLINK; urb->status = 0; catc->netdev->trans_start = jiffies; catc->stats.tx_errors++; @@ -443,7 +443,7 @@ static void catc_tx_timeout(struct net_device *netdev) struct catc *catc = netdev->priv; warn("Transmit timed out."); - catc->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; + catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; usb_unlink_urb(catc->tx_urb); } @@ -783,7 +783,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id u8 broadcast[6]; int i, pktsz; - if (usb_set_interface(usbdev, intf->altsetting->bInterfaceNumber, 1)) { + if (usb_set_interface(usbdev, + intf->altsetting->desc.bInterfaceNumber, 1)) { err("Can't set altsetting 1."); return -EIO; } @@ -847,16 +848,16 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id pktsz = RX_MAX_BURST * (PKT_SZ + 2); } - FILL_CONTROL_URB(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), + usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), NULL, NULL, 0, catc_ctrl_done, catc); - FILL_BULK_URB(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), + usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), NULL, 0, catc_tx_done, catc); - FILL_BULK_URB(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), + usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), catc->rx_buf, pktsz, catc_rx_done, catc); - FILL_INT_URB(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), + usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), catc->irq_buf, 2, catc_irq_done, catc, 1); if (!catc->is_f5u011) { diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c index 513f83c9bda1..2b9626c44276 100644 --- a/drivers/usb/net/cdc-ether.c +++ b/drivers/usb/net/cdc-ether.c @@ -125,7 +125,7 @@ static void read_bulk_callback( struct urb *urb ) goon: // Prep the USB to wait for another frame - FILL_BULK_URB( ether_dev->rx_urb, ether_dev->usb, + usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb, usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in), ether_dev->rx_buff, ether_dev->wMaxSegmentSize, read_bulk_callback, ether_dev ); @@ -259,7 +259,7 @@ static void CDCEther_tx_timeout( struct net_device *net ) warn("%s: Tx timed out.", net->name); // Tear the waiting frame off the list - ether_dev->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; + ether_dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; usb_unlink_urb( ether_dev->tx_urb ); // Update statistics @@ -293,7 +293,7 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) memcpy(ether_dev->tx_buff, skb->data, skb->len); // Fill in the URB for shipping it out. - FILL_BULK_URB( ether_dev->tx_urb, ether_dev->usb, + usb_fill_bulk_urb( ether_dev->tx_urb, ether_dev->usb, usb_sndbulkpipe(ether_dev->usb, ether_dev->data_ep_out), ether_dev->tx_buff, ether_dev->wMaxSegmentSize, write_bulk_callback, ether_dev ); @@ -344,7 +344,7 @@ static int CDCEther_open(struct net_device *net) } // Prep a receive URB - FILL_BULK_URB( ether_dev->rx_urb, ether_dev->usb, + usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb, usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in), ether_dev->rx_buff, ether_dev->wMaxSegmentSize, read_bulk_callback, ether_dev ); @@ -723,9 +723,9 @@ static int parse_ethernet_class_information( unsigned char *data, int length, et static int find_and_parse_ethernet_class_information( struct usb_device *device, ether_dev_t *ether_dev ) { - struct usb_config_descriptor *conf = NULL; + struct usb_host_config *conf = NULL; struct usb_interface *comm_intf_group = NULL; - struct usb_interface_descriptor *comm_intf = NULL; + struct usb_host_interface *comm_intf = NULL; int rc = -1; // The assumption here is that find_ethernet_comm_interface // and find_valid_configuration @@ -760,9 +760,9 @@ static int find_and_parse_ethernet_class_information( struct usb_device *device, static int get_data_interface_endpoints( struct usb_device *device, ether_dev_t *ether_dev ) { - struct usb_config_descriptor *conf = NULL; + struct usb_host_config *conf = NULL; struct usb_interface *data_intf_group = NULL; - struct usb_interface_descriptor *data_intf = NULL; + struct usb_host_interface *data_intf = NULL; // Walk through and get to the data interface we are checking. conf = &( device->config[ether_dev->configuration_num] ); @@ -774,30 +774,30 @@ static int get_data_interface_endpoints( struct usb_device *device, ether_dev_t ether_dev->data_ep_out = 0; // If these are not BULK endpoints, we don't want them - if ( data_intf->endpoint[0].bmAttributes != 0x02 ) { + if ( data_intf->endpoint[0].desc.bmAttributes != 0x02 ) { return -1; - } if ( data_intf->endpoint[1].bmAttributes != 0x02 ) { + } if ( data_intf->endpoint[1].desc.bmAttributes != 0x02 ) { return -1; } // Check the first endpoint to see if it is IN or OUT - if ( data_intf->endpoint[0].bEndpointAddress & 0x80 ) { + if ( data_intf->endpoint[0].desc.bEndpointAddress & 0x80 ) { // This endpoint is IN - ether_dev->data_ep_in = data_intf->endpoint[0].bEndpointAddress & 0x7F; + ether_dev->data_ep_in = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F; } else { // This endpoint is OUT - ether_dev->data_ep_out = data_intf->endpoint[0].bEndpointAddress & 0x7F; - ether_dev->data_ep_out_size = data_intf->endpoint[0].wMaxPacketSize; + ether_dev->data_ep_out = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F; + ether_dev->data_ep_out_size = data_intf->endpoint[0].desc.wMaxPacketSize; } // Check the second endpoint to see if it is IN or OUT - if ( data_intf->endpoint[1].bEndpointAddress & 0x80 ) { + if ( data_intf->endpoint[1].desc.bEndpointAddress & 0x80 ) { // This endpoint is IN - ether_dev->data_ep_in = data_intf->endpoint[1].bEndpointAddress & 0x7F; + ether_dev->data_ep_in = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F; } else { // This endpoint is OUT - ether_dev->data_ep_out = data_intf->endpoint[1].bEndpointAddress & 0x7F; - ether_dev->data_ep_out_size = data_intf->endpoint[1].wMaxPacketSize; + ether_dev->data_ep_out = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F; + ether_dev->data_ep_out_size = data_intf->endpoint[1].desc.wMaxPacketSize; } // Now make sure we got both an IN and an OUT @@ -811,7 +811,7 @@ static int get_data_interface_endpoints( struct usb_device *device, ether_dev_t static int verify_ethernet_data_interface( struct usb_device *device, ether_dev_t *ether_dev ) { - struct usb_config_descriptor *conf = NULL; + struct usb_host_config *conf = NULL; struct usb_interface *data_intf_group = NULL; struct usb_interface_descriptor *data_intf = NULL; int rc = -1; @@ -834,7 +834,7 @@ static int verify_ethernet_data_interface( struct usb_device *device, ether_dev_ // Walk through every possible setting for this interface until // we find what makes us happy. for ( altset_num = 0; altset_num < data_intf_group->num_altsetting; altset_num++ ) { - data_intf = &( data_intf_group->altsetting[altset_num] ); + data_intf = &( data_intf_group->altsetting[altset_num].desc ); // Is this a data interface we like? if ( ( data_intf->bInterfaceClass == 0x0A ) @@ -875,7 +875,7 @@ static int verify_ethernet_data_interface( struct usb_device *device, ether_dev_ static int find_ethernet_comm_interface( struct usb_device *device, ether_dev_t *ether_dev ) { - struct usb_config_descriptor *conf = NULL; + struct usb_host_config *conf = NULL; struct usb_interface *comm_intf_group = NULL; struct usb_interface_descriptor *comm_intf = NULL; int intf_num; @@ -886,12 +886,12 @@ static int find_ethernet_comm_interface( struct usb_device *device, ether_dev_t // We need to check and see if any of these interfaces are something we want. // Walk through each interface one at a time - for ( intf_num = 0; intf_num < conf->bNumInterfaces; intf_num++ ) { + for ( intf_num = 0; intf_num < conf->desc.bNumInterfaces; intf_num++ ) { comm_intf_group = &( conf->interface[intf_num] ); // Now for each of those interfaces, check every possible // alternate setting. for ( altset_num = 0; altset_num < comm_intf_group->num_altsetting; altset_num++ ) { - comm_intf = &( comm_intf_group->altsetting[altset_num] ); + comm_intf = &( comm_intf_group->altsetting[altset_num].desc); // Is this a communication class of interface of the // ethernet subclass variety. @@ -944,7 +944,7 @@ static int find_ethernet_comm_interface( struct usb_device *device, ether_dev_t static int find_valid_configuration( struct usb_device *device, ether_dev_t *ether_dev ) { - struct usb_config_descriptor *conf = NULL; + struct usb_host_config *conf = NULL; int conf_num; int rc; @@ -953,7 +953,7 @@ static int find_valid_configuration( struct usb_device *device, ether_dev_t *eth conf = &( device->config[conf_num] ); // Our first requirement : 2 interfaces - if ( conf->bNumInterfaces != 2 ) { + if ( conf->desc.bNumInterfaces != 2 ) { // I currently don't know how to handle devices with any number of interfaces // other than 2. continue; @@ -962,7 +962,7 @@ static int find_valid_configuration( struct usb_device *device, ether_dev_t *eth // This one passed our first check, fill in some // useful data ether_dev->configuration_num = conf_num; - ether_dev->bConfigurationValue = conf->bConfigurationValue; + ether_dev->bConfigurationValue = conf->desc.bConfigurationValue; // Now run it through the ringers and see what comes // out the other side. @@ -983,14 +983,14 @@ static int find_valid_configuration( struct usb_device *device, ether_dev_t *eth // has claimed any of the devices interfaces ///////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -static int check_for_claimed_interfaces( struct usb_config_descriptor *config ) +static int check_for_claimed_interfaces( struct usb_host_config *config ) { struct usb_interface *comm_intf_group; int intf_num; // Go through all the interfaces and make sure none are // claimed by anybody else. - for ( intf_num = 0; intf_num < config->bNumInterfaces; intf_num++ ) { + for ( intf_num = 0; intf_num < config->desc.bNumInterfaces; intf_num++ ) { comm_intf_group = &( config->interface[intf_num] ); if ( usb_interface_claimed( comm_intf_group ) ) { // Somebody has beat us to this guy. diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index cea07c41875b..32e669e81758 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -449,7 +449,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) usb_sndctrlpipe(kaweth->dev, 0), USB_REQ_SET_CONFIGURATION, 0, - kaweth->dev->config[0].bConfigurationValue, + kaweth->dev->config[0].desc.bConfigurationValue, 0, NULL, 0, @@ -514,7 +514,7 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, { int result; - FILL_BULK_URB(kaweth->rx_urb, + usb_fill_bulk_urb(kaweth->rx_urb, kaweth->dev, usb_rcvbulkpipe(kaweth->dev, 1), kaweth->rx_buf, @@ -620,7 +620,7 @@ static int kaweth_open(struct net_device *net) if (res) return -EIO; - FILL_INT_URB( + usb_fill_int_urb( kaweth->irq_urb, kaweth->dev, usb_rcvintpipe(kaweth->dev, 3), @@ -752,7 +752,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) *private_header = cpu_to_le16(skb->len); kaweth->tx_skb = skb; - FILL_BULK_URB(kaweth->tx_urb, + usb_fill_bulk_urb(kaweth->tx_urb, kaweth->dev, usb_sndbulkpipe(kaweth->dev, 2), private_header, @@ -760,7 +760,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) kaweth_usb_transmit_complete, kaweth); kaweth->end = 0; - kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; + kaweth->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) { @@ -1207,7 +1207,7 @@ int kaweth_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, if (!urb) return -ENOMEM; - FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, + usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, (usb_complete_t)usb_api_blocking_completion,0); retv = usb_start_wait_urb(urb, timeout, &length); diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 19f3b82d54fc..34ed89241550 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -143,7 +143,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->dr.wLength = cpu_to_le16p(&size); pegasus->ctrl_urb->transfer_buffer_length = size; - FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb, + usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, buffer, size, ctrl_callback, pegasus); @@ -194,7 +194,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->dr.wLength = cpu_to_le16p(&size); pegasus->ctrl_urb->transfer_buffer_length = size; - FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb, + usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, buffer, size, ctrl_callback, pegasus); @@ -243,7 +243,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) pegasus->dr.wLength = cpu_to_le16(1); pegasus->ctrl_urb->transfer_buffer_length = 1; - FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb, + usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, buffer, 1, ctrl_callback, pegasus); @@ -275,7 +275,7 @@ static int update_eth_regs_async(pegasus_t * pegasus) pegasus->dr.wLength = cpu_to_le16(3); pegasus->ctrl_urb->transfer_buffer_length = 3; - FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb, + usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, pegasus->eth_regs, 3, ctrl_callback, pegasus); @@ -596,7 +596,7 @@ static void read_bulk_callback(struct urb *urb) if (pegasus->rx_skb == NULL) goto tl_sched; goon: - FILL_BULK_URB(pegasus->rx_urb, pegasus->usb, + usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); @@ -635,7 +635,7 @@ static void rx_fixup(unsigned long data) tasklet_schedule(&pegasus->rx_tl); return; } - FILL_BULK_URB(pegasus->rx_urb, pegasus->usb, + usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); @@ -718,7 +718,7 @@ static void pegasus_tx_timeout(struct net_device *net) return; warn("%s: Tx timed out.", net->name); - pegasus->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; + pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; usb_unlink_urb(pegasus->tx_urb); pegasus->stats.tx_errors++; } @@ -734,7 +734,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) ((__u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16); memcpy(pegasus->tx_buff + 2, skb->data, skb->len); - FILL_BULK_URB(pegasus->tx_urb, pegasus->usb, + usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb, usb_sndbulkpipe(pegasus->usb, 2), pegasus->tx_buff, count, write_bulk_callback, pegasus); @@ -852,13 +852,13 @@ static int pegasus_open(struct net_device *net) return -ENOMEM; down(&pegasus->sem); - FILL_BULK_URB(pegasus->rx_urb, pegasus->usb, + usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) warn("%s: failed rx_urb %d", __FUNCTION__, res); - FILL_INT_URB(pegasus->intr_urb, pegasus->usb, + usb_fill_int_urb(pegasus->intr_urb, pegasus->usb, usb_rcvintpipe(pegasus->usb, 3), pegasus->intr_buff, sizeof(pegasus->intr_buff), intr_callback, pegasus, pegasus->intr_interval); @@ -1061,7 +1061,7 @@ static int pegasus_probe(struct usb_interface *intf, pegasus_t *pegasus; int dev_index = id - pegasus_ids; - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { + if (usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue)) { err("usb_set_configuration() failed"); return -ENODEV; } diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 7517394ebb92..bb38b4caa353 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -174,7 +174,7 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) dev->dr.wIndex = 0; dev->dr.wLength = cpu_to_le16(size); dev->ctrl_urb->transfer_buffer_length = size; - FILL_CONTROL_URB(dev->ctrl_urb, dev->udev, + usb_fill_control_urb(dev->ctrl_urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, &dev->rx_creg, size, ctrl_callback, dev); if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) @@ -387,7 +387,7 @@ static void read_bulk_callback(struct urb *urb) dev->rx_skb = skb; goon: - FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), + usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { set_bit(RX_URB_FAIL, &dev->flags); @@ -420,7 +420,7 @@ static void rx_fixup(unsigned long data) if (skb == NULL) goto tlsched; dev->rx_skb = skb; - FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), + usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); try_again: if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { @@ -573,7 +573,7 @@ static void rtl8150_tx_timeout(struct net_device *netdev) if (!dev) return; warn("%s: Tx timeout.", netdev->name); - dev->tx_urb->transfer_flags |= USB_ASYNC_UNLINK; + dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; usb_unlink_urb(dev->tx_urb); dev->stats.tx_errors++; } @@ -610,7 +610,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) count = (skb->len < 60) ? 60 : skb->len; count = (count & 0x3f) ? count : count + 1; dev->tx_skb = skb; - FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), + usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), skb->data, count, write_bulk_callback, dev); if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { warn("failed tx_urb %d\n", res); @@ -640,11 +640,11 @@ static int rtl8150_open(struct net_device *netdev) return -ENOMEM; down(&dev->sem); - FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), + usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); - FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), + usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), dev->intr_buff, sizeof(dev->intr_buff), intr_callback, dev, dev->intr_interval); if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) @@ -789,7 +789,7 @@ static int rtl8150_probe(struct usb_interface *intf, rtl8150_t *dev; struct net_device *netdev; - if (usb_set_configuration(udev, udev->config[0].bConfigurationValue)) { + if (usb_set_configuration(udev, udev->config[0].desc.bConfigurationValue)) { err("usb_set_configuration() failed"); return -EIO; } diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 9c21bc806400..69a67505b02c 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -532,7 +532,7 @@ static int genelink_init (struct usbnet *dev) } // fill irq urb - FILL_INT_URB (priv->irq_urb, dev->udev, + usb_fill_int_urb (priv->irq_urb, dev->udev, usb_rcvintpipe (dev->udev, GENELINK_INTERRUPT_PIPE), priv->irq_buf, INTERRUPT_BUFSIZE, gl_interrupt_complete, 0, @@ -1472,14 +1472,14 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) entry->state = rx_start; entry->length = 0; - FILL_BULK_URB (urb, dev->udev, + usb_fill_bulk_urb (urb, dev->udev, usb_rcvbulkpipe (dev->udev, dev->driver_info->in), skb->data, size, rx_complete, skb); - urb->transfer_flags |= USB_ASYNC_UNLINK; + urb->transfer_flags |= URB_ASYNC_UNLINK; #if 0 // Idle-but-posted reads with UHCI really chew up // PCI bandwidth unless FSBR is disabled - urb->transfer_flags |= USB_NO_FSBR; + urb->transfer_flags |= URB_NO_FSBR; #endif spin_lock_irqsave (&dev->rxq.lock, lockflags); @@ -1954,10 +1954,10 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) if ((length % EP_SIZE (dev)) == 0) skb->len++; - FILL_BULK_URB (urb, dev->udev, + usb_fill_bulk_urb (urb, dev->udev, usb_sndbulkpipe (dev->udev, info->out), skb->data, skb->len, tx_complete, skb); - urb->transfer_flags |= USB_ASYNC_UNLINK; + urb->transfer_flags |= URB_ASYNC_UNLINK; // FIXME urb->timeout = ... jiffies ... ; spin_lock_irqsave (&dev->txq.lock, flags); @@ -2125,7 +2125,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) { struct usbnet *dev; struct net_device *net; - struct usb_interface_descriptor *interface; + struct usb_host_interface *interface; struct driver_info *info; struct usb_device *xdev; @@ -2135,8 +2135,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) interface = &udev->altsetting [udev->act_altsetting]; if (!(info->flags & FLAG_NO_SETINT)) { - if (usb_set_interface (xdev, interface->bInterfaceNumber, - interface->bAlternateSetting) < 0) { + if (usb_set_interface (xdev, interface->desc.bInterfaceNumber, + interface->desc.bAlternateSetting) < 0) { err ("set_interface failed"); return -EIO; } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 5806d3e173b3..75d55155ba15 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -244,7 +244,7 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u priv->wrsent=length; /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, + usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, length, ((serial->type->write_bulk_callback) ? @@ -422,7 +422,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb) priv->wrsent+=length; /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, + usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, length, ((serial->type->write_bulk_callback) ? diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index ac3f11202cae..f006bab74df0 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -168,7 +168,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) bytes_out = 0; /* Start reading from the device */ - FILL_BULK_URB( + usb_fill_bulk_urb( port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, @@ -265,7 +265,7 @@ static int empeg_write (struct usb_serial_port *port, int from_user, const unsig } /* build up our urb */ - FILL_BULK_URB ( + usb_fill_bulk_urb ( urb, serial->dev, usb_sndbulkpipe(serial->dev, @@ -413,7 +413,7 @@ static void empeg_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - FILL_BULK_URB( + usb_fill_bulk_urb( port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2df1a6ca0f66..fe4a96240096 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -346,7 +346,7 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp) } /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ftdi_sio_read_bulk_callback, port); @@ -449,7 +449,7 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user, usb_serial_debug_data (__FILE__, __FUNCTION__, count, first_byte); /* send the data out the bulk port */ - FILL_BULK_URB(port->write_urb, serial->dev, + usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ftdi_sio_write_bulk_callback, port); @@ -608,7 +608,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb) #endif /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ftdi_sio_read_bulk_callback, port); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 88d2eae8a915..f777c14abe34 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1479,7 +1479,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge } /* fill up the urb with all of our data and submit it */ - FILL_BULK_URB (urb, edge_serial->serial->dev, + usb_fill_bulk_urb (urb, edge_serial->serial->dev, usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), buffer, count+2, edge_bulk_out_data_callback, edge_port); @@ -2504,7 +2504,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer CmdUrbs++; dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); - FILL_BULK_URB (urb, edge_serial->serial->dev, + usb_fill_bulk_urb (urb, edge_serial->serial->dev, usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), buffer, length, edge_bulk_out_cmd_callback, edge_port); diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index df4b5ff95a7b..4ac6d31bfd38 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -588,10 +588,10 @@ static int TIChooseConfiguration (struct usb_device *dev) // we want. However, we just support one config at this point, // configuration # 1, which is Config Descriptor 0. - dbg ("%s - Number of Interfaces = %d", __FUNCTION__, dev->config->bNumInterfaces); - dbg ("%s - MAX Power = %d", __FUNCTION__, dev->config->MaxPower*2); + dbg ("%s - Number of Interfaces = %d", __FUNCTION__, dev->config->desc.bNumInterfaces); + dbg ("%s - MAX Power = %d", __FUNCTION__, dev->config->desc.bMaxPower*2); - if (dev->config->bNumInterfaces != 1) { + if (dev->config->desc.bNumInterfaces != 1) { err ("%s - bNumInterfaces is not 1, ERROR!", __FUNCTION__); return -ENODEV; } @@ -980,7 +980,7 @@ static int TIDownloadFirmware (struct edgeport_serial *serial) if (status) return status; - interface = serial->serial->dev->config->interface->altsetting; + interface = &serial->serial->dev->config->interface->altsetting->desc; if (!interface) { err ("%s - no interface set, error!", __FUNCTION__); return -ENODEV; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index cc0beb63d50c..c4a145cb5aa2 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -200,7 +200,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE; /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ipaq_read_bulk_callback, port); @@ -308,7 +308,7 @@ static void ipaq_read_bulk_callback(struct urb *urb) } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ipaq_read_bulk_callback, port); @@ -429,7 +429,7 @@ static void ipaq_write_gather(struct usb_serial_port *port) } count = URBDATA_SIZE - room; - FILL_BULK_URB(port->write_urb, serial->dev, + usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback, port); diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 307b62a32652..e11b418d6474 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -395,7 +395,7 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned ir_write_bulk_callback, port); - port->write_urb->transfer_flags = USB_ZERO_PACKET; + port->write_urb->transfer_flags = URB_ZERO_PACKET; result = usb_submit_urb (port->write_urb, GFP_ATOMIC); if (result) @@ -597,7 +597,7 @@ static void ir_set_termios (struct usb_serial_port *port, struct termios *old_te ir_write_bulk_callback, port); - port->write_urb->transfer_flags = USB_ZERO_PACKET; + port->write_urb->transfer_flags = URB_ZERO_PACKET; result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7d2794872c6e..5afe854714ec 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -344,11 +344,11 @@ static int keyspan_write(struct usb_serial_port *port, int from_user, dbg("%s - endpoint %d flip %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), flip); if (this_urb->status == -EINPROGRESS) { - if (this_urb->transfer_flags & USB_ASYNC_UNLINK) + if (this_urb->transfer_flags & URB_ASYNC_UNLINK) break; if (jiffies - p_priv->tx_start_time[flip] < 10 * HZ) break; - this_urb->transfer_flags |= USB_ASYNC_UNLINK; + this_urb->transfer_flags |= URB_ASYNC_UNLINK; usb_unlink_urb(this_urb); break; } @@ -368,7 +368,7 @@ static int keyspan_write(struct usb_serial_port *port, int from_user, /* send the data out the bulk port */ this_urb->transfer_buffer_length = todo + 1; - this_urb->transfer_flags &= ~USB_ASYNC_UNLINK; + this_urb->transfer_flags &= ~URB_ASYNC_UNLINK; this_urb->dev = port->serial->dev; if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { dbg("usb_submit_urb(write bulk) failed (%d)", err); @@ -912,7 +912,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) static inline void stop_urb(struct urb *urb) { if (urb && urb->status == -EINPROGRESS) { - urb->transfer_flags &= ~USB_ASYNC_UNLINK; + urb->transfer_flags &= ~URB_ASYNC_UNLINK; usb_unlink_urb(urb); } } @@ -1085,7 +1085,7 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, } /* Fill URB using supplied data. */ - FILL_BULK_URB(urb, serial->dev, + usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, endpoint) | dir, buf, len, callback, ctx); diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 47312691cc43..f97774827372 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -390,7 +390,7 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) /* READ_ON and urb submission */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, @@ -534,7 +534,7 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user, ((__u8 *)urb->transfer_buffer)[1] = (__u8) ((size & 0xFF00)>>8); /* set up our urb */ - FILL_BULK_URB(urb, serial->dev, + usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), urb->transfer_buffer, @@ -697,7 +697,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb) priv->bytes_in += bytes_sent; } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 0cdb7e44933c..5b7a48de3b2c 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -450,7 +450,7 @@ static int mct_u232_write (struct usb_serial_port *port, int from_user, } /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, + usb_fill_bulk_urb(port->write_urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, size, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index b4d5fa960435..541bcdbe8f61 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -172,7 +172,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) wport->tty = port->tty; /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, omninet_read_bulk_callback, port); @@ -255,7 +255,7 @@ static void omninet_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - FILL_BULK_URB(urb, serial->dev, + usb_fill_bulk_urb(urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), urb->transfer_buffer, urb->transfer_buffer_length, omninet_read_bulk_callback, port); diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 1f64274873de..31301e598125 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -270,7 +270,7 @@ static void safe_read_bulk_callback (struct urb *urb) } /* Continue trying to always read */ - FILL_BULK_URB (urb, serial->dev, + usb_fill_bulk_urb (urb, serial->dev, usb_rcvbulkpipe (serial->dev, port->bulk_in_endpointAddress), urb->transfer_buffer, urb->transfer_buffer_length, safe_read_bulk_callback, port); @@ -393,7 +393,7 @@ static int safe_write_room (struct usb_serial_port *port) static int safe_startup (struct usb_serial *serial) { - switch (serial->interface->altsetting->bInterfaceProtocol) { + switch (serial->interface->altsetting->desc.bInterfaceProtocol) { case LINEO_SAFESERIAL_CRC: break; case LINEO_SAFESERIAL_CRC_PADDED: diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4cb3cb879e1b..75510b41e8ab 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1147,7 +1147,7 @@ int usb_serial_probe(struct usb_interface *interface, struct usb_device *dev = interface_to_usbdev (interface); struct usb_serial *serial = NULL; struct usb_serial_port *port; - struct usb_interface_descriptor *iface_desc; + struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS]; struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; @@ -1208,8 +1208,8 @@ int usb_serial_probe(struct usb_interface *interface, /* descriptor matches, let's find the endpoints needed */ /* check out the endpoints */ iface_desc = &interface->altsetting[0]; - for (i = 0; i < iface_desc->bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i]; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) { @@ -1249,8 +1249,8 @@ int usb_serial_probe(struct usb_interface *interface, //interface = &dev->actconfig->interface[ifnum ^ 1]; interface = &dev->actconfig->interface[0]; iface_desc = &interface->altsetting[0]; - for (i = 0; i < iface_desc->bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i]; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x03)) { /* we found a interrupt in endpoint */ diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 928b739597b4..1db93f62063c 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -249,7 +249,7 @@ static int bus_reset( Scsi_Cmnd *srb ) /* FIXME: This needs to lock out driver probing while it's working * or we can have race conditions */ /* This functionality really should be provided by the khubd thread */ - for (i = 0; i < pusb_dev_save->actconfig->bNumInterfaces; i++) { + for (i = 0; i < pusb_dev_save->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = &pusb_dev_save->actconfig->interface[i]; diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 6820bdc91e1b..b216f61e7919 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -381,7 +381,7 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) * before the submission or before setting the CAN_CANCEL bit. If so, it's * essential to abort the URB if it hasn't been cancelled already (i.e., * if the CAN_CANCEL bit is still set). Either way, the function must then - * wait for the URB to finish. Note that because the USB_ASYNC_UNLINK flag + * wait for the URB to finish. Note that because the URB_ASYNC_UNLINK flag * is set, the URB can still be in progress even after a call to * usb_unlink_urb() returns. * @@ -426,7 +426,7 @@ static int usb_stor_msg_common(struct us_data *us) us->current_urb->context = &urb_done; us->current_urb->actual_length = 0; us->current_urb->error_count = 0; - us->current_urb->transfer_flags = USB_ASYNC_UNLINK; + us->current_urb->transfer_flags = URB_ASYNC_UNLINK; /* submit the URB */ status = usb_submit_urb(us->current_urb, GFP_NOIO); @@ -474,7 +474,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, us->dr->wLength = cpu_to_le16(size); /* fill and submit the URB */ - FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe, + usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe, (unsigned char*) us->dr, data, size, usb_stor_blocking_completion, NULL); status = usb_stor_msg_common(us); @@ -494,7 +494,7 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, unsigned int pipe, int status; /* fill and submit the URB */ - FILL_BULK_URB(us->current_urb, us->pusb_dev, pipe, data, len, + usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, data, len, usb_stor_blocking_completion, NULL); status = usb_stor_msg_common(us); diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index a463fe4544aa..445cb612db2a 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -577,7 +577,7 @@ static int usb_stor_allocate_urbs(struct us_data *ss) maxp = sizeof(ss->irqbuf); /* fill in the URB with our data */ - FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, + usb_fill_int_urb(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, maxp, usb_stor_CBI_irq, ss, ss->ep_int->bInterval); /* submit the URB for processing */ @@ -646,7 +646,7 @@ static int storage_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->bInterfaceNumber; + int ifnum = intf->altsetting->desc.bInterfaceNumber; int i; const int id_index = id - storage_usb_ids; char mf[USB_STOR_STRING_LEN]; /* manufacturer */ @@ -671,7 +671,7 @@ static int storage_probe(struct usb_interface *intf, /* the altsetting on the interface we're probing that matched our * usb_match_id table */ - struct usb_interface_descriptor *altsetting = + struct usb_host_interface *altsetting = intf[ifnum].altsetting + intf[ifnum].act_altsetting; US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting); @@ -716,22 +716,25 @@ static int storage_probe(struct usb_interface *intf, * An optional interrupt is OK (necessary for CBI protocol). * We will ignore any others. */ - for (i = 0; i < altsetting->bNumEndpoints; i++) { + for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { + struct usb_endpoint_descriptor *ep; + + ep = &altsetting->endpoint[i].desc; + /* is it an BULK endpoint? */ - if ((altsetting->endpoint[i].bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { + if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) { /* BULK in or out? */ - if (altsetting->endpoint[i].bEndpointAddress & - USB_DIR_IN) - ep_in = &altsetting->endpoint[i]; + if (ep->bEndpointAddress & USB_DIR_IN) + ep_in = ep; else - ep_out = &altsetting->endpoint[i]; + ep_out = ep; } /* is it an interrupt endpoint? */ - if ((altsetting->endpoint[i].bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { - ep_int = &altsetting->endpoint[i]; + else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { + ep_int = ep; } } US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n", diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index bae45783a718..97aa1a3556db 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -428,7 +428,7 @@ static ssize_t skel_write (struct file *file, const char *buffer, size_t count, dev->write_urb->transfer_buffer); /* set up our urb */ - FILL_BULK_URB(dev->write_urb, dev->udev, + usb_fill_bulk_urb(dev->write_urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), dev->write_urb->transfer_buffer, bytes_written, skel_write_bulk_callback, dev); @@ -555,7 +555,7 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i /* check out the endpoints */ iface_desc = &interface->altsetting[0]; for (i = 0; i < iface_desc->bNumEndpoints; ++i) { - endpoint = &iface_desc->endpoint[i]; + endpoint = &iface_desc->endpoint[i].desc; if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) { @@ -587,7 +587,7 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i err("Couldn't allocate bulk_out_buffer"); goto error; } - FILL_BULK_URB(dev->write_urb, udev, + usb_fill_bulk_urb(dev->write_urb, udev, usb_sndbulkpipe(udev, endpoint->bEndpointAddress), dev->bulk_out_buffer, buffer_size, diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 7f50af855687..020bd1596ab9 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -85,7 +85,6 @@ extern struct resource iomem_resource; extern int get_resource_list(struct resource *, char *buf, int size); -extern int check_resource(struct resource *root, unsigned long, unsigned long); extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); extern int allocate_resource(struct resource *root, struct resource *new, diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 0d0ce25b333e..2f429e27a007 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -1,10 +1,9 @@ -/* $Id: isdn.h,v 1.111.6.9 2001/09/23 22:25:05 kai Exp $ - * - * Main header for the Linux ISDN subsystem (linklevel). +/* Linux ISDN subsystem, main header * * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * Copyright 2000-2002 by Kai Germaschewski (kai@germaschewski.name) * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -15,9 +14,7 @@ #define __ISDN_H__ #include <linux/ioctl.h> - -// FIXME!!! -#include <../drivers/isdn/i4l/isdn_fsm.h> +#include <linux/isdn/fsm.h> #ifdef CONFIG_COBALT_MICRO_SERVER /* Save memory */ @@ -238,210 +235,9 @@ typedef struct { #define USG_MODEMORVOICE(x) (((x & ISDN_USAGE_MASK)==ISDN_USAGE_MODEM) || \ ((x & ISDN_USAGE_MASK)==ISDN_USAGE_VOICE) ) -/* Timer-delays and scheduling-flags */ -#define ISDN_TIMER_RES 4 /* Main Timer-Resolution */ -#define ISDN_TIMER_02SEC (HZ/ISDN_TIMER_RES/5) /* Slow-Timer1 .2 sec */ -#define ISDN_TIMER_1SEC (HZ/ISDN_TIMER_RES) /* Slow-Timer2 1 sec */ -#define ISDN_TIMER_RINGING 5 /* tty RINGs = ISDN_TIMER_1SEC * this factor */ -#define ISDN_TIMER_KEEPINT 10 /* Cisco-Keepalive = ISDN_TIMER_1SEC * this factor */ -#define ISDN_TIMER_MODEMREAD 1 -#define ISDN_TIMER_MODEMPLUS 2 -#define ISDN_TIMER_MODEMRING 4 -#define ISDN_TIMER_MODEMXMIT 8 -#define ISDN_TIMER_CARRIER 256 /* Wait for Carrier */ -#define ISDN_TIMER_FAST (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \ - ISDN_TIMER_MODEMXMIT) -#define ISDN_TIMER_SLOW (ISDN_TIMER_MODEMRING | ISDN_TIMER_CARRIER) - /* GLOBAL_FLAGS */ #define ISDN_GLOBAL_STOPPED 1 -/*=================== Start of ip-over-ISDN stuff =========================*/ - -/* Feature- and status-flags for a net-interface */ -#define ISDN_NET_SECURE 0x02 /* Accept calls from phonelist only */ -#define ISDN_NET_CALLBACK 0x04 /* activate callback */ -#define ISDN_NET_CBHUP 0x08 /* hangup before callback */ -#define ISDN_NET_CBOUT 0x10 /* remote machine does callback */ - -#define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */ - -/* Phone-list-element */ -struct isdn_net_phone { - struct list_head list; - char num[ISDN_MSNLEN]; -}; - -/* - Principles when extending structures for generic encapsulation protocol - ("concap") support: - - Stuff which is hardware specific (here i4l-specific) goes in - the netdev -> local structure (here: isdn_net_local) - - Stuff which is encapsulation protocol specific goes in the structure - which holds the linux device structure (here: isdn_net_device) -*/ - -struct isdn_net_dev_s; -struct isdn_net_local_s; - -struct isdn_netif_ops { - int (*hard_start_xmit) (struct sk_buff *skb, - struct net_device *dev); - int (*hard_header) (struct sk_buff *skb, - struct net_device *dev, - unsigned short type, - void *daddr, - void *saddr, - unsigned len); - int (*do_ioctl)(struct net_device *dev, - struct ifreq *ifr, int cmd); - - unsigned short flags; /* interface flags (a la BSD) */ - unsigned short type; /* interface hardware type */ - unsigned char addr_len;/* hardware address length */ - void (*receive)(struct isdn_net_local_s *, - struct isdn_net_dev_s *, - struct sk_buff *); - void (*connected)(struct isdn_net_dev_s *); - void (*disconnected)(struct isdn_net_dev_s *); - int (*bind)(struct isdn_net_dev_s *); - void (*unbind)(struct isdn_net_dev_s *); - int (*init)(struct isdn_net_local_s *); - void (*cleanup)(struct isdn_net_local_s *); - int (*open)(struct isdn_net_local_s *); - void (*close)(struct isdn_net_local_s *); -}; - -/* Local interface-data */ -typedef struct isdn_net_local_s { - ulong magic; - struct net_device_stats stats; /* Ethernet Statistics */ - int flags; /* Connection-flags */ - int dialmax; /* Max. Number of Dial-retries */ - int dialtimeout; /* How long shall we try on dialing */ - int dialwait; /* wait after failed attempt */ - - int cbdelay; /* Delay before Callback starts */ - char msn[ISDN_MSNLEN]; /* MSNs/EAZs for this interface */ - - u_char cbhup; /* Flag: Reject Call before Callback*/ - int hupflags; /* Flags for charge-unit-hangup: */ - int onhtime; /* Time to keep link up */ - - u_char p_encap; /* Packet encapsulation */ - u_char l2_proto; /* Layer-2-protocol */ - u_char l3_proto; /* Layer-3-protocol */ - - ulong slavedelay; /* Dynamic bundling delaytime */ - int triggercps; /* BogoCPS needed for trigger slave */ - struct list_head phone[2]; /* List of remote-phonenumbers */ - /* phone[0] = Incoming Numbers */ - /* phone[1] = Outgoing Numbers */ - - struct list_head slaves; /* list of all bundled channels - protected by serializing config - ioctls / no change allowed when - interface is running */ - struct list_head online; /* list of all bundled channels - which can be used for actual - data (IP) transfer - protected by xmit_lock */ - - spinlock_t xmit_lock; /* used to protect the xmit path of - a net_device, including all - associated channels's frame_cnt */ - struct list_head running_devs; /* member of global running_devs */ - atomic_t refcnt; /* references held by ISDN code */ - -#ifdef CONFIG_ISDN_X25 - struct concap_device_ops *dops; /* callbacks used by encapsulator */ -#endif -#ifdef CONFIG_ISDN_PPP - unsigned int mpppcfg; - long mp_seqno; - struct ippp_ccp *ccp; - unsigned long debug; -#ifdef CONFIG_ISDN_PPP_VJ - unsigned char *cbuf; - struct slcompress *slcomp; -#endif -#endif - - /* use an own struct for that in later versions */ - ulong cisco_myseq; /* Local keepalive seq. for Cisco */ - ulong cisco_mineseen; /* returned keepalive seq. from remote */ - ulong cisco_yourseq; /* Remote keepalive seq. for Cisco */ - int cisco_keepalive_period; /* keepalive period */ - ulong cisco_last_slarp_in; /* jiffie of last keepalive packet we received */ - char cisco_line_state; /* state of line according to keepalive packets */ - char cisco_debserint; /* debugging flag of cisco hdlc with slarp */ - - struct timer_list cisco_timer; - - struct isdn_netif_ops *ops; - - struct net_device dev; /* interface to upper levels */ -} isdn_net_local; - -/* the interface itself */ -typedef struct isdn_net_dev_s { - int isdn_slot; /* Index to isdn device/channel */ - int pre_device; /* Preselected isdn-device */ - int pre_channel; /* Preselected isdn-channel */ - int exclusive; /* -1 if non excl./idx to excl chan */ - - struct timer_list dial_timer; /* dial events timer */ - struct fsm_inst fi; /* call control state machine */ - int dial_event; /* event in case of timer expiry */ - int dial; /* # of phone number just dialed */ - int outgoing; /* Flag: outgoing call */ - int dialretry; /* Counter for Dialout-retries */ - - int cps; /* current speed of this interface */ - int transcount; /* byte-counter for cps-calculation */ - int last_jiffies; /* when transcount was reset */ - int sqfull; /* Flag: netdev-queue overloaded */ - ulong sqfull_stamp; /* Start-Time of overload */ - - int huptimer; /* Timeout-counter for auto-hangup */ - int charge; /* Counter for charging units */ - int charge_state; /* ChargeInfo state machine */ - unsigned long chargetime; /* Timer for Charging info */ - int chargeint; /* Interval between charge-infos */ - - int pppbind; /* ippp device for bindings */ - struct ipppd *ipppd; /* /dev/ipppX which controls us */ - - struct sk_buff_head super_tx_queue; /* List of supervisory frames to */ - /* be transmitted asap */ - int frame_cnt; /* number of frames currently */ - /* queued in HL driver */ - struct tasklet_struct tlet; - - isdn_net_local *mlp; /* Ptr to master device for all devs*/ - - struct list_head slaves; /* member of local->slaves */ - struct list_head online; /* member of local->online */ - - char name[10]; /* Name of device */ - struct list_head global_list; /* global list of all isdn_net_devs */ -#ifdef CONFIG_ISDN_PPP - unsigned int pppcfg; - unsigned int pppseq; /* last seq no seen */ - struct ippp_ccp *ccp; - unsigned long debug; - - ippp_bundle * pb; /* pointer to the common bundle structure - * with the per-bundle data */ -#endif -#ifdef CONFIG_ISDN_X25 - struct concap_proto *cprot; /* connection oriented encapsulation protocol */ -#endif - -} isdn_net_dev; - -/*===================== End of ip-over-ISDN stuff ===========================*/ - /*======================= Start of ISDN-tty stuff ===========================*/ #define ISDN_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */ @@ -494,7 +290,6 @@ typedef struct atemu { int mdmcmdl; /* Length of Modem-Commandbuffer */ int pluscount; /* Counter for +++ sequence */ int lastplus; /* Timestamp of last + */ - int carrierwait; /* Seconds of carrier waiting */ char mdmcmd[255]; /* Modem-Commandbuffer */ unsigned int charge; /* Charge units of current connection */ } atemu; @@ -516,7 +311,9 @@ typedef struct modem_info { /* 2 = B-Channel is up, deliver d.*/ int dialing; /* Dial in progress or ATA */ int rcvsched; /* Receive needs schedule */ - int isdn_slot; /* Index to isdn-driver/channel */ + struct isdn_slot *isdn_slot; /* Ptr to isdn-driver/channel */ + struct sk_buff_head rpqueue; /* Queue of recv'd packets */ + int rcvcount; /* Byte-counters for B rx */ int ncarrier; /* Flag: schedule NO CARRIER */ unsigned char last_cause[8]; /* Last cause message */ unsigned char last_num[ISDN_MSNLEN]; @@ -533,6 +330,7 @@ typedef struct modem_info { struct sk_buff_head xmit_queue; /* transmit queue */ atomic_t xmit_lock; /* Semaphore for isdn_tty_write */ #ifdef CONFIG_ISDN_AUDIO + unsigned long DLEflag; /* Insert DLE at next read */ int vonline; /* Voice-channel status */ /* Bit 0 = recording */ /* Bit 1 = playback */ @@ -549,6 +347,10 @@ typedef struct modem_info { #endif struct tty_struct *tty; /* Pointer to corresponding tty */ atemu emu; /* AT-emulator data */ + struct timer_list escape_timer; /* to recognize +++ escape */ + struct timer_list ring_timer; /* for writing 'RING' responses */ + struct timer_list connect_timer; /* waiting for CONNECT */ + struct timer_list read_timer; /* read incoming data */ struct termios normal_termios; /* For saving termios structs */ struct termios callout_termios; wait_queue_head_t open_wait, close_wait; @@ -557,17 +359,6 @@ typedef struct modem_info { #define ISDN_MODEM_WINSIZE 8 -/* Description of one ISDN-tty */ -typedef struct { - int refcount; /* Number of opens */ - struct tty_driver tty_modem; /* tty-device */ - struct tty_driver cua_modem; /* cua-device */ - struct tty_struct *modem_table[ISDN_MAX_CHANNELS]; /* ?? copied from Orig */ - struct termios *modem_termios[ISDN_MAX_CHANNELS]; - struct termios *modem_termios_locked[ISDN_MAX_CHANNELS]; - modem_info info[ISDN_MAX_CHANNELS]; /* Private data */ -} modem; - /*======================= End of ISDN-tty stuff ============================*/ /*======================== Start of V.110 stuff ============================*/ @@ -602,37 +393,10 @@ typedef struct { char *private; } 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 */ - wait_queue_head_t *rcv_waitq; /* Wait-Queues for B-Channel-Reads */ - wait_queue_head_t *snd_waitq; /* Wait-Queue for B-Channel-Send's */ - char msn2eaz[10][ISDN_MSNLEN]; /* Mapping-Table MSN->EAZ */ -} driver; - /* Main driver-data */ typedef struct isdn_devt { unsigned short flags; /* Bitmapped Flags: */ /* */ - int drivers; /* Current number of drivers */ int channels; /* Current number of channels */ int net_verbose; /* Verbose-Flag */ int modempoll; /* Flag: tty-read active */ @@ -641,11 +405,7 @@ typedef struct isdn_devt { int global_flags; infostruct *infochain; /* List of open info-devs. */ wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */ - struct timer_list timer; /* Misc.-function Timer */ - driver *drv[ISDN_MAX_DRIVERS]; /* Array of drivers */ - char drvid[ISDN_MAX_DRIVERS][20];/* Driver-ID */ struct task_struct *profd; /* For iprofd */ - modem mdm; /* tty-driver-data */ struct semaphore sem; /* serialize list access*/ unsigned long global_features; #ifdef CONFIG_DEVFS_FS diff --git a/drivers/isdn/i4l/isdn_fsm.h b/include/linux/isdn/fsm.h index 4a48a401da45..95beb142b392 100644 --- a/drivers/isdn/i4l/isdn_fsm.h +++ b/include/linux/isdn/fsm.h @@ -1,14 +1,11 @@ -/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $ - * - * Finite state machine +/* Linux ISDN subsystem, finite state machine * * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * by Kai Germaschewski <kai.germaschewski@gmx.de> + * Copyright by Karsten Keil <keil@isdn4linux.de> + * 2001-2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. - * */ #ifndef __ISDN_FSM_H__ diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h index ec6016c37421..669822e2868a 100644 --- a/include/linux/isdn_ppp.h +++ b/include/linux/isdn_ppp.h @@ -1,10 +1,15 @@ -/* +/* Linux ISDN subsystem, sync PPP, interface to ipppd + * + * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) + * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg + * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) + * Copyright 2000-2002 by Kai Germaschewski (kai@germaschewski.name) + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ - #ifndef _LINUX_ISDN_PPP_H #define _LINUX_ISDN_PPP_H @@ -16,22 +21,21 @@ struct pppcallinfo { - int calltype; - unsigned char local_num[64]; - unsigned char remote_num[64]; - int charge_units; + int calltype; + unsigned char local_num[64]; + unsigned char remote_num[64]; + int charge_units; }; -#define PPPIOCGCALLINFO _IOWR('t',128,struct pppcallinfo) -#define PPPIOCBUNDLE _IOW('t',129,int) -#define PPPIOCGMPFLAGS _IOR('t',130,int) -#define PPPIOCSMPFLAGS _IOW('t',131,int) -#define PPPIOCSMPMTU _IOW('t',132,int) -#define PPPIOCSMPMRU _IOW('t',133,int) -#define PPPIOCGCOMPRESSORS _IOR('t',134,unsigned long [8]) -#define PPPIOCSCOMPRESSOR _IOW('t',135,int) -#define PPPIOCGIFNAME _IOR('t',136, char [IFNAMSIZ] ) - +#define PPPIOCGCALLINFO _IOWR('t',128,struct pppcallinfo) +#define PPPIOCBUNDLE _IOW('t',129,int) +#define PPPIOCGMPFLAGS _IOR('t',130,int) +#define PPPIOCSMPFLAGS _IOW('t',131,int) +#define PPPIOCSMPMTU _IOW('t',132,int) +#define PPPIOCSMPMRU _IOW('t',133,int) +#define PPPIOCGCOMPRESSORS _IOR('t',134,unsigned long[8]) +#define PPPIOCSCOMPRESSOR _IOW('t',135,int) +#define PPPIOCGIFNAME _IOR('t',136,char[IFNAMSIZ]) #define SC_MP_PROT 0x00000200 #define SC_REJ_MP_PROT 0x00000400 @@ -44,26 +48,19 @@ struct pppcallinfo #define IPPP_COMP_FLAG_LINK 0x2 struct isdn_ppp_comp_data { - int num; - unsigned char options[ISDN_PPP_COMP_MAX_OPTIONS]; - int optlen; - int flags; + int num; + unsigned char options[ISDN_PPP_COMP_MAX_OPTIONS]; + int optlen; + int flags; }; #ifdef __KERNEL__ - -#include <linux/config.h> #include <linux/skbuff.h> #include <linux/ppp_defs.h> #define DECOMP_ERR_NOMEM (-10) -#define MP_END_FRAG 0x40 -#define MP_BEGIN_FRAG 0x80 - -#define MP_MAX_QUEUE_LEN 16 - /* * We need a way for the decompressor to influence the generation of CCP * Reset-Requests in a variety of ways. The decompressor is already returning @@ -82,15 +79,15 @@ struct isdn_ppp_comp_data { #define IPPP_RESET_MAXDATABYTES 32 struct isdn_ppp_resetparams { - unsigned char valid:1; /* rw Is this structure filled at all ? */ - unsigned char rsend:1; /* rw Should we send one at all ? */ - unsigned char idval:1; /* rw Is the id field valid ? */ - unsigned char dtval:1; /* rw Is the data field valid ? */ - unsigned char expra:1; /* rw Is an Ack expected for this Req ? */ - unsigned char id; /* wo Send CCP ResetReq with this id */ - unsigned short maxdlen; /* ro Max bytes to be stored in data field */ - unsigned short dlen; /* rw Bytes stored in data field */ - unsigned char *data; /* wo Data for ResetReq info field */ + unsigned char valid:1; /* rw Is this structure filled at all ? */ + unsigned char rsend:1; /* rw Should we send one at all ? */ + unsigned char idval:1; /* rw Is the id field valid ? */ + unsigned char dtval:1; /* rw Is the data field valid ? */ + unsigned char expra:1; /* rw Is an Ack expected for this Req ? */ + unsigned char id; /* wo Send CCP ResetReq with this id */ + unsigned short maxdlen; /* ro Max bytes to be stored in data field */ + unsigned short dlen; /* rw Bytes stored in data field */ + unsigned char *data; /* wo Data for ResetReq info field */ }; /* @@ -98,89 +95,37 @@ struct isdn_ppp_resetparams { * check the original include for more information */ struct isdn_ppp_compressor { - struct isdn_ppp_compressor *next, *prev; - int num; /* CCP compression protocol number */ + struct isdn_ppp_compressor *next, *prev; + int num; /* CCP compression protocol number */ - void *(*alloc) (struct isdn_ppp_comp_data *); - void (*free) (void *state); - int (*init) (void *state, struct isdn_ppp_comp_data *, - int unit,int debug); + void *(*alloc) (struct isdn_ppp_comp_data *); + void (*free) (void *state); + int (*init) (void *state, struct isdn_ppp_comp_data *, + int unit,int debug); - /* The reset entry needs to get more exact information about the - ResetReq or ResetAck it was called with. The parameters are - obvious. If reset is called without a Req or Ack frame which - could be handed into it, code MUST be set to 0. Using rsparm, - the reset entry can control if and how a ResetAck is returned. */ + /* The reset entry needs to get more exact information about the + ResetReq or ResetAck it was called with. The parameters are + obvious. If reset is called without a Req or Ack frame which + could be handed into it, code MUST be set to 0. Using rsparm, + the reset entry can control if and how a ResetAck is returned. */ - void (*reset) (void *state, unsigned char code, unsigned char id, - unsigned char *data, unsigned len, - struct isdn_ppp_resetparams *rsparm); + void (*reset) (void *state, unsigned char code, unsigned char id, + unsigned char *data, unsigned len, + struct isdn_ppp_resetparams *rsparm); - int (*compress) (void *state, struct sk_buff *in, - struct sk_buff *skb_out, int proto); + int (*compress) (void *state, struct sk_buff *in, + struct sk_buff *skb_out, int proto); int (*decompress) (void *state,struct sk_buff *in, struct sk_buff *skb_out, struct isdn_ppp_resetparams *rsparm); - void (*incomp) (void *state, struct sk_buff *in,int proto); - void (*stat) (void *state, struct compstat *stats); + void (*incomp) (void *state, struct sk_buff *in,int proto); + void (*stat) (void *state, struct compstat *stats); }; extern int isdn_ppp_register_compressor(struct isdn_ppp_compressor *); extern int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *); -typedef struct { - unsigned long seqerrs; - unsigned long frame_drops; - unsigned long overflows; - unsigned long max_queue_len; -} isdn_mppp_stats; - -typedef struct { - int mp_mrru; /* unused */ - struct sk_buff * frags; /* fragments sl list -- use skb->next */ - long frames; /* number of frames in the frame list */ - unsigned int seq; /* last processed packet seq #: any packets - * with smaller seq # will be dropped - * unconditionally */ - spinlock_t lock; - int ref_ct; - /* statistics */ - isdn_mppp_stats stats; -} ippp_bundle; - -#define IPPP_MAX_RQ_LEN 8 - -/* The data structure for one CCP reset transaction */ -enum ippp_ccp_reset_states { - CCPResetIdle, - CCPResetSentReq, - CCPResetRcvdReq, - CCPResetSentAck, - CCPResetRcvdAck -}; - -struct ippp_ccp_reset_state { - enum ippp_ccp_reset_states state; /* State of this transaction */ - struct ippp_ccp *ccp; /* Backlink */ - unsigned char id; /* id index */ - unsigned char ta:1; /* The timer is active (flag) */ - unsigned char expra:1; /* We expect a ResetAck at all */ - int dlen; /* Databytes stored in data */ - struct timer_list timer; /* For timeouts/retries */ - /* This is a hack but seems sufficient for the moment. We do not want - to have this be yet another allocation for some bytes, it is more - memory management overhead than the whole mess is worth. */ - unsigned char data[IPPP_RESET_MAXDATABYTES]; -}; - -/* The data structure keeping track of the currently outstanding CCP Reset - transactions. */ -struct ippp_ccp_reset { - struct ippp_ccp_reset_state *rs[256]; /* One per possible id */ - unsigned char lastid; /* Last id allocated by the engine */ -}; - #endif /* __KERNEL__ */ #endif /* _LINUX_ISDN_PPP_H */ diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h index c9718d4de584..342dd971b1b6 100644 --- a/include/linux/isdnif.h +++ b/include/linux/isdnif.h @@ -202,14 +202,12 @@ typedef struct #define ISDN_STAT_LOAD 265 /* Signal new lowlevel-driver is loaded */ #define ISDN_STAT_UNLOAD 266 /* Signal unload of lowlevel-driver */ #define ISDN_STAT_BSENT 267 /* Signal packet sent */ -#define ISDN_STAT_NODCH 268 /* Signal no D-Channel */ #define ISDN_STAT_ADDCH 269 /* Add more Channels */ #define ISDN_STAT_CAUSE 270 /* Cause-Message */ #define ISDN_STAT_ICALLW 271 /* Incoming call without B-chan waiting */ #define ISDN_STAT_REDIR 272 /* Redir result */ #define ISDN_STAT_PROT 273 /* protocol IO specific callback */ #define ISDN_STAT_DISPLAY 274 /* deliver a received display message */ -#define ISDN_STAT_L1ERR 275 /* Signal Layer-1 Error */ #define ISDN_STAT_FAXIND 276 /* FAX indications from HL-driver */ #define ISDN_STAT_AUDIO 277 /* DTMF, DSP indications */ #define ISDN_STAT_DISCH 278 /* Disable/Enable channel usage */ @@ -221,12 +219,6 @@ typedef struct #define ISDN_AUDIO_DTMF 1 /* Rx/Tx DTMF */ /* - * Values for errcode field - */ -#define ISDN_STAT_L1ERR_SEND 1 -#define ISDN_STAT_L1ERR_RECV 2 - -/* * Values for feature-field of interface-struct. */ /* Layer 2 */ diff --git a/include/linux/usb.h b/include/linux/usb.h index 0397f55aabdc..0f486d95bdb7 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -41,56 +41,36 @@ struct usb_device; /*-------------------------------------------------------------------------*/ /* - * Standard USB Descriptor support. + * Host-side wrappers for standard USB descriptors ... these are parsed + * from the data provided by devices. Parsing turns them from a flat + * sequence of descriptors into a hierarchy: + * + * - devices have one (usually) or more configs; + * - configs have one (often) or more interfaces; + * - interfaces have one (usually) or more settings; + * - each interface setting has zero or (usually) more endpoints. + * + * And there might be other descriptors mixed in with those. + * * Devices may also have class-specific or vendor-specific descriptors. */ -/* - * Descriptor sizes per descriptor type - */ -#define USB_DT_DEVICE_SIZE 18 -#define USB_DT_CONFIG_SIZE 9 -#define USB_DT_INTERFACE_SIZE 9 -#define USB_DT_ENDPOINT_SIZE 7 -#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ - -/* most of these maximums are arbitrary */ -#define USB_MAXCONFIG 8 -#define USB_ALTSETTINGALLOC 4 -#define USB_MAXALTSETTING 128 /* Hard limit */ -#define USB_MAXINTERFACES 32 -#define USB_MAXENDPOINTS 32 /* Hard limit */ - -/* USB_DT_ENDPOINT: Endpoint descriptor */ -struct usb_endpoint_descriptor { - __u8 bLength __attribute__ ((packed)); - __u8 bDescriptorType __attribute__ ((packed)); - __u8 bEndpointAddress __attribute__ ((packed)); - __u8 bmAttributes __attribute__ ((packed)); - __u16 wMaxPacketSize __attribute__ ((packed)); - __u8 bInterval __attribute__ ((packed)); - __u8 bRefresh __attribute__ ((packed)); - __u8 bSynchAddress __attribute__ ((packed)); - - /* the rest is internal to the Linux implementation */ +/* host-side wrapper for parsed endpoint descriptors */ +struct usb_host_endpoint { + struct usb_endpoint_descriptor desc; + unsigned char *extra; /* Extra descriptors */ int extralen; }; -/* USB_DT_INTERFACE: Interface descriptor */ -struct usb_interface_descriptor { - __u8 bLength __attribute__ ((packed)); - __u8 bDescriptorType __attribute__ ((packed)); - __u8 bInterfaceNumber __attribute__ ((packed)); - __u8 bAlternateSetting __attribute__ ((packed)); - __u8 bNumEndpoints __attribute__ ((packed)); - __u8 bInterfaceClass __attribute__ ((packed)); - __u8 bInterfaceSubClass __attribute__ ((packed)); - __u8 bInterfaceProtocol __attribute__ ((packed)); - __u8 iInterface __attribute__ ((packed)); - - /* the rest is internal to the Linux implementation */ - struct usb_endpoint_descriptor *endpoint; +/* host-side wrapper for one interface setting's parsed descriptors */ +struct usb_host_interface { + struct usb_interface_descriptor desc; + + /* array of desc.bNumEndpoint endpoints associated with this + * interface setting. these will be in no particular order. + */ + struct usb_host_endpoint *endpoint; unsigned char *extra; /* Extra descriptors */ int extralen; @@ -127,7 +107,10 @@ struct usb_interface_descriptor { * will use them in non-default settings. */ struct usb_interface { - struct usb_interface_descriptor *altsetting; + /* array of alternate settings for this interface. + * these will be in numeric order, 0..num_altsettting + */ + struct usb_host_interface *altsetting; unsigned act_altsetting; /* active alternate setting */ unsigned num_altsetting; /* number of alternate settings */ @@ -148,17 +131,12 @@ struct usb_interface { * different depending on what speed they're currently running. Only * devices with a USB_DT_DEVICE_QUALIFIER have an OTHER_SPEED_CONFIG. */ -struct usb_config_descriptor { - __u8 bLength __attribute__ ((packed)); - __u8 bDescriptorType __attribute__ ((packed)); - __u16 wTotalLength __attribute__ ((packed)); - __u8 bNumInterfaces __attribute__ ((packed)); - __u8 bConfigurationValue __attribute__ ((packed)); - __u8 iConfiguration __attribute__ ((packed)); - __u8 bmAttributes __attribute__ ((packed)); - __u8 MaxPower __attribute__ ((packed)); - - /* the rest is internal to the Linux implementation */ +struct usb_host_config { + struct usb_config_descriptor desc; + + /* the interfaces associated with this configuration + * these will be in numeric order, 0..desc.bNumInterfaces + */ struct usb_interface *interface; unsigned char *extra; /* Extra descriptors */ @@ -178,8 +156,6 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, /* -------------------------------------------------------------------------- */ -/* Host Controller Driver (HCD) support */ - struct usb_operations; /* @@ -248,8 +224,8 @@ struct usb_device { struct device dev; /* Generic device interface */ struct usb_device_descriptor descriptor;/* Descriptor */ - struct usb_config_descriptor *config; /* All of the configs */ - struct usb_config_descriptor *actconfig;/* the active configuration */ + struct usb_host_config *config; /* All of the configs */ + struct usb_host_config *actconfig;/* the active configuration */ char **rawdescriptors; /* Raw descriptors for each config */ @@ -560,17 +536,15 @@ extern int usb_disabled(void); /* * urb->transfer_flags: - * - * FIXME should _all_ be URB_* flags */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ -#define USB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ +#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ #define URB_NO_DMA_MAP 0x0004 /* urb->*_dma are valid on submit */ -#define USB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */ -#define USB_NO_FSBR 0x0020 /* UHCI-specific */ -#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ +#define URB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */ +#define URB_NO_FSBR 0x0020 /* UHCI-specific */ +#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ -#define USB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */ +#define URB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */ struct usb_iso_packet_descriptor { unsigned int offset; @@ -674,7 +648,7 @@ typedef void (*usb_complete_t)(struct urb *); * * All URBs submitted must initialize dev, pipe, * transfer_flags (may be zero), complete, timeout (may be zero). - * The USB_ASYNC_UNLINK transfer flag affects later invocations of + * The URB_ASYNC_UNLINK transfer flag affects later invocations of * the usb_unlink_urb() routine. * * All URBs must also initialize @@ -683,7 +657,7 @@ typedef void (*usb_complete_t)(struct urb *); * to be treated as errors; that flag is invalid for write requests. * * Bulk URBs may - * use the USB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers + * use the URB_ZERO_PACKET transfer flag, indicating that bulk OUT transfers * should always terminate with a short packet, even if it means adding an * extra zero length packet. * @@ -700,7 +674,7 @@ typedef void (*usb_complete_t)(struct urb *); * endpoints, as well as high speed interrupt endpoints, the encoding of * the transfer interval in the endpoint descriptor is logarithmic.) * - * Isochronous URBs normally use the USB_ISO_ASAP transfer flag, telling + * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling * the host controller to schedule the transfer as soon as bandwidth * utilization allows, and then set start_frame to reflect the actual frame * selected during submission. Otherwise drivers must specify the start_frame @@ -872,17 +846,6 @@ static inline void usb_fill_int_urb (struct urb *urb, urb->start_frame = -1; } -/* - * old style macros to enable 2.4 and 2.2 drivers to build - * properly. Please do not use these for new USB drivers. - */ -#define FILL_CONTROL_URB(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ - usb_fill_control_urb(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) -#define FILL_BULK_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ - usb_fill_bulk_urb(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) -#define FILL_INT_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) \ - usb_fill_int_urb(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) - extern struct urb *usb_alloc_urb(int iso_packets, int mem_flags); extern void usb_free_urb(struct urb *urb); #define usb_put_urb usb_free_urb diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index 9e05b8c05004..69645ae25aae 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h @@ -6,7 +6,7 @@ * * - the master/host side Linux-USB kernel driver API; * - the "usbfs" user space API; and - * - (eventually) a Linux slave/device side driver API. + * - (eventually) a Linux "gadget" slave/device side driver API. * * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems * act either as a USB master/host or as a USB slave/device. That means @@ -101,7 +101,8 @@ struct usb_ctrlrequest { * (rarely) accepted by SET_DESCRIPTOR. * * Note that all multi-byte values here are encoded in little endian - * byte order. + * byte order "on the wire". But when exposed through Linux-USB APIs, + * they've been converted to cpu byte order. */ /* @@ -123,10 +124,13 @@ struct usb_descriptor_header { } __attribute__ ((packed)); +/*-------------------------------------------------------------------------*/ + /* USB_DT_DEVICE: Device descriptor */ struct usb_device_descriptor { __u8 bLength; __u8 bDescriptorType; + __u16 bcdUSB; __u8 bDeviceClass; __u8 bDeviceSubClass; @@ -141,10 +145,12 @@ struct usb_device_descriptor { __u8 bNumConfigurations; } __attribute__ ((packed)); +#define USB_DT_DEVICE_SIZE 18 + /* * Device and/or Interface Class codes - * as found in device and interface descriptors + * as found in bDeviceClass or bInterfaceClass * and defined by www.usb.org documents */ #define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ @@ -162,18 +168,88 @@ struct usb_device_descriptor { #define USB_CLASS_APP_SPEC 0xfe #define USB_CLASS_VENDOR_SPEC 0xff -// FIXME include struct usb_config_descriptor +/*-------------------------------------------------------------------------*/ + +/* USB_DT_CONFIG: Configuration descriptor information. + * + * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the + * descriptor type is different. Highspeed-capable devices can look + * different depending on what speed they're currently running. Only + * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG + * descriptors. + */ +struct usb_config_descriptor { + __u8 bLength; + __u8 bDescriptorType; + + __u16 wTotalLength; + __u8 bNumInterfaces; + __u8 bConfigurationValue; + __u8 iConfiguration; + __u8 bmAttributes; + __u8 bMaxPower; +} __attribute__ ((packed)); + +#define USB_DT_CONFIG_SIZE 9 + +/* from config descriptor bmAttributes */ +#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ +#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ +#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ + +/*-------------------------------------------------------------------------*/ /* USB_DT_STRING: String descriptor */ struct usb_string_descriptor { __u8 bLength; __u8 bDescriptorType; + __u16 wData[1]; /* UTF-16LE encoded */ } __attribute__ ((packed)); -// FIXME include struct usb_interface_descriptor +/* note that "string" zero is special, it holds language codes that + * the device supports, not Unicode characters. + */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_INTERFACE: Interface descriptor */ +struct usb_interface_descriptor { + __u8 bLength; + __u8 bDescriptorType; + + __u8 bInterfaceNumber; + __u8 bAlternateSetting; + __u8 bNumEndpoints; + __u8 bInterfaceClass; + __u8 bInterfaceSubClass; + __u8 bInterfaceProtocol; + __u8 iInterface; +} __attribute__ ((packed)); + +#define USB_DT_INTERFACE_SIZE 9 + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_ENDPOINT: Endpoint descriptor */ +struct usb_endpoint_descriptor { + __u8 bLength; + __u8 bDescriptorType; + + __u8 bEndpointAddress; + __u8 bmAttributes; + __u16 wMaxPacketSize; + __u8 bInterval; + + // NOTE: these two are _only_ in audio endpoints. + // use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. + __u8 bRefresh; + __u8 bSynchAddress; +} __attribute__ ((packed)); + +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ -// FIXME include struct usb_endpoint_descriptor /* * Endpoints @@ -188,10 +264,13 @@ struct usb_string_descriptor { #define USB_ENDPOINT_XFER_INT 3 +/*-------------------------------------------------------------------------*/ + /* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ struct usb_qualifier_descriptor { __u8 bLength; __u8 bDescriptorType; + __u16 bcdUSB; __u8 bDeviceClass; __u8 bDeviceSubClass; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 190fb0c1f0cb..7ecffcd552d1 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -445,7 +445,6 @@ EXPORT_SYMBOL(enable_hlt); EXPORT_SYMBOL(request_resource); EXPORT_SYMBOL(release_resource); EXPORT_SYMBOL(allocate_resource); -EXPORT_SYMBOL(check_resource); EXPORT_SYMBOL(__request_region); EXPORT_SYMBOL(__check_region); EXPORT_SYMBOL(__release_region); diff --git a/kernel/module.c b/kernel/module.c index 8c776f07e765..6b8bd749e436 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1165,7 +1165,7 @@ static void *s_start(struct seq_file *m, loff_t *pos) if (!p) return ERR_PTR(-ENOMEM); lock_kernel(); - for (v = module_list, n = *pos; v; n -= v->nsyms, v = v->next) { + for (v = module_list; v; n -= v->nsyms, v = v->next) { if (n < v->nsyms) { p->mod = v; p->index = n; diff --git a/kernel/resource.c b/kernel/resource.c index 57541cc03d09..9664ad073db7 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -131,20 +131,6 @@ int release_resource(struct resource *old) return retval; } -int check_resource(struct resource *root, unsigned long start, unsigned long len) -{ - struct resource *conflict, tmp; - - tmp.start = start; - tmp.end = start + len - 1; - write_lock(&resource_lock); - conflict = __request_resource(root, &tmp); - if (!conflict) - __release_resource(&tmp); - write_unlock(&resource_lock); - return conflict ? -EBUSY : 0; -} - /* * Find empty slot in the resource tree given range and alignment. */ diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 9cebe6d8501a..49a48317f8ea 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -201,7 +201,7 @@ static unsigned int ip_refrag(unsigned int hooknum, /* Local packets are never produced too large for their interface. We degfragment them at LOCAL_OUT, however, so we have to refragment them here. */ - if ((*pskb)->len > rt->u.dst.pmtu) { + if ((*pskb)->len > dst_pmtu(&rt->u.dst)) { /* No hook can be after us, so this should be OK. */ ip_fragment(*pskb, okfn); return NF_STOLEN; diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 8a444327ae9b..10c1690a2717 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -148,7 +148,7 @@ static void send_reset(struct sk_buff *oldskb, int local) nskb->dst = &rt->u.dst; /* "Never happens" */ - if (nskb->len > nskb->dst->pmtu) + if (nskb->len > dst_pmtu(nskb->dst)) goto free_nskb; connection_attach(nskb, oldskb->nfct); @@ -225,8 +225,8 @@ static void send_unreach(struct sk_buff *skb_in, int code) /* RFC says return as much as we can without exceeding 576 bytes. */ length = skb_in->len + sizeof(struct iphdr) + sizeof(struct icmphdr); - if (length > rt->u.dst.pmtu) - length = rt->u.dst.pmtu; + if (length > dst_pmtu(&rt->u.dst)) + length = dst_pmtu(&rt->u.dst); if (length > 576) length = 576; diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 066989423869..ae6ac63877b3 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -189,7 +189,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, } /* Try to redo what tcp_v4_send_synack did. */ - req->window_clamp = rt->u.dst.window; + req->window_clamp = dst_metric(&rt->u.dst, RTAX_WINDOW); tcp_select_initial_window(tcp_full_space(sk), req->mss, &req->rcv_wnd, &req->window_clamp, 0, &rcv_wscale); diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 0b867f319abd..93c5c240cbfc 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -82,7 +82,7 @@ MODULE_PARM_SYNTAX(pid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16"); /* #define SND_USE_ASYNC_UNLINK */ #ifdef SND_USB_ASYNC_UNLINK -#define UNLINK_FLAGS USB_ASYNC_UNLINK +#define UNLINK_FLAGS URB_ASYNC_UNLINK #else #define UNLINK_FLAGS 0 #endif @@ -867,7 +867,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run } u->urb->dev = subs->dev; u->urb->pipe = subs->datapipe; - u->urb->transfer_flags = USB_ISO_ASAP | UNLINK_FLAGS; + u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->number_of_packets = u->packets; u->urb->context = u; u->urb->complete = snd_complete_urb; @@ -889,7 +889,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *run u->urb->transfer_buffer_length = NRPACKS * 3; u->urb->dev = subs->dev; u->urb->pipe = subs->syncpipe; - u->urb->transfer_flags = USB_ISO_ASAP | UNLINK_FLAGS; + u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->number_of_packets = u->packets; u->urb->context = u; u->urb->complete = snd_complete_sync_urb; @@ -933,8 +933,8 @@ static struct audioformat *find_format(snd_usb_substream_t *subs, snd_pcm_runtim static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) { struct usb_device *dev = subs->dev; - struct usb_config_descriptor *config = dev->actconfig; - struct usb_interface_descriptor *alts; + struct usb_host_config *config = dev->actconfig; + struct usb_host_interface *alts; struct usb_interface *iface; struct audioformat *fmt; unsigned int ep, attr; @@ -951,7 +951,7 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) iface = &config->interface[fmt->iface]; alts = &iface->altsetting[fmt->altset_idx]; - snd_assert(alts->bAlternateSetting == fmt->altsetting, return -EINVAL); + snd_assert(alts->desc.bAlternateSetting == fmt->altsetting, return -EINVAL); /* close the old interface */ if (subs->interface >= 0 && subs->interface != fmt->iface) { @@ -973,31 +973,31 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) } /* create a data pipe */ - ep = alts->endpoint[0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep = alts->endpoint[0].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; if (is_playback) subs->datapipe = usb_sndisocpipe(dev, ep); else subs->datapipe = usb_rcvisocpipe(dev, ep); subs->syncpipe = subs->syncinterval = 0; - subs->maxpacksize = alts->endpoint[0].wMaxPacketSize; + subs->maxpacksize = alts->endpoint[0].desc.wMaxPacketSize; subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize); subs->fill_max = 0; /* we need a sync pipe in async OUT or adaptive IN mode */ - attr = alts->endpoint[0].bmAttributes & EP_ATTR_MASK; + attr = alts->endpoint[0].desc.bmAttributes & EP_ATTR_MASK; if ((is_playback && attr == EP_ATTR_ASYNC) || (! is_playback && attr == EP_ATTR_ADAPTIVE)) { /* check endpoint */ - if (alts->bNumEndpoints < 2 || - alts->endpoint[1].bmAttributes != 0x01 || - alts->endpoint[1].bSynchAddress != 0) { + if (alts->desc.bNumEndpoints < 2 || + alts->endpoint[1].desc.bmAttributes != 0x01 || + alts->endpoint[1].desc.bSynchAddress != 0) { snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", dev->devnum, fmt->iface, fmt->altsetting); return -EINVAL; } - ep = alts->endpoint[1].bEndpointAddress; - if ((is_playback && ep != (alts->endpoint[0].bSynchAddress | USB_DIR_IN)) || - (! is_playback && ep != (alts->endpoint[0].bSynchAddress & ~USB_DIR_IN))) { + ep = alts->endpoint[1].desc.bEndpointAddress; + if ((is_playback && ep != (alts->endpoint[0].desc.bSynchAddress | USB_DIR_IN)) || + (! is_playback && ep != (alts->endpoint[0].desc.bSynchAddress & ~USB_DIR_IN))) { snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", dev->devnum, fmt->iface, fmt->altsetting); return -EINVAL; @@ -1007,10 +1007,10 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) subs->syncpipe = usb_rcvisocpipe(dev, ep); else subs->syncpipe = usb_sndisocpipe(dev, ep); - subs->syncinterval = alts->endpoint[1].bRefresh; + subs->syncinterval = alts->endpoint[1].desc.bRefresh; } - ep = alts->endpoint[0].bEndpointAddress; + ep = alts->endpoint[0].desc.bEndpointAddress; /* if endpoint has pitch control, enable it */ if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) { data[0] = 1; @@ -1673,9 +1673,9 @@ static int parse_audio_format_type(struct usb_device *dev, int iface_no, int alt static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, int buflen, int iface_no) { struct usb_device *dev; - struct usb_config_descriptor *config; + struct usb_host_config *config; struct usb_interface *iface; - struct usb_interface_descriptor *alts; + struct usb_host_interface *alts; int i, altno, err, stream; int channels, nr_rates, pcm_format, format; struct audioformat *fp; @@ -1689,18 +1689,18 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i for (i = 0; i < iface->num_altsetting; i++) { alts = &iface->altsetting[i]; /* skip invalid one */ - if (alts->bInterfaceClass != USB_CLASS_AUDIO || - alts->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING || - alts->bNumEndpoints < 1) + if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO || + alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING || + alts->desc.bNumEndpoints < 1) continue; /* must be isochronous */ - if ((alts->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != + if ((alts->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) continue; /* check direction */ - stream = (alts->endpoint[0].bEndpointAddress & USB_DIR_IN) ? + stream = (alts->endpoint[0].desc.bEndpointAddress & USB_DIR_IN) ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; - altno = alts->bAlternateSetting; + altno = alts->desc.bAlternateSetting; /* get audio formats */ fmt = snd_usb_find_csint_desc(buffer, buflen, NULL, AS_GENERAL, iface_no, altno); @@ -1767,8 +1767,8 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i fp->altsetting = altno; fp->altset_idx = i; fp->format = pcm_format; - fp->endpoint = alts->endpoint[0].bEndpointAddress; - fp->ep_attr = alts->endpoint[0].bmAttributes; + fp->endpoint = alts->endpoint[0].desc.bEndpointAddress; + fp->ep_attr = alts->endpoint[0].desc.bmAttributes; fp->channels = channels; fp->attributes = csep[3]; @@ -1837,7 +1837,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffer, int buflen) { struct usb_device *dev = chip->dev; - struct usb_config_descriptor *config; + struct usb_host_config *config; struct usb_interface *iface; unsigned char *p1; int i, j; @@ -1858,7 +1858,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, config = dev->actconfig; for (i = 0; i < p1[7]; i++) { j = p1[8 + i]; - if (j >= config->bNumInterfaces) { + if (j >= config->desc.bNumInterfaces) { snd_printk(KERN_ERR "%d:%u:%d : does not exist\n", dev->devnum, ctrlif, j); continue; @@ -1868,8 +1868,8 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j); continue; } - if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO && - iface->altsetting[0].bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { + if (iface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO && + iface->altsetting[0].desc.bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { if (snd_usb_create_midi_interface(chip, iface, NULL) < 0) { snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j); continue; @@ -1877,8 +1877,8 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); continue; } - if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO || - iface->altsetting[0].bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { + if (iface->altsetting[0].desc.bInterfaceClass != USB_CLASS_AUDIO || + iface->altsetting[0].desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].bInterfaceClass); /* skip non-supported classes */ continue; @@ -1937,11 +1937,11 @@ static int snd_usb_roland_ua100_hack(snd_usb_audio_t *chip) .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = &ep_quirk }; - struct usb_config_descriptor *cfg = chip->dev->actconfig; + struct usb_host_config *cfg = chip->dev->actconfig; struct usb_interface *iface; int err; - if (cfg->bNumInterfaces != 3) { + if (cfg->desc.bNumInterfaces != 3) { snd_printdd(KERN_ERR "invalid UA-100 descriptor\n"); return -ENXIO; } @@ -2134,18 +2134,18 @@ static void *snd_usb_audio_probe(struct usb_device *dev, struct usb_interface *intf, const struct usb_device_id *usb_id) { - struct usb_config_descriptor *config = dev->actconfig; + struct usb_host_config *config = dev->actconfig; const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info; int i; snd_card_t *card; snd_usb_audio_t *chip; - int ifnum = intf->altsetting->bInterfaceNumber; + int ifnum = intf->altsetting->desc.bInterfaceNumber; if (quirk && quirk->ifnum != QUIRK_ANY_INTERFACE && ifnum != quirk->ifnum) goto __err_val; - if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { - snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", config->bConfigurationValue); + if (usb_set_configuration(dev, config->desc.bConfigurationValue) < 0) { + snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", config->desc.bConfigurationValue); goto __err_val; } diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index f2f6f2a75a90..f26b2069e5b2 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -184,10 +184,8 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb) return; } - if (!usb_pipeint(urb->pipe)) { - urb->dev = ep->umidi->chip->dev; - snd_usbmidi_submit_urb(urb, GFP_ATOMIC); - } + urb->dev = ep->umidi->chip->dev; + snd_usbmidi_submit_urb(urb, GFP_ATOMIC); } /* @@ -517,7 +515,7 @@ static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) static struct usb_endpoint_descriptor* snd_usbmidi_get_int_epd(snd_usb_midi_t* umidi) { struct usb_interface* intf; - struct usb_interface_descriptor* intfd; + struct usb_host_interface* intfd; if (umidi->chip->dev->descriptor.idVendor != 0x0582) return NULL; @@ -526,28 +524,28 @@ static struct usb_endpoint_descriptor* snd_usbmidi_get_int_epd(snd_usb_midi_t* u return NULL; intfd = &intf->altsetting[0]; - if (intfd->bNumEndpoints != 2 || - (intfd->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || - (intfd->endpoint[1].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) + if (intfd->desc.bNumEndpoints != 2 || + (intfd->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || + (intfd->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) return NULL; intfd = &intf->altsetting[1]; - if (intfd->bNumEndpoints != 2 || - (intfd->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || - (intfd->endpoint[1].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) + if (intfd->desc.bNumEndpoints != 2 || + (intfd->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || + (intfd->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return NULL; - usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, - intfd->bAlternateSetting); - return &intfd->endpoint[1]; + usb_set_interface(umidi->chip->dev, intfd->desc.bInterfaceNumber, + intfd->desc.bAlternateSetting); + return &intfd->endpoint[1].desc; } static struct usb_endpoint_descriptor* snd_usbmidi_get_midiman_int_epd(snd_usb_midi_t* umidi) { struct usb_interface* intf = umidi->iface; - if (!intf || intf->altsetting[0].bNumEndpoints < 1) + if (!intf || intf->altsetting[0].desc.bNumEndpoints < 1) return NULL; - return &intf->altsetting[0].endpoint[0]; + return &intf->altsetting[0].endpoint[0].desc; } /* @@ -590,10 +588,10 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, return -ENOMEM; } if (int_epd) - FILL_INT_URB(ep->urb, umidi->chip->dev, pipe, buffer, length, + usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, snd_usbmidi_in_urb_complete, ep, int_epd->bInterval); else - FILL_BULK_URB(ep->urb, umidi->chip->dev, pipe, buffer, length, + usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, snd_usbmidi_in_urb_complete, ep); rep->in = ep; @@ -657,7 +655,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, snd_usbmidi_out_endpoint_delete(ep); return -ENOMEM; } - FILL_BULK_URB(ep->urb, umidi->chip->dev, pipe, buffer, + usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, ep->max_transfer, snd_usbmidi_out_urb_complete, ep); spin_lock_init(&ep->buffer_lock); @@ -774,9 +772,9 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi, snd_usb_midi_endpoint_info_t* endpoints) { struct usb_interface* intf; - struct usb_interface_descriptor* intfd; + struct usb_host_interface* intfd; struct usb_ms_header_descriptor* ms_header; - struct usb_endpoint_descriptor* ep; + struct usb_host_endpoint* ep; struct usb_ms_endpoint_descriptor* ms_ep; int i, epidx; @@ -795,9 +793,9 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi, printk(KERN_WARNING "snd-usb-midi: MIDIStreaming interface descriptor not found\n"); epidx = 0; - for (i = 0; i < intfd->bNumEndpoints; ++i) { + for (i = 0; i < intfd->desc.bNumEndpoints; ++i) { ep = &intfd->endpoint[i]; - if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) continue; ms_ep = (struct usb_ms_endpoint_descriptor*)ep->extra; if (ep->extralen < 4 || @@ -806,22 +804,22 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi, ms_ep->bDescriptorSubtype != MS_GENERAL) continue; if (endpoints[epidx].epnum != 0 && - endpoints[epidx].epnum != (ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) { + endpoints[epidx].epnum != (ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) { ++epidx; if (epidx >= MIDI_MAX_ENDPOINTS) { printk(KERN_WARNING "snd-usb-midi: too many endpoints\n"); break; } } - endpoints[epidx].epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - if (ep->bEndpointAddress & USB_DIR_IN) { + endpoints[epidx].epnum = ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + if (ep->desc.bEndpointAddress & USB_DIR_IN) { endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; } else { endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; } printk(KERN_INFO "snd-usb-midi: detected %d %s jack(s) on endpoint %d\n", ms_ep->bNumEmbMIDIJack, - ep->bEndpointAddress & USB_DIR_IN ? "input" : "output", + ep->desc.bEndpointAddress & USB_DIR_IN ? "input" : "output", endpoints[epidx].epnum); } return 0; @@ -835,7 +833,7 @@ static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, snd_usb_midi_endpoint_info_t* endpoint) { struct usb_interface* intf; - struct usb_interface_descriptor* intfd; + struct usb_host_interface* intfd; struct usb_endpoint_descriptor* epd; if (endpoint->epnum == -1) { @@ -843,9 +841,9 @@ static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, if (!intf || intf->num_altsetting < 1) return -ENOENT; intfd = intf->altsetting; - if (intfd->bNumEndpoints < 1) + if (intfd->desc.bNumEndpoints < 1) return -ENOENT; - epd = intfd->endpoint; + epd = &intfd->endpoint [0].desc; endpoint->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; } return 0; @@ -858,14 +856,14 @@ static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi, snd_usb_midi_endpoint_info_t* endpoint) { struct usb_interface* intf; - struct usb_interface_descriptor* intfd; + struct usb_host_interface* intfd; uint8_t* cs_desc; intf = umidi->iface; if (!intf) return -ENOENT; intfd = intf->altsetting; - if (intfd->bNumEndpoints < 1) + if (intfd->desc.bNumEndpoints < 1) return -ENOENT; for (cs_desc = intfd->extra; @@ -892,7 +890,7 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports { snd_usb_midi_endpoint_info_t ep_info; struct usb_interface* intf; - struct usb_interface_descriptor* intfd; + struct usb_host_interface* intfd; struct usb_endpoint_descriptor* epd; int cable, err; @@ -900,25 +898,25 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports if (!intf) return -ENOENT; intfd = intf->altsetting; - if (intfd->bNumEndpoints < (ports > 1 ? 5 : 3)) { + if (intfd->desc.bNumEndpoints < (ports > 1 ? 5 : 3)) { snd_printdd(KERN_ERR "not enough endpoints\n"); return -ENOENT; } - epd = &intfd->endpoint[0]; + epd = &intfd->endpoint[0].desc; if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN || (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n"); return -ENXIO; } - epd = &intfd->endpoint[2]; + epd = &intfd->endpoint[2].desc; if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n"); return -ENXIO; } if (ports > 1) { - epd = &intfd->endpoint[4]; + epd = &intfd->endpoint[4].desc; if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n"); @@ -926,13 +924,13 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports } } - ep_info.epnum = intfd->endpoint[2].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.epnum = intfd->endpoint[2].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.out_cables = 0x5555 & ((1 << ports) - 1); err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) return err; - ep_info.epnum = intfd->endpoint[0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.epnum = intfd->endpoint[0].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.in_cables = (1 << ports) - 1; err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) @@ -940,7 +938,7 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports umidi->endpoints[0].in->urb->complete = snd_usbmidi_in_midiman_complete; if (ports > 1) { - ep_info.epnum = intfd->endpoint[4].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.epnum = intfd->endpoint[4].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.out_cables = 0xaaaa & ((1 << ports) - 1); err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]); if (err < 0) |
