From 50d369cba8d1a88f0fe46e18cd9cce71ff01920d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 18 Aug 2007 00:07:40 -0700 Subject: [PATCH] --- yaml --- r: 64211 b: refs/heads/master c: 195f7fd0a7e2b3179d52aa8ed6de3637203946c6 h: refs/heads/master i: 64209: ae988ed0278d305258492530686eff85f889026b 64207: f57be9bb336659e2a7ee6c527e104cc624814192 v: v3 --- [refs] | 2 +- trunk/arch/i386/Kconfig | 8 +- trunk/arch/i386/mm/fault.c | 5 +- trunk/arch/powerpc/sysdev/fsl_pci.c | 2 - trunk/arch/s390/hypfs/inode.c | 33 +- trunk/arch/s390/kernel/Makefile | 2 +- trunk/arch/s390/kernel/diag.c | 102 ----- trunk/arch/s390/kernel/dis.c | 2 +- trunk/arch/s390/kernel/kprobes.c | 2 +- trunk/arch/s390/kernel/s390_ksyms.c | 1 + trunk/arch/s390/mm/cmm.c | 1 - trunk/arch/s390/mm/init.c | 17 + trunk/drivers/isdn/hisax/hfc_usb.c | 603 ++++++++++++++++----------- trunk/drivers/isdn/hisax/hfc_usb.h | 130 +++--- trunk/drivers/net/ppp_generic.c | 2 +- trunk/drivers/net/sky2.c | 4 +- trunk/drivers/s390/block/dasd_diag.c | 1 - trunk/drivers/s390/char/raw3270.c | 1 - trunk/drivers/s390/char/vmur.c | 250 ++++------- trunk/drivers/s390/char/vmur.h | 1 - trunk/drivers/s390/cio/cmf.c | 10 +- trunk/drivers/s390/cio/device.c | 5 +- trunk/drivers/s390/cio/device_id.c | 48 ++- trunk/drivers/s390/cio/qdio.c | 5 +- trunk/drivers/usb/host/ehci-hcd.c | 67 +++ trunk/drivers/usb/host/ehci-mem.c | 3 + trunk/drivers/usb/host/ehci-q.c | 4 + trunk/drivers/usb/host/ehci-sched.c | 127 ++++++ trunk/drivers/usb/host/ehci.h | 14 + trunk/include/asm-s390/atomic.h | 26 +- trunk/include/asm-s390/cio.h | 15 + trunk/include/asm-s390/diag.h | 39 -- trunk/include/asm-s390/pgalloc.h | 2 + trunk/include/asm-sparc64/percpu.h | 4 +- trunk/include/asm-sparc64/system.h | 26 +- trunk/include/linux/pci_ids.h | 6 +- trunk/kernel/printk.c | 10 +- trunk/net/802/psnap.c | 17 +- trunk/net/dccp/ccids/ccid2.c | 2 +- trunk/net/ipv6/ip6_output.c | 2 +- trunk/net/irda/irmod.c | 2 +- trunk/net/irda/irnetlink.c | 2 +- 42 files changed, 890 insertions(+), 715 deletions(-) delete mode 100644 trunk/arch/s390/kernel/diag.c delete mode 100644 trunk/include/asm-s390/diag.h diff --git a/[refs] b/[refs] index fd8dfb414637..cb47f73828c9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 13c926e04602db207366c7d213dd99d443ac4ad8 +refs/heads/master: 195f7fd0a7e2b3179d52aa8ed6de3637203946c6 diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 97b64d7d6bf6..f16a46e8849c 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -614,14 +614,10 @@ config X86_PAE # Common NUMA Features config NUMA - bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)" - depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL + bool "Numa Memory Allocation and Scheduler Support" + depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) - help - NUMA support for i386. This is currently high experimental - and should be only used for kernel development. It might also - cause boot failures. comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index fcb38e7f3543..01ffdd4964f0 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -249,10 +249,9 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) return NULL; - if (!pmd_present(*pmd)) { + if (!pmd_present(*pmd)) set_pmd(pmd, *pmd_k); - arch_flush_lazy_mmu_mode(); - } else + else BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); return pmd_k; } diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c index 114c90f8f560..9fb0ce5c7176 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.c +++ b/trunk/arch/powerpc/sysdev/fsl_pci.c @@ -251,8 +251,6 @@ DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transpare DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index 5245717295b8..ad4ca75c0f04 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -60,28 +60,17 @@ static void hypfs_add_dentry(struct dentry *dentry) hypfs_last_dentry = dentry; } -static inline int hypfs_positive(struct dentry *dentry) -{ - return dentry->d_inode && !d_unhashed(dentry); -} - static void hypfs_remove(struct dentry *dentry) { struct dentry *parent; parent = dentry->d_parent; - if (!parent || !parent->d_inode) - return; - mutex_lock(&parent->d_inode->i_mutex); - if (hypfs_positive(dentry)) { - if (S_ISDIR(dentry->d_inode->i_mode)) - simple_rmdir(parent->d_inode, dentry); - else - simple_unlink(parent->d_inode, dentry); - } + if (S_ISDIR(dentry->d_inode->i_mode)) + simple_rmdir(parent->d_inode, dentry); + else + simple_unlink(parent->d_inode, dentry); d_delete(dentry); dput(dentry); - mutex_unlock(&parent->d_inode->i_mutex); } static void hypfs_delete_tree(struct dentry *root) @@ -326,7 +315,6 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) } hypfs_update_update(sb); sb->s_root = root_dentry; - printk(KERN_INFO "hypfs: Hypervisor filesystem mounted\n"); return 0; err_tree: @@ -368,17 +356,13 @@ static struct dentry *hypfs_create_file(struct super_block *sb, qname.name = name; qname.len = strlen(name); qname.hash = full_name_hash(name, qname.len); - mutex_lock(&parent->d_inode->i_mutex); dentry = lookup_one_len(name, parent, strlen(name)); - if (IS_ERR(dentry)) { - dentry = ERR_PTR(-ENOMEM); - goto fail; - } + if (IS_ERR(dentry)) + return ERR_PTR(-ENOMEM); inode = hypfs_make_inode(sb, mode); if (!inode) { dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto fail; + return ERR_PTR(-ENOMEM); } if (mode & S_IFREG) { inode->i_fop = &hypfs_file_ops; @@ -395,8 +379,6 @@ static struct dentry *hypfs_create_file(struct super_block *sb, inode->i_private = data; d_instantiate(dentry, inode); dget(dentry); -fail: - mutex_unlock(&parent->d_inode->i_mutex); return dentry; } @@ -409,6 +391,7 @@ struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, if (IS_ERR(dentry)) return dentry; hypfs_add_dentry(dentry); + parent->d_inode->i_nlink++; return dentry; } diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile index 56cb71007cd9..3195d375bd51 100644 --- a/trunk/arch/s390/kernel/Makefile +++ b/trunk/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o + semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/trunk/arch/s390/kernel/diag.c b/trunk/arch/s390/kernel/diag.c deleted file mode 100644 index c032d11da8a1..000000000000 --- a/trunk/arch/s390/kernel/diag.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Implementation of s390 diagnose codes - * - * Copyright IBM Corp. 2007 - * Author(s): Michael Holzheu - */ - -#include -#include - -/* - * Diagnose 10: Release pages - */ -void diag10(unsigned long addr) -{ - if (addr >= 0x7ff00000) - return; - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" -#else - " diag %0,%0,0x10\n" - "0:\n" -#endif - EX_TABLE(0b, 0b) - : : "a" (addr)); -} -EXPORT_SYMBOL(diag10); - -/* - * Diagnose 14: Input spool file manipulation - */ -int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) -{ - register unsigned long _ry1 asm("2") = ry1; - register unsigned long _ry2 asm("3") = subcode; - int rc = 0; - - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %2,2,0x14\n" - " sam64\n" -#else - " diag %2,2,0x14\n" -#endif - " ipm %0\n" - " srl %0,28\n" - : "=d" (rc), "+d" (_ry2) - : "d" (rx), "d" (_ry1) - : "cc"); - - return rc; -} -EXPORT_SYMBOL(diag14); - -/* - * Diagnose 210: Get information about a virtual device - */ -int diag210(struct diag210 *addr) -{ - /* - * diag 210 needs its data below the 2GB border, so we - * use a static data area to be sure - */ - static struct diag210 diag210_tmp; - static DEFINE_SPINLOCK(diag210_lock); - unsigned long flags; - int ccode; - - spin_lock_irqsave(&diag210_lock, flags); - diag210_tmp = *addr; - -#ifdef CONFIG_64BIT - asm volatile( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - EX_TABLE(0b, 1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#else - asm volatile( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#endif - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} -EXPORT_SYMBOL(diag210); diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index 50d2235df732..d3057318f2bf 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -577,7 +577,7 @@ static struct insn opcode_b2[] = { { "esta", 0x4a, INSTR_RRE_RR }, { "lura", 0x4b, INSTR_RRE_RR }, { "tar", 0x4c, INSTR_RRE_AR }, - { "cpya", 0x4d, INSTR_RRE_AA }, + { "cpya", INSTR_RRE_AA }, { "sar", 0x4e, INSTR_RRE_AR }, { "ear", 0x4f, INSTR_RRE_RA }, { "csp", 0x50, INSTR_RRE_RR }, diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index e40373d9fbce..358d2bbbc481 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -85,7 +85,7 @@ void __kprobes get_instruction_type(struct arch_specific_insn *ainsn) ainsn->reg = (*ainsn->insn & 0xf0) >> 4; /* save the instruction length (pop 5-5) in bytes */ - switch (*(__u8 *) (ainsn->insn) >> 6) { + switch (*(__u8 *) (ainsn->insn) >> 4) { case 0: ainsn->ilen = 2; break; diff --git a/trunk/arch/s390/kernel/s390_ksyms.c b/trunk/arch/s390/kernel/s390_ksyms.c index 7234c737f825..90b5ef529eb7 100644 --- a/trunk/arch/s390/kernel/s390_ksyms.c +++ b/trunk/arch/s390/kernel/s390_ksyms.c @@ -25,6 +25,7 @@ EXPORT_SYMBOL(_oi_bitmap); EXPORT_SYMBOL(_ni_bitmap); EXPORT_SYMBOL(_zb_findmap); EXPORT_SYMBOL(_sb_findmap); +EXPORT_SYMBOL(diag10); /* * semaphore ops diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c index fabc50adc46a..c5b2f4f078bc 100644 --- a/trunk/arch/s390/mm/cmm.c +++ b/trunk/arch/s390/mm/cmm.c @@ -20,7 +20,6 @@ #include #include -#include static char *sender = "VMRMSVM"; module_param(sender, charp, 0400); diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 3a25bbf2eb0a..9098531a2671 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -42,6 +42,23 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); +void diag10(unsigned long addr) +{ + if (addr >= 0x7ff00000) + return; + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" +#else + " diag %0,%0,0x10\n" + "0:\n" +#endif + EX_TABLE(0b,0b) + : : "a" (addr)); +} + void show_mem(void) { int i, total = 0, reserved = 0; diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index 60843b3f3b6f..b1a26e02df02 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -1,12 +1,12 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $ + * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * - * Authors : Peter Sprenger (sprenger@moving-bytes.de) - * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) + * Authors : Peter Sprenger (sprenger@moving-bytes.de) + * Martin Bachem (info@colognechip.com) * * based on the first hfc_usb driver of * Werner Cornelius (werner@isdn-development.de) @@ -37,25 +37,24 @@ #include #include #include -#include -#include -#include #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ "; + "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; /* Hisax debug support -* debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] +* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG */ +#ifdef CONFIG_HISAX_DEBUG +#include #define __debug_variable hfc_debug #include "hisax_debug.h" static u_int debug; module_param(debug, uint, 0); static int hfc_debug; - +#endif /* private vendor specific data */ typedef struct { @@ -64,7 +63,9 @@ typedef struct { char *vend_name; // device name } hfcsusb_vdata; -/* VID/PID device list */ +/****************************************/ +/* data defining the devices to be used */ +/****************************************/ static struct usb_device_id hfcusb_idtab[] = { { USB_DEVICE(0x0959, 0x2bd0), @@ -89,47 +90,49 @@ static struct usb_device_id hfcusb_idtab[] = { .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Stollmann USB TA"}), - }, + }, { USB_DEVICE(0x0742, 0x2009), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Aceex USB ISDN TA"}), - }, + }, { USB_DEVICE(0x0742, 0x200A), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "OEM USB ISDN TA"}), - }, + }, { USB_DEVICE(0x08e3, 0x0301), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {2, 0, 1, 4}, "Olitec USB RNIS"}), - }, + }, { USB_DEVICE(0x07fa, 0x0846), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Bewan Modem RNIS USB"}), - }, + }, { USB_DEVICE(0x07fa, 0x0847), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Djinn Numeris USB"}), - }, + }, { USB_DEVICE(0x07b0, 0x0006), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Twister ISDN TA"}), - }, + }, { } }; +/***************************************************************/ /* structure defining input+output fifos (interrupt/bulk mode) */ +/***************************************************************/ struct usb_fifo; /* forward definition */ typedef struct iso_urb_struct { struct urb *purb; @@ -137,8 +140,8 @@ typedef struct iso_urb_struct { struct usb_fifo *owner_fifo; /* pointer to owner fifo */ } iso_urb_struct; -struct hfcusb_data; /* forward definition */ +struct hfcusb_data; /* forward definition */ typedef struct usb_fifo { int fifonum; /* fifo index attached to this structure */ int active; /* fifo is currently active */ @@ -157,12 +160,15 @@ typedef struct usb_fifo { struct hisax_if *hif; /* hisax interface */ int delete_flg; /* only delete skbuff once */ int last_urblen; /* remember length of last packet */ + } usb_fifo; +/*********************************************/ /* structure holding all data for one device */ +/*********************************************/ typedef struct hfcusb_data { /* HiSax Interface for loadable Layer1 drivers */ - struct hisax_d_if d_if; /* see hisax_if.h */ + struct hisax_d_if d_if; /* see hisax_if.h */ struct hisax_b_if b_if[2]; /* see hisax_if.h */ int protocol; @@ -170,13 +176,12 @@ typedef struct hfcusb_data { int if_used; /* used interface number */ int alt_used; /* used alternate config */ int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, /* handles for control pipe */ - ctrl_out_pipe; + int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ int cfg_used; /* configuration index used */ int vend_idx; /* vendor found */ int b_mode[2]; /* B-channel mode */ int l1_activated; /* layer 1 activated */ - int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ + int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ int packet_size, iso_packet_size; /* control pipe background handling */ @@ -203,6 +208,7 @@ typedef struct hfcusb_data { static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish); + static inline const char * symbolic(struct hfcusb_symbolic_list list[], const int num) { @@ -213,6 +219,10 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) return ""; } + +/******************************************************/ +/* start next background transfer for control channel */ +/******************************************************/ static void ctrl_start_transfer(hfcusb_data * hfc) { @@ -230,6 +240,10 @@ ctrl_start_transfer(hfcusb_data * hfc) } } /* ctrl_start_transfer */ +/************************************/ +/* queue a control transfer request */ +/* return 0 on success. */ +/************************************/ static int queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) { @@ -246,8 +260,19 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) if (++hfc->ctrl_cnt == 1) ctrl_start_transfer(hfc); return (0); +} /* queue_control_request */ + +static int +control_action_handler(hfcusb_data * hfc, int reg, int val, int action) +{ + if (!action) + return (1); /* no action defined */ + return (0); } +/***************************************************************/ +/* control completion routine handling background control cmds */ +/***************************************************************/ static void ctrl_complete(struct urb *urb) { @@ -257,6 +282,9 @@ ctrl_complete(struct urb *urb) urb->dev = hfc->dev; if (hfc->ctrl_cnt) { buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; + control_action_handler(hfc, buf->hfc_reg, buf->reg_val, + buf->action); + hfc->ctrl_cnt--; /* decrement actual count */ if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ @@ -265,7 +293,9 @@ ctrl_complete(struct urb *urb) } } /* ctrl_complete */ +/***************************************************/ /* write led data to auxport & invert if necessary */ +/***************************************************/ static void write_led(hfcusb_data * hfc, __u8 led_state) { @@ -275,6 +305,9 @@ write_led(hfcusb_data * hfc, __u8 led_state) } } +/**************************/ +/* handle LED bits */ +/**************************/ static void set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) { @@ -291,7 +324,9 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) } } -/* handle LED requests */ +/**************************/ +/* handle LED requests */ +/**************************/ static void handle_led(hfcusb_data * hfc, int event) { @@ -304,73 +339,85 @@ handle_led(hfcusb_data * hfc, int event) switch (event) { case LED_POWER_ON: - set_led_bit(hfc, driver_info->led_bits[0], 0); - set_led_bit(hfc, driver_info->led_bits[1], 1); - set_led_bit(hfc, driver_info->led_bits[2], 1); - set_led_bit(hfc, driver_info->led_bits[3], 1); + set_led_bit(hfc, driver_info->led_bits[0], + 0); + set_led_bit(hfc, driver_info->led_bits[1], + 1); + set_led_bit(hfc, driver_info->led_bits[2], + 1); + set_led_bit(hfc, driver_info->led_bits[3], + 1); break; - case LED_POWER_OFF: - set_led_bit(hfc, driver_info->led_bits[0], 1); - set_led_bit(hfc, driver_info->led_bits[1], 1); - set_led_bit(hfc, driver_info->led_bits[2], 1); - set_led_bit(hfc, driver_info->led_bits[3], 1); + case LED_POWER_OFF: /* no Power off handling */ break; case LED_S0_ON: - set_led_bit(hfc, driver_info->led_bits[1], 0); + set_led_bit(hfc, driver_info->led_bits[1], + 0); break; case LED_S0_OFF: - set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[1], + 1); break; case LED_B1_ON: - set_led_bit(hfc, driver_info->led_bits[2], 0); + set_led_bit(hfc, driver_info->led_bits[2], + 0); break; case LED_B1_OFF: - set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[2], + 1); break; case LED_B2_ON: - set_led_bit(hfc, driver_info->led_bits[3], 0); + set_led_bit(hfc, driver_info->led_bits[3], + 0); break; case LED_B2_OFF: - set_led_bit(hfc, driver_info->led_bits[3], 1); + set_led_bit(hfc, driver_info->led_bits[3], + 1); break; } write_led(hfc, hfc->led_state); } -/* ISDN l1 timer T3 expires */ +/********************************/ +/* called when timer t3 expires */ +/********************************/ static void l1_timer_expire_t3(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); - - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); - - hfc->l1_activated = 0; +#endif + hfc->l1_activated = false; handle_led(hfc, LED_S0_OFF); /* deactivate : */ queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); queue_control_request(hfc, HFCUSB_STATES, 3, 1); } -/* ISDN l1 timer T4 expires */ +/********************************/ +/* called when timer t4 expires */ +/********************************/ static void l1_timer_expire_t4(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); - - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); - - hfc->l1_activated = 0; +#endif + hfc->l1_activated = false; handle_led(hfc, LED_S0_OFF); } -/* S0 state changed */ +/*****************************/ +/* handle S0 state changes */ +/*****************************/ static void -s0_state_handler(hfcusb_data * hfc, __u8 state) +state_handler(hfcusb_data * hfc, __u8 state) { __u8 old_state; @@ -378,29 +425,38 @@ s0_state_handler(hfcusb_data * hfc, __u8 state) if (state == old_state || state < 1 || state > 8) return; - DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", - old_state, state); - +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, + old_state); +#endif if (state < 4 || state == 7 || state == 8) { if (timer_pending(&hfc->t3_timer)) del_timer(&hfc->t3_timer); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); +#endif } if (state >= 7) { if (timer_pending(&hfc->t4_timer)) del_timer(&hfc->t4_timer); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); +#endif } if (state == 7 && !hfc->l1_activated) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); - DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); - hfc->l1_activated = 1; +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); +#endif + hfc->l1_activated = true; handle_led(hfc, LED_S0_ON); } else if (state <= 3 /* && activated */ ) { if (old_state == 7 || old_state == 8) { - DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: T4 activated"); +#endif if (!timer_pending(&hfc->t4_timer)) { hfc->t4_timer.expires = jiffies + (HFC_TIMER_T4 * HZ) / 1000; @@ -410,15 +466,18 @@ s0_state_handler(hfcusb_data * hfc, __u8 state) hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); - hfc->l1_activated = 0; +#endif + hfc->l1_activated = false; handle_led(hfc, LED_S0_OFF); } } hfc->l1_state = state; } +/* prepare iso urb */ static void fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *buf, int num_packets, int packet_size, int interval, @@ -444,16 +503,15 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, } /* allocs urbs and start isoc transfer with two pending urbs to avoid - * gaps in the transfer chain - */ + gaps in the transfer chain */ static int start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, usb_complete_t complete, int packet_size) { int i, k, errcode; - DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", - fifo->fifonum); + printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", + fifo->fifonum); /* allocate Memory for Iso out Urbs */ for (i = 0; i < 2; i++) { @@ -498,9 +556,10 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); fifo->active = (errcode >= 0) ? 1 : 0; - if (errcode < 0) - printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", - i, errcode, symbolic(urb_errlist, errcode)); + if (errcode < 0) { + printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", + symbolic(urb_errlist, errcode), i); + }; } return (fifo->active); } @@ -513,15 +572,16 @@ stop_isoc_chain(usb_fifo * fifo) for (i = 0; i < 2; i++) { if (fifo->iso[i].purb) { - DBG(HFCUSB_DBG_INIT, +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, "HFC-S USB: Stopping iso chain for fifo %i.%i", fifo->fifonum, i); +#endif usb_kill_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); fifo->iso[i].purb = NULL; } } - usb_kill_urb(fifo->urb); usb_free_urb(fifo->urb); fifo->urb = NULL; @@ -534,6 +594,9 @@ static int iso_packets[8] = ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D }; +/*****************************************************/ +/* transmit completion routine for all ISO tx fifos */ +/*****************************************************/ static void tx_iso_complete(struct urb *urb) { @@ -544,38 +607,20 @@ tx_iso_complete(struct urb *urb) errcode; int frame_complete, transp_mode, fifon, status; __u8 threshbit; + __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; fifon = fifo->fifonum; status = urb->status; tx_offset = 0; - /* ISO transfer only partially completed, - look at individual frame status for details */ - if (status == -EXDEV) { - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" - ", urb->status %d, fifonum %d\n", - status, fifon); - - for (k = 0; k < iso_packets[fifon]; ++k) { - errcode = urb->iso_frame_desc[k].status; - if (errcode) - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " - "packet %i, status: %i\n", - k, errcode); - } - - // clear status, so go on with ISO transfers - status = 0; - } - if (fifo->active && !status) { transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = 1; + transp_mode = true; /* is FifoFull-threshold set for our channel? */ - threshbit = (hfc->threshold_mask & (1 << fifon)); + threshbit = threshtable[fifon] & hfc->threshold_mask; num_isoc_packets = iso_packets[fifon]; /* predict dataflow to avoid fifo overflow */ @@ -590,9 +635,8 @@ tx_iso_complete(struct urb *urb) tx_iso_complete, urb->context); memset(context_iso_urb->buffer, 0, sizeof(context_iso_urb->buffer)); - frame_complete = 0; - - /* Generate next ISO Packets */ + frame_complete = false; + /* Generate next Iso Packets */ for (k = 0; k < num_isoc_packets; ++k) { if (fifo->skbuff) { len = fifo->skbuff->len; @@ -617,7 +661,7 @@ tx_iso_complete(struct urb *urb) /* add 2 byte flags and 16bit CRC at end of ISDN frame */ fifo->bit_line += 32; } - frame_complete = 1; + frame_complete = true; } memcpy(context_iso_urb->buffer + @@ -644,7 +688,7 @@ tx_iso_complete(struct urb *urb) } if (frame_complete) { - fifo->delete_flg = 1; + fifo->delete_flg = true; fifo->hif->l1l2(fifo->hif, PH_DATA | CONFIRM, (void *) (unsigned long) fifo->skbuff-> @@ -652,26 +696,30 @@ tx_iso_complete(struct urb *urb) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = 0; + fifo->delete_flg = false; } - frame_complete = 0; + frame_complete = false; } } errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d\n", + "HFC-S USB: error submitting ISO URB: %d \n", errcode); } } else { if (status && !hfc->disc_flag) { printk(KERN_INFO - "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", - status, symbolic(urb_errlist, status), fifon); + "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", + symbolic(urb_errlist, status), status, + fifon); } } -} +} /* tx_iso_complete */ +/*****************************************************/ +/* receive completion routine for all ISO tx fifos */ +/*****************************************************/ static void rx_iso_complete(struct urb *urb) { @@ -683,25 +731,21 @@ rx_iso_complete(struct urb *urb) unsigned int iso_status; __u8 *buf; static __u8 eof[8]; +#ifdef CONFIG_HISAX_DEBUG + __u8 i; +#endif fifon = fifo->fifonum; status = urb->status; if (urb->status == -EOVERFLOW) { - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); - status = 0; - } - - /* ISO transfer only partially completed, - look at individual frame status for details */ - if (status == -EXDEV) { - DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " - "urb->status %d, fifonum %d\n", - status, fifon); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", + fifon); +#endif status = 0; } - if (fifo->active && !status) { num_isoc_packets = iso_packets[fifon]; maxlen = fifo->usb_packet_maxlen; @@ -710,38 +754,40 @@ rx_iso_complete(struct urb *urb) offset = urb->iso_frame_desc[k].offset; buf = context_iso_urb->buffer + offset; iso_status = urb->iso_frame_desc[k].status; - +#ifdef CONFIG_HISAX_DEBUG if (iso_status && !hfc->disc_flag) - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-S USB: rx_iso_complete " - "ISO packet %i, status: %i\n", - k, iso_status); + DBG(USB_DBG, + "HFC-S USB: ISO packet failure - status:%x", + iso_status); - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_VERBOSE_USB, + if ((fifon == 5) && (debug > 1)) { + printk(KERN_INFO "HFC-S USB: ISO-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d EOF:0x%0x", + "act_urblen:%2d max-urblen:%2d " + "EOF:0x%0x DATA: ", fifo->last_urblen, len, maxlen, eof[5]); - - DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); + for (i = 0; i < len; i++) + printk("%.2x ", buf[i]); + printk("\n"); } - +#endif if (fifo->last_urblen != maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* care for L1 state only for D-Channel to avoid overlapped iso completions */ - if (fifon == HFCUSB_D_RX) { + if (fifon == 5) { /* the S0 state is in the upper half of the 1st status byte */ - s0_state_handler(hfc, buf[0] >> 4); + state_handler(hfc, buf[0] >> 4); } eof[fifon] = buf[0] & 1; if (len > 2) collect_rx_frame(fifo, buf + 2, len - 2, - (len < maxlen) ? + (len < + maxlen) ? eof[fifon] : 0); } else { collect_rx_frame(fifo, buf, len, @@ -758,37 +804,41 @@ rx_iso_complete(struct urb *urb) rx_iso_complete, urb->context); errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { - printk(KERN_ERR - "HFC-S USB: error submitting ISO URB: %d\n", + printk(KERN_INFO + "HFC-S USB: error submitting ISO URB: %d \n", errcode); } } else { if (status && !hfc->disc_flag) { - printk(KERN_ERR + printk(KERN_INFO "HFC-S USB: rx_iso_complete : " "urb->status %d, fifonum %d\n", status, fifon); } } -} +} /* rx_iso_complete */ -/* collect rx data from INT- and ISO-URBs */ +/*****************************************************/ +/* collect data from interrupt or isochron in */ +/*****************************************************/ static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) { hfcusb_data *hfc = fifo->hfc; int transp_mode, fifon; - +#ifdef CONFIG_HISAX_DEBUG + int i; +#endif fifon = fifo->fifonum; transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = 1; + transp_mode = true; if (!fifo->skbuff) { fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); if (!fifo->skbuff) { - printk(KERN_ERR - "HFC-S USB: cannot allocate buffer for fifo(%d)\n", + printk(KERN_INFO + "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", fifon); return; } @@ -797,11 +847,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (fifo->skbuff->len + len < fifo->max_size) { memcpy(skb_put(fifo->skbuff, len), data, len); } else { - DBG(HFCUSB_DBG_FIFO_ERR, - "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", +#ifdef CONFIG_HISAX_DEBUG + printk(KERN_INFO "HFC-S USB: "); + for (i = 0; i < 15; i++) + printk("%.2x ", + fifo->skbuff->data[fifo->skbuff-> + len - 15 + i]); + printk("\n"); +#endif + printk(KERN_INFO + "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", fifo->max_size, fifon); - DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); - skb_trim(fifo->skbuff, 0); } } if (transp_mode && fifo->skbuff->len >= 128) { @@ -814,13 +870,6 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (finish) { if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) && (fifo->skbuff->len > 3)) { - - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_DCHANNEL, - "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); - DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); - } - /* remove CRC & status */ skb_trim(fifo->skbuff, fifo->skbuff->len - 3); if (fifon == HFCUSB_PCM_RX) { @@ -833,17 +882,39 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) fifo->skbuff); fifo->skbuff = NULL; /* buffer was freed from upper layer */ } else { - DBG(HFCUSB_DBG_FIFO_ERR, - "HFC-S USB: ERROR frame len(%d) fifo(%d)", - fifo->skbuff->len, fifon); - DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); + if (fifo->skbuff->len > 3) { + printk(KERN_INFO + "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", + fifo->skbuff->len, fifon); +#ifdef CONFIG_HISAX_DEBUG + if (debug > 1) { + printk(KERN_INFO "HFC-S USB: "); + for (i = 0; i < 15; i++) + printk("%.2x ", + fifo->skbuff-> + data[fifo->skbuff-> + len - 15 + i]); + printk("\n"); + } +#endif + } +#ifdef CONFIG_HISAX_DEBUG + else { + printk(KERN_INFO + "HFC-S USB: frame to small (%d bytes)!!!\n", + fifo->skbuff->len); + } +#endif skb_trim(fifo->skbuff, 0); } } } +/***********************************************/ +/* receive completion routine for all rx fifos */ +/***********************************************/ static void -rx_int_complete(struct urb *urb) +rx_complete(struct urb *urb) { int len; int status; @@ -851,14 +922,18 @@ rx_int_complete(struct urb *urb) usb_fifo *fifo = (usb_fifo *) urb->context; hfcusb_data *hfc = fifo->hfc; static __u8 eof[8]; +#ifdef CONFIG_HISAX_DEBUG + __u8 i; +#endif urb->dev = hfc->dev; /* security init */ fifon = fifo->fifonum; if ((!fifo->active) || (urb->status)) { - DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", fifon, urb->status); - +#endif fifo->urb->interval = 0; /* cancel automatic rescheduling */ if (fifo->skbuff) { dev_kfree_skb_any(fifo->skbuff); @@ -870,20 +945,22 @@ rx_int_complete(struct urb *urb) buf = fifo->buffer; maxlen = fifo->usb_packet_maxlen; - if (fifon == HFCUSB_D_RX) { - DBG(HFCUSB_DBG_VERBOSE_USB, - "HFC-S USB: INT-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d EOF:0x%0x", - fifo->last_urblen, len, maxlen, - eof[5]); - DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); +#ifdef CONFIG_HISAX_DEBUG + if ((fifon == 5) && (debug > 1)) { + printk(KERN_INFO + "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", + fifo->last_urblen, len, maxlen, eof[5]); + for (i = 0; i < len; i++) + printk("%.2x ", buf[i]); + printk("\n"); } +#endif if (fifo->last_urblen != fifo->usb_packet_maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* the S0 state is in the upper half of the 1st status byte */ - s0_state_handler(hfc, buf[0] >> 4); + state_handler(hfc, buf[0] >> 4); eof[fifon] = buf[0] & 1; /* if we have more than the 2 status bytes -> collect data */ if (len > 2) @@ -898,19 +975,20 @@ rx_int_complete(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { printk(KERN_INFO - "HFC-S USB: %s error resubmitting URB fifo(%d)\n", - __FUNCTION__, fifon); + "HFC-S USB: error resubmitting URN at rx_complete...\n"); } -} +} /* rx_complete */ -/* start initial INT-URB for certain fifo */ +/***************************************************/ +/* start the interrupt transfer for the given fifo */ +/***************************************************/ static void start_int_fifo(usb_fifo * fifo) { int errcode; - DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", - fifo->fifonum); + printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", + fifo->fifonum); if (!fifo->urb) { fifo->urb = usb_alloc_urb(0, GFP_KERNEL); @@ -919,28 +997,33 @@ start_int_fifo(usb_fifo * fifo) } usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer, fifo->usb_packet_maxlen, - rx_int_complete, fifo, fifo->intervall); + rx_complete, fifo, fifo->intervall); fifo->active = 1; /* must be marked active */ errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); if (errcode) { - printk(KERN_ERR + printk(KERN_INFO "HFC-S USB: submit URB error(start_int_info): status:%i\n", errcode); fifo->active = 0; fifo->skbuff = NULL; } -} +} /* start_int_fifo */ +/*****************************/ +/* set the B-channel mode */ +/*****************************/ static void -setup_bchannel(hfcusb_data * hfc, int channel, int mode) +set_hfcmode(hfcusb_data * hfc, int channel, int mode) { __u8 val, idx_table[2] = { 0, 2 }; if (hfc->disc_flag) { return; } - DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", - channel, mode); +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, + mode); +#endif hfc->b_mode[channel] = mode; /* setup CON_HDLC */ @@ -997,17 +1080,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) switch (pr) { case PH_ACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); - +#endif if (hfc->l1_state != 3 && hfc->l1_state != 7) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); +#endif } else { if (hfc->l1_state == 7) { /* l1 already active */ hfc->d_if.ifc.l1l2(&hfc-> @@ -1017,8 +1103,10 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | INDICATION, NULL); - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); +#endif } else { /* force sending sending INFO1 */ queue_control_request(hfc, @@ -1044,9 +1132,11 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) } } } else { - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); - setup_bchannel(hfc, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, + "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); +#endif + set_hfcmode(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (long) arg); @@ -1057,12 +1147,18 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) break; case PH_DEACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); +#endif + printk(KERN_INFO + "HFC-S USB: ISDN TE device should not deativate...\n"); } else { - DBG(HFCUSB_DBG_STATES, +#ifdef CONFIG_HISAX_DEBUG + DBG(ISDN_DBG, "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); - setup_bchannel(hfc, +#endif + set_hfcmode(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (int) L1_MODE_NULL); @@ -1075,20 +1171,25 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = 0; + fifo->delete_flg = false; } fifo->skbuff = arg; /* we have a new buffer */ break; default: - DBG(HFCUSB_DBG_STATES, - "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); + printk(KERN_INFO + "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", + pr); break; } } -/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ +/***************************************************************************/ +/* usb_init is called once when a new matching device is detected to setup */ +/* main parameters. It registers the driver at the main hisax module. */ +/* on success 0 is returned. */ +/***************************************************************************/ static int -hfc_usb_init(hfcusb_data * hfc) +usb_init(hfcusb_data * hfc) { usb_fifo *fifo; int i, err; @@ -1113,11 +1214,11 @@ hfc_usb_init(hfcusb_data * hfc) /* aux = output, reset off */ write_usb(hfc, HFCUSB_CIRM, 0x10); - /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ + /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ write_usb(hfc, HFCUSB_USB_SIZE, (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ + /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); /* enable PCM/GCI master mode */ @@ -1156,8 +1257,8 @@ hfc_usb_init(hfcusb_data * hfc) hfc->b_mode[0] = L1_MODE_NULL; hfc->b_mode[1] = L1_MODE_NULL; - hfc->l1_activated = 0; - hfc->disc_flag = 0; + hfc->l1_activated = false; + hfc->disc_flag = false; hfc->led_state = 0; hfc->led_new_data = 0; hfc->old_led_state = 0; @@ -1248,9 +1349,11 @@ hfc_usb_init(hfcusb_data * hfc) handle_led(hfc, LED_POWER_ON); return (0); -} +} /* usb_init */ -/* initial callback for each plugged USB device */ +/*************************************************/ +/* function called to probe a new plugged device */ +/*************************************************/ static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1275,6 +1378,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, + iface->desc.bAlternateSetting, intf->minor); +#endif printk(KERN_INFO "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, iface->desc.bAlternateSetting, intf->minor); @@ -1295,11 +1403,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* check for config EOL element */ while (validconf[cfg_used][0]) { - cfg_found = 1; + cfg_found = true; vcf = validconf[cfg_used]; /* first endpoint descriptor */ ep = iface->endpoint; - +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", + ifnum, probe_alt_setting, cfg_used); +#endif memcpy(cmptbl, vcf, 16 * sizeof(int)); /* check for all endpoints in this alternate setting */ @@ -1313,7 +1425,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) idx++; attr = ep->desc.bmAttributes; if (cmptbl[idx] == EP_NUL) { - cfg_found = 0; + cfg_found = false; } if (attr == USB_ENDPOINT_XFER_INT && cmptbl[idx] == EP_INT) @@ -1326,9 +1438,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) cmptbl[idx] = EP_NUL; /* check if all INT endpoints match minimum interval */ - if ((attr == USB_ENDPOINT_XFER_INT) - && (ep->desc.bInterval < vcf[17])) { - cfg_found = 0; + if (attr == USB_ENDPOINT_XFER_INT + && ep->desc.bInterval < + vcf[17]) { +#ifdef CONFIG_HISAX_DEBUG + if (cfg_found) + DBG(USB_DBG, + "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", + vcf[17]); +#endif + cfg_found = false; } ep++; } @@ -1336,7 +1455,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* all entries must be EP_NOP or EP_NUL for a valid config */ if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) - cfg_found = 0; + cfg_found = false; } if (cfg_found) { if (cfg_used < small_match) { @@ -1345,16 +1464,23 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) probe_alt_setting; iface_used = iface; } +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-USB: small_match=%x %x\n", + small_match, alt_used); +#endif } cfg_used++; } alt_idx++; - } /* (alt_idx < intf->num_altsetting) */ + } /* (alt_idx < intf->num_altsetting) */ /* found a valid USB Ta Endpint config */ if (small_match != 0xffff) { iface = iface_used; - if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) + if (! + (context = + kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) return (-ENOMEM); /* got no mem */ ep = iface->endpoint; @@ -1487,15 +1613,20 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) driver_info; printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", driver_info->vend_name); - - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", conf_str[small_match], context->if_used, - context->alt_used, - validconf[small_match][18]); - + context->alt_used); + printk(KERN_INFO + "HFC-S USB: E-channel (\"ECHO:\") logging "); + if (validconf[small_match][18]) + printk(" possible\n"); + else + printk("NOT possible\n"); +#endif /* init the chip and register the driver */ - if (hfc_usb_init(context)) { + if (usb_init(context)) { usb_kill_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; @@ -1512,19 +1643,17 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return (-EIO); } -/* callback for unplugged USB device */ +/****************************************************/ +/* function called when an active device is removed */ +/****************************************************/ static void hfc_usb_disconnect(struct usb_interface *intf) { hfcusb_data *context = usb_get_intfdata(intf); int i; - - handle_led(context, LED_POWER_OFF); - schedule_timeout((10 * HZ) / 1000); - printk(KERN_INFO "HFC-S USB: device disconnect\n"); - context->disc_flag = 1; + context->disc_flag = true; usb_set_intfdata(intf, NULL); if (!context) return; @@ -1532,22 +1661,25 @@ hfc_usb_disconnect(struct usb_interface del_timer(&context->t3_timer); if (timer_pending(&context->t4_timer)) del_timer(&context->t4_timer); - /* tell all fifos to terminate */ for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { if (context->fifos[i].usb_transfer_mode == USB_ISOC) { if (context->fifos[i].active > 0) { stop_isoc_chain(&context->fifos[i]); - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: %s stopping ISOC chain Fifo(%i)", - __FUNCTION__, i); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", + i); +#endif } } else { if (context->fifos[i].active > 0) { context->fifos[i].active = 0; - DBG(HFCUSB_DBG_INIT, - "HFC-S USB: %s unlinking URB for Fifo(%i)", - __FUNCTION__, i); +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, + "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", + i); +#endif } usb_kill_urb(context->fifos[i].urb); usb_free_urb(context->fifos[i].urb); @@ -1560,29 +1692,34 @@ hfc_usb_disconnect(struct usb_interface context->ctrl_urb = NULL; hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ -} +} /* hfc_usb_disconnect */ +/************************************/ +/* our driver information structure */ +/************************************/ static struct usb_driver hfc_drv = { .name = "hfc_usb", .id_table = hfcusb_idtab, .probe = hfc_usb_probe, .disconnect = hfc_usb_disconnect, }; - static void __exit -hfc_usb_mod_exit(void) +hfc_usb_exit(void) { - usb_deregister(&hfc_drv); /* release our driver */ +#ifdef CONFIG_HISAX_DEBUG + DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); +#endif + usb_deregister(&hfc_drv); /* release our driver */ printk(KERN_INFO "HFC-S USB: module removed\n"); } static int __init -hfc_usb_mod_init(void) +hfc_usb_init(void) { - char revstr[30], datestr[30], dummy[30]; #ifndef CONFIG_HISAX_DEBUG - hfc_debug = debug; + unsigned int debug = -1; #endif + char revstr[30], datestr[30], dummy[30]; sscanf(hfcusb_revision, "%s %s $ %s %s %s $ ", dummy, revstr, dummy, datestr, dummy); @@ -1597,8 +1734,8 @@ hfc_usb_mod_init(void) return (0); } -module_init(hfc_usb_mod_init); -module_exit(hfc_usb_mod_exit); +module_init(hfc_usb_init); +module_exit(hfc_usb_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/isdn/hisax/hfc_usb.h b/trunk/drivers/isdn/hisax/hfc_usb.h index e79f56568d30..471f2354dfde 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.h +++ b/trunk/drivers/isdn/hisax/hfc_usb.h @@ -1,8 +1,8 @@ /* - * hfc_usb.h - * - * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ - */ +* hfc_usb.h +* +* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ +*/ #ifndef __HFC_USB_H__ #define __HFC_USB_H__ @@ -10,20 +10,25 @@ #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" +#define VERBOSE_USB_DEBUG -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ +/***********/ +/* defines */ +/***********/ +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ +#define HFC_TIMER_T4 500 /* time for state change interval */ -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ +#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ +#define HFCUSB_L1_DRX 1 /* D-frame received */ +#define HFCUSB_L1_ERX 2 /* E-frame received */ +#define HFCUSB_L1_DTX 4 /* D-frames completed */ -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ + +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ #define HFCUSB_CIRM 0x00 /* cirm register index */ @@ -47,8 +52,9 @@ #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ - +/******************/ /* fifo registers */ +/******************/ #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ @@ -60,9 +66,9 @@ #define HFCUSB_PCM_RX 7 /* - * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just - * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out - */ +* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just +* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out +*/ #define USB_INT 0 #define USB_BULK 1 #define USB_ISOC 2 @@ -71,36 +77,49 @@ #define ISOC_PACKETS_B 8 #define ISO_BUFFER_SIZE 128 -/* Fifo flow Control for TX ISO */ +// ISO send definitions #define SINK_MAX 68 #define SINK_MIN 48 #define SINK_DMIN 12 #define SINK_DMAX 18 #define BITLINE_INF (-64*8) -/* HFC-S USB register access by Control-URSs */ + +/**********/ +/* macros */ +/**********/ #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) + + +/*******************/ +/* Debugging Flags */ +/*******************/ +#define USB_DBG 1 +#define ISDN_DBG 2 + + +/* *********************/ +/* USB related defines */ +/***********************/ #define HFC_CTRL_BUFSIZE 32 + + +/*************************************************/ /* entry and size of output/input control buffer */ +/*************************************************/ typedef struct { __u8 hfc_reg; /* register number */ __u8 reg_val; /* value to be written (or read) */ int action; /* data for action handler */ } ctrl_buft; -/* Debugging Flags */ -#define HFCUSB_DBG_INIT 0x0001 -#define HFCUSB_DBG_STATES 0x0002 -#define HFCUSB_DBG_DCHANNEL 0x0080 -#define HFCUSB_DBG_FIFO_ERR 0x4000 -#define HFCUSB_DBG_VERBOSE_USB 0x8000 -/* - * URB error codes: - * Used to represent a list of values and their respective symbolic names - */ +/********************/ +/* URB error codes: */ +/********************/ +/* Used to represent a list of values and their respective symbolic names */ struct hfcusb_symbolic_list { const int num; const char *name; @@ -115,20 +134,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { {-ENXIO, "URB already queued"}, {-EFBIG, "Too much ISO frames requested"}, {-ENOSR, "Buffer error (overrun)"}, - {-EPIPE, "Specified endpoint is stalled (device not responding)"}, + {-EPIPE, "Specified endpoint is stalled"}, {-EOVERFLOW, "Babble (bad cable?)"}, {-EPROTO, "Bit-stuff error (bad cable?)"}, - {-EILSEQ, "CRC/Timeout"}, - {-ETIMEDOUT, "NAK (device does not respond)"}, + {-EILSEQ, "CRC or missing token"}, + {-ETIME, "Device did not respond"}, {-ESHUTDOWN, "Device unplugged"}, {-1, NULL} }; -/* - * device dependant information to support different - * ISDN Ta's using the HFC-S USB chip - */ +/*****************************************************/ +/* device dependant information to support different */ +/* ISDN Ta's using the HFC-S USB chip */ +/*****************************************************/ /* USB descriptor need to contain one of the following EndPoint combination: */ #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT @@ -136,19 +155,16 @@ static struct hfcusb_symbolic_list urb_errlist[] = { #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position +#define EP_NUL 1 // Endpoint at this position not allowed +#define EP_NOP 2 // all type of endpoints allowed at this position +#define EP_ISO 3 // Isochron endpoint mandatory at this position +#define EP_BLK 4 // Bulk endpoint mandatory at this position +#define EP_INT 5 // Interrupt endpoint mandatory at this position -/* - * List of all supported endpoint configuration sets, used to find the - * best matching endpoint configuration within a devices' USB descriptor. - * We need at least 3 RX endpoints, and 3 TX endpoints, either - * INT-in and ISO-out, or ISO-in and ISO-out) - * with 4 RX endpoints even E-Channel logging is possible - */ +/* this array represents all endpoints possible in the HCF-USB the last +* 3 entries are the configuration number, the minimum interval for +* Interrupt endpoints & boolean if E-channel logging possible +*/ static int validconf[][19] = { // INT in, ISO out config {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, @@ -177,6 +193,7 @@ static char *conf_str[] = { }; #endif + typedef struct { int vendor; // vendor id int prod_id; // product id @@ -185,9 +202,9 @@ typedef struct { signed short led_bits[8]; // array of 8 possible LED bitmask settings } vendor_data; -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... +#define LED_OFF 0 // no LED support +#define LED_SCHEME1 1 // LED standard scheme +#define LED_SCHEME2 2 // not used yet... #define LED_POWER_ON 1 #define LED_POWER_OFF 2 @@ -200,8 +217,11 @@ typedef struct { #define LED_B2_OFF 9 #define LED_B2_DATA 10 -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted +#define LED_NORMAL 0 // LEDs are normal +#define LED_INVERTED 1 // LEDs are inverted + +/* time in ms to perform a Flashing LED when B-Channel has traffic */ +#define LED_TIME 250 -#endif // __HFC_USB_H__ +#endif // __HFC_USB_H__ diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 9293c82ef2af..ef3325b69233 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, obuff_size); + skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 757592436390..e7a2eadcc3b0 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -696,8 +696,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) int i; const u8 *addr = hw->dev[port]->dev_addr; - sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); + sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index d32c60dbdd82..eccac1c3b71b 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "dasd_int.h" #include "dasd_diag.h" diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 2edd5fb6d3dc..4f2f81b16cfa 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "raw3270.h" diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index d70a6e65bf14..04b19bdc09da 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "vmur.h" @@ -69,26 +68,8 @@ static struct ccw_driver ur_driver = { .set_offline = ur_set_offline, }; -static DEFINE_MUTEX(vmur_mutex); - /* * Allocation, freeing, getting and putting of urdev structures - * - * Each ur device (urd) contains a reference to its corresponding ccw device - * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the - * ur device using the cdev->dev.driver_data pointer. - * - * urd references: - * - ur_probe gets a urd reference, ur_remove drops the reference - * (cdev->dev.driver_data) - * - ur_open gets a urd reference, ur_relase drops the reference - * (urf->urd) - * - * cdev references: - * - urdev_alloc get a cdev reference (urd->cdev) - * - urdev_free drops the cdev reference (urd->cdev) - * - * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock */ static struct urdev *urdev_alloc(struct ccw_device *cdev) { @@ -97,61 +78,42 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); if (!urd) return NULL; + urd->cdev = cdev; urd->reclen = cdev->id.driver_info; ccw_device_get_id(cdev, &urd->dev_id); mutex_init(&urd->io_mutex); mutex_init(&urd->open_mutex); - atomic_set(&urd->ref_count, 1); - urd->cdev = cdev; - get_device(&cdev->dev); return urd; } static void urdev_free(struct urdev *urd) { - TRACE("urdev_free: %p\n", urd); - if (urd->cdev) - put_device(&urd->cdev->dev); kfree(urd); } -static void urdev_get(struct urdev *urd) -{ - atomic_inc(&urd->ref_count); -} - -static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) -{ - struct urdev *urd; - unsigned long flags; - - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - urd = cdev->dev.driver_data; - if (urd) - urdev_get(urd); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - return urd; -} - +/* + * This is how the character device driver gets a reference to a + * ur device. When this call returns successfully, a reference has + * been taken (by get_device) on the underlying kobject. The recipient + * of this urdev pointer must eventually drop it with urdev_put(urd) + * which does the corresponding put_device(). + */ static struct urdev *urdev_get_from_devno(u16 devno) { char bus_id[16]; struct ccw_device *cdev; - struct urdev *urd; sprintf(bus_id, "0.0.%04x", devno); cdev = get_ccwdev_by_busid(&ur_driver, bus_id); if (!cdev) return NULL; - urd = urdev_get_from_cdev(cdev); - put_device(&cdev->dev); - return urd; + + return cdev->dev.driver_data; } static void urdev_put(struct urdev *urd) { - if (atomic_dec_and_test(&urd->ref_count)) - urdev_free(urd); + put_device(&urd->cdev->dev); } /* @@ -283,7 +245,6 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } urd = cdev->dev.driver_data; - BUG_ON(!urd); /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); @@ -301,15 +262,9 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, static ssize_t ur_attr_reclen_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct urdev *urd; - int rc; + struct urdev *urd = dev->driver_data; - urd = urdev_get_from_cdev(to_ccwdev(dev)); - if (!urd) - return -ENODEV; - rc = sprintf(buf, "%zu\n", urd->reclen); - urdev_put(urd); - return rc; + return sprintf(buf, "%zu\n", urd->reclen); } static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); @@ -424,6 +379,31 @@ static ssize_t ur_write(struct file *file, const char __user *udata, return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); } +static int do_diag_14(unsigned long rx, unsigned long ry1, + unsigned long subcode) +{ + register unsigned long _ry1 asm("2") = ry1; + register unsigned long _ry2 asm("3") = subcode; + int rc = 0; + + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %2,2,0x14\n" + " sam64\n" +#else + " diag %2,2,0x14\n" +#endif + " ipm %0\n" + " srl %0,28\n" + : "=d" (rc), "+d" (_ry2) + : "d" (rx), "d" (_ry1) + : "cc"); + + TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); + return rc; +} + /* * diagnose code 0x14 subcode 0x0028 - position spool file to designated * record @@ -435,7 +415,7 @@ static int diag_position_to_record(int devno, int record) { int cc; - cc = diag14(record, devno, 0x28); + cc = do_diag_14(record, devno, 0x28); switch (cc) { case 0: return 0; @@ -460,7 +440,7 @@ static int diag_read_file(int devno, char *buf) { int cc; - cc = diag14((unsigned long) buf, devno, 0x00); + cc = do_diag_14((unsigned long) buf, devno, 0x00); switch (cc) { case 0: return 0; @@ -553,7 +533,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) { int cc; - cc = diag14((unsigned long) buf, spid, 0xfff); + cc = do_diag_14((unsigned long) buf, spid, 0xfff); switch (cc) { case 0: return 0; @@ -770,94 +750,86 @@ static struct file_operations ur_fops = { /* * ccw_device infrastructure: - * ur_probe creates the struct urdev (with refcount = 1), the device - * attributes, sets up the interrupt handler and validates the virtual - * unit record device. - * ur_remove removes the device attributes and drops the reference to - * struct urdev. - * - * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized - * by the vmur_mutex lock. - * - * urd->char_device is used as indication that the online function has - * been completed successfully. + * ur_probe gets its own ref to the device (i.e. get_device), + * creates the struct urdev, the device attributes, sets up + * the interrupt handler and validates the virtual unit record device. + * ur_remove removes the device attributes, frees the struct urdev + * and drops (put_device) the ref to the device we got in ur_probe. */ static int ur_probe(struct ccw_device *cdev) { struct urdev *urd; int rc; - TRACE("ur_probe: cdev=%p\n", cdev); + TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); + + if (!get_device(&cdev->dev)) + return -ENODEV; - mutex_lock(&vmur_mutex); urd = urdev_alloc(cdev); if (!urd) { rc = -ENOMEM; - goto fail_unlock; + goto fail; } - rc = ur_create_attributes(&cdev->dev); if (rc) { rc = -ENOMEM; - goto fail_urdev_put; + goto fail; } + cdev->dev.driver_data = urd; cdev->handler = ur_int_handler; /* validate virtual unit record device */ urd->class = get_urd_class(urd); if (urd->class < 0) { rc = urd->class; - goto fail_remove_attr; + goto fail; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { rc = -ENOTSUPP; - goto fail_remove_attr; + goto fail; } - spin_lock_irq(get_ccwdev_lock(cdev)); - cdev->dev.driver_data = urd; - spin_unlock_irq(get_ccwdev_lock(cdev)); - mutex_unlock(&vmur_mutex); return 0; -fail_remove_attr: - ur_remove_attributes(&cdev->dev); -fail_urdev_put: - urdev_put(urd); -fail_unlock: - mutex_unlock(&vmur_mutex); +fail: + urdev_free(urd); + put_device(&cdev->dev); return rc; } +static void ur_remove(struct ccw_device *cdev) +{ + struct urdev *urd = cdev->dev.driver_data; + + TRACE("ur_remove\n"); + if (cdev->online) + ur_set_offline(cdev); + ur_remove_attributes(&cdev->dev); + urdev_free(urd); + put_device(&cdev->dev); +} + static int ur_set_online(struct ccw_device *cdev) { struct urdev *urd; int minor, major, rc; char node_id[16]; - TRACE("ur_set_online: cdev=%p\n", cdev); - - mutex_lock(&vmur_mutex); - urd = urdev_get_from_cdev(cdev); - if (!urd) { - /* ur_remove already deleted our urd */ - rc = -ENODEV; - goto fail_unlock; - } + TRACE("ur_set_online: cdev=%p state=%d\n", cdev, + *(int *) cdev->private); - if (urd->char_device) { - /* Another ur_set_online was faster */ - rc = -EBUSY; - goto fail_urdev_put; - } + if (!try_module_get(ur_driver.owner)) + return -EINVAL; + urd = (struct urdev *) cdev->dev.driver_data; minor = urd->dev_id.devno; major = MAJOR(ur_first_dev_maj_min); urd->char_device = cdev_alloc(); if (!urd->char_device) { rc = -ENOMEM; - goto fail_urdev_put; + goto fail_module_put; } cdev_init(urd->char_device, &ur_fops); @@ -886,79 +858,29 @@ static int ur_set_online(struct ccw_device *cdev) TRACE("ur_set_online: device_create rc=%d\n", rc); goto fail_free_cdev; } - urdev_put(urd); - mutex_unlock(&vmur_mutex); + return 0; fail_free_cdev: cdev_del(urd->char_device); - urd->char_device = NULL; -fail_urdev_put: - urdev_put(urd); -fail_unlock: - mutex_unlock(&vmur_mutex); +fail_module_put: + module_put(ur_driver.owner); + return rc; } -static int ur_set_offline_force(struct ccw_device *cdev, int force) +static int ur_set_offline(struct ccw_device *cdev) { struct urdev *urd; - int rc; - TRACE("ur_set_offline: cdev=%p\n", cdev); - urd = urdev_get_from_cdev(cdev); - if (!urd) - /* ur_remove already deleted our urd */ - return -ENODEV; - if (!urd->char_device) { - /* Another ur_set_offline was faster */ - rc = -EBUSY; - goto fail_urdev_put; - } - if (!force && (atomic_read(&urd->ref_count) > 2)) { - /* There is still a user of urd (e.g. ur_open) */ - TRACE("ur_set_offline: BUSY\n"); - rc = -EBUSY; - goto fail_urdev_put; - } + TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", + cdev, cdev->private, *(int *) cdev->private); + urd = (struct urdev *) cdev->dev.driver_data; device_destroy(vmur_class, urd->char_device->dev); cdev_del(urd->char_device); - urd->char_device = NULL; - rc = 0; - -fail_urdev_put: - urdev_put(urd); - return rc; -} - -static int ur_set_offline(struct ccw_device *cdev) -{ - int rc; - - mutex_lock(&vmur_mutex); - rc = ur_set_offline_force(cdev, 0); - mutex_unlock(&vmur_mutex); - return rc; -} - -static void ur_remove(struct ccw_device *cdev) -{ - unsigned long flags; - - TRACE("ur_remove\n"); + module_put(ur_driver.owner); - mutex_lock(&vmur_mutex); - - if (cdev->online) - ur_set_offline_force(cdev, 1); - ur_remove_attributes(&cdev->dev); - - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - urdev_put(cdev->dev.driver_data); - cdev->dev.driver_data = NULL; - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - - mutex_unlock(&vmur_mutex); + return 0; } /* diff --git a/trunk/drivers/s390/char/vmur.h b/trunk/drivers/s390/char/vmur.h index fa959644735a..2b3c564e0472 100644 --- a/trunk/drivers/s390/char/vmur.h +++ b/trunk/drivers/s390/char/vmur.h @@ -70,7 +70,6 @@ struct urdev { size_t reclen; /* Record length for *write* CCWs */ int class; /* VM device class */ int io_request_rc; /* return code from I/O request */ - atomic_t ref_count; /* reference counter */ }; /* diff --git a/trunk/drivers/s390/cio/cmf.c b/trunk/drivers/s390/cio/cmf.c index 34a796913b06..02fd00b55e1b 100644 --- a/trunk/drivers/s390/cio/cmf.c +++ b/trunk/drivers/s390/cio/cmf.c @@ -594,9 +594,6 @@ alloc_cmb (struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ - printk(KERN_WARNING "cio: failed to allocate area " - "for measuring %d subchannels\n", - cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1282,6 +1279,13 @@ init_cmf(void) case CMF_BASIC: format_string = "basic"; cmbops = &cmbops_basic; + if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { + printk(KERN_ERR "cio: Basic channel measurement " + "facility can only use 1 to 4096 devices\n" + KERN_ERR "when the cmf driver is built" + " as a loadable module\n"); + return 1; + } break; case CMF_EXTENDED: format_string = "extended"; diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index e44d92eac8e9..297659fa0e26 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -117,10 +117,7 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MODALIAS=%s", modalias_buf); - if (ret) - return ret; - envp[i] = NULL; - return 0; + return ret; } struct bus_type ccw_bus_type; diff --git a/trunk/drivers/s390/cio/device_id.c b/trunk/drivers/s390/cio/device_id.c index f232832f2b22..60b9347f7c92 100644 --- a/trunk/drivers/s390/cio/device_id.c +++ b/trunk/drivers/s390/cio/device_id.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "cio.h" #include "cio_debug.h" @@ -25,6 +24,51 @@ #include "device.h" #include "ioasm.h" +/* + * diag210 is used under VM to get information about a virtual device + */ +int +diag210(struct diag210 * addr) +{ + /* + * diag 210 needs its data below the 2GB border, so we + * use a static data area to be sure + */ + static struct diag210 diag210_tmp; + static DEFINE_SPINLOCK(diag210_lock); + unsigned long flags; + int ccode; + + spin_lock_irqsave(&diag210_lock, flags); + diag210_tmp = *addr; + +#ifdef CONFIG_64BIT + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#else + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#endif + + *addr = diag210_tmp; + spin_unlock_irqrestore(&diag210_lock, flags); + + return ccode; +} + /* * Input : * devno - device number @@ -305,3 +349,5 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) break; } } + +EXPORT_SYMBOL(diag210); diff --git a/trunk/drivers/s390/cio/qdio.c b/trunk/drivers/s390/cio/qdio.c index d8d479876ec7..03347aed2b3e 100644 --- a/trunk/drivers/s390/cio/qdio.c +++ b/trunk/drivers/s390/cio/qdio.c @@ -195,8 +195,6 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, again: ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); rc = qdio_check_ccq(q, ccq); - if ((ccq == 96) && (tmp_cnt != *cnt)) - rc = 0; if (rc == 1) { QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); goto again; @@ -742,8 +740,7 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), (QDIO_MAX_BUFFERS_PER_Q-1)); - if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || - (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) + if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) SYNC_MEMORY; check_next: diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 35cdba10411b..c4e15ed1405a 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -275,6 +275,58 @@ static void ehci_work(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_CPU_FREQ + +#include + +static void ehci_cpufreq_pause (struct ehci_hcd *ehci) +{ + unsigned long flags; + + spin_lock_irqsave(&ehci->lock, flags); + if (!ehci->cpufreq_changing++) + qh_inactivate_split_intr_qhs(ehci); + spin_unlock_irqrestore(&ehci->lock, flags); +} + +static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) +{ + unsigned long flags; + + spin_lock_irqsave(&ehci->lock, flags); + if (!--ehci->cpufreq_changing) + qh_reactivate_split_intr_qhs(ehci); + spin_unlock_irqrestore(&ehci->lock, flags); +} + +/* + * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when + * EHCI controllers that don't cache many uframes get delayed trying to + * read main memory during CPU frequency transitions. This can cause + * split interrupt transactions to not be completed in the required uframe. + * This has been observed on the Broadcom/ServerWorks HT1000 controller. + */ +static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, + cpufreq_transition); + + switch (val) { + case CPUFREQ_PRECHANGE: + ehci_cpufreq_pause(ehci); + break; + case CPUFREQ_POSTCHANGE: + ehci_cpufreq_unpause(ehci); + break; + } + return 0; +} + +#endif + +/*-------------------------------------------------------------------------*/ + static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; @@ -408,6 +460,10 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_writel(ehci, 0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&ehci->cpufreq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif /* let companion controllers work when we aren't */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); @@ -513,6 +569,17 @@ static int ehci_init(struct usb_hcd *hcd) } ehci->command = temp; +#ifdef CONFIG_CPU_FREQ + INIT_LIST_HEAD(&ehci->split_intr_qhs); + /* + * If the EHCI controller caches enough uframes, this probably + * isn't needed unless there are so many low/full speed devices + * that the controller's can't cache it all. + */ + ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; + cpufreq_register_notifier(&ehci->cpufreq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +#endif return 0; } diff --git a/trunk/drivers/usb/host/ehci-mem.c b/trunk/drivers/usb/host/ehci-mem.c index 0431397836f6..8816d09903d0 100644 --- a/trunk/drivers/usb/host/ehci-mem.c +++ b/trunk/drivers/usb/host/ehci-mem.c @@ -94,6 +94,9 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); +#ifdef CONFIG_CPU_FREQ + INIT_LIST_HEAD (&qh->split_intr_qhs); +#endif /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index 140bfa423e07..2284028f8aa5 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -312,6 +312,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) struct urb *urb; u32 token = 0; + /* ignore QHs that are currently inactive */ + if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) + break; + qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb; diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index e682f2342ef8..d4a8ace49676 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -479,6 +479,109 @@ static int disable_periodic (struct ehci_hcd *ehci) } /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_CPU_FREQ + +static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + int now; /* current (frame * 8) + uframe */ + int prev_start, next_start; /* uframes from/to split start */ + int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK); + int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8); + int split_duration = end_uframe - start_uframe; + + now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3); + + next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) + % (qh->period << 3); + prev_start = (qh->period << 3) - next_start; + + /* + * Make sure there will be at least one uframe when qh is safe. + */ + if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration)) + /* never safe */ + return -EINVAL; + + /* + * Wait 1 uframe after transaction should have started, to make + * sure controller has time to write back overlay, so we can + * check QTD_STS_STS to see if transaction is in progress. + */ + if ((next_start > ehci->i_thresh) && (prev_start > 1)) + /* safe to set "i" bit if split isn't in progress */ + return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1; + else + return 0; +} + +/* Set inactivate bit for all the split interrupt QHs. */ +static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci) +{ + struct ehci_qh *qh; + int not_done, safe; + u32 inactivate = INACTIVATE_BIT(ehci); + u32 active = ACTIVE_BIT(ehci); + + do { + not_done = 0; + list_for_each_entry(qh, &ehci->split_intr_qhs, + split_intr_qhs) { + if (qh->hw_info1 & inactivate) + /* already off */ + continue; + /* + * To avoid setting "I" after the start split happens, + * don't set it if the QH might be cached in the + * controller. Some HCs (Broadcom/ServerWorks HT1000) + * will stop in the middle of a split transaction when + * the "I" bit is set. + */ + safe = safe_to_modify_i(ehci, qh); + if (safe == 0) { + not_done = 1; + } else if (safe > 0) { + qh->was_active = qh->hw_token & active; + qh->hw_info1 |= inactivate; + } + } + } while (not_done); + wmb(); +} + +static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci) +{ + struct ehci_qh *qh; + u32 token; + int not_done, safe; + u32 inactivate = INACTIVATE_BIT(ehci); + u32 active = ACTIVE_BIT(ehci); + u32 halt = HALT_BIT(ehci); + + do { + not_done = 0; + list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) { + if (!(qh->hw_info1 & inactivate)) /* already on */ + continue; + /* + * Don't reactivate if cached, or controller might + * overwrite overlay after we modify it! + */ + safe = safe_to_modify_i(ehci, qh); + if (safe == 0) { + not_done = 1; + } else if (safe > 0) { + /* See EHCI 1.0 section 4.15.2.4. */ + token = qh->hw_token; + qh->hw_token = (token | halt) & ~active; + wmb(); + qh->hw_info1 &= ~inactivate; + wmb(); + qh->hw_token = (token & ~halt) | qh->was_active; + } + } + } while (not_done); +} +#endif /* periodic schedule slots have iso tds (normal or split) first, then a * sparse tree for active interrupt transfers. @@ -496,6 +599,17 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs); +#ifdef CONFIG_CPU_FREQ + /* + * If low/full speed interrupt QHs are inactive (because of + * cpufreq changing processor speeds), start QH with I flag set-- + * it will automatically be cleared when cpufreq is done. + */ + if (ehci->cpufreq_changing) + if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) + qh->hw_info1 |= INACTIVATE_BIT(ehci); +#endif + /* high bandwidth, or otherwise every microframe */ if (period == 0) period = 1; @@ -544,6 +658,12 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) ? ((qh->usecs + qh->c_usecs) / qh->period) : (qh->usecs * 8); +#ifdef CONFIG_CPU_FREQ + /* add qh to list of low/full speed interrupt QHs, if applicable */ + if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { + list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs); + } +#endif /* maybe enable periodic schedule processing */ if (!ehci->periodic_sched++) return enable_periodic (ehci); @@ -563,6 +683,13 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) // THEN // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); +#ifdef CONFIG_CPU_FREQ + /* remove qh from list of low/full speed interrupt QHs */ + if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { + list_del_init(&qh->split_intr_qhs); + } +#endif + /* high bandwidth, or otherwise part of every microframe */ if ((period = qh->period) == 0) period = 1; diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 951d69fec513..2c68a04230c1 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -71,6 +71,12 @@ struct ehci_hcd { /* one per controller */ __u32 hcs_params; /* cached register copy */ spinlock_t lock; +#ifdef CONFIG_CPU_FREQ + struct notifier_block cpufreq_transition; + int cpufreq_changing; + struct list_head split_intr_qhs; +#endif + /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; @@ -433,6 +439,10 @@ struct ehci_qh { __hc32 hw_next; /* see EHCI 3.6.1 */ __hc32 hw_info1; /* see EHCI 3.6.2 */ #define QH_HEAD 0x00008000 +#define QH_INACTIVATE 0x00000080 + +#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE) + __hc32 hw_info2; /* see EHCI 3.6.2 */ #define QH_SMASK 0x000000ff #define QH_CMASK 0x0000ff00 @@ -482,6 +492,10 @@ struct ehci_qh { unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ +#ifdef CONFIG_CPU_FREQ + struct list_head split_intr_qhs; /* list of split qhs */ + __le32 was_active; /* active bit before "i" set */ +#endif } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ diff --git a/trunk/include/asm-s390/atomic.h b/trunk/include/asm-s390/atomic.h index 2d184655bc5d..ea486952f778 100644 --- a/trunk/include/asm-s390/atomic.h +++ b/trunk/include/asm-s390/atomic.h @@ -67,17 +67,8 @@ typedef struct { #endif /* __GNUC__ */ -static inline int atomic_read(const atomic_t *v) -{ - barrier(); - return v->counter; -} - -static inline void atomic_set(atomic_t *v, int i) -{ - v->counter = i; - barrier(); -} +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) static __inline__ int atomic_add_return(int i, atomic_t * v) { @@ -191,17 +182,8 @@ typedef struct { #endif /* __GNUC__ */ -static inline long long atomic64_read(const atomic64_t *v) -{ - barrier(); - return v->counter; -} - -static inline void atomic64_set(atomic64_t *v, long long i) -{ - v->counter = i; - barrier(); -} +#define atomic64_read(v) ((v)->counter) +#define atomic64_set(v,i) (((v)->counter) = (i)) static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) { diff --git a/trunk/include/asm-s390/cio.h b/trunk/include/asm-s390/cio.h index 1982fb344164..f738d2827582 100644 --- a/trunk/include/asm-s390/cio.h +++ b/trunk/include/asm-s390/cio.h @@ -258,6 +258,19 @@ struct ciw { /* Sick revalidation of device. */ #define CIO_REVALIDATE 0x0008 +struct diag210 { + __u16 vrdcdvno : 16; /* device number (input) */ + __u16 vrdclen : 16; /* data block length (input) */ + __u32 vrdcvcla : 8; /* virtual device class (output) */ + __u32 vrdcvtyp : 8; /* virtual device type (output) */ + __u32 vrdcvsta : 8; /* virtual device status (output) */ + __u32 vrdcvfla : 8; /* virtual device flags (output) */ + __u32 vrdcrccl : 8; /* real device class (output) */ + __u32 vrdccrty : 8; /* real device type (output) */ + __u32 vrdccrmd : 8; /* real device model (output) */ + __u32 vrdccrft : 8; /* real device feature (output) */ +} __attribute__ ((packed,aligned(4))); + struct ccw_dev_id { u8 ssid; u16 devno; @@ -272,6 +285,8 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } +extern int diag210(struct diag210 *addr); + extern void wait_cons_dev(void); extern void css_schedule_reprobe(void); diff --git a/trunk/include/asm-s390/diag.h b/trunk/include/asm-s390/diag.h deleted file mode 100644 index 72b2e2f2d32d..000000000000 --- a/trunk/include/asm-s390/diag.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * s390 diagnose functions - * - * Copyright IBM Corp. 2007 - * Author(s): Michael Holzheu - */ - -#ifndef _ASM_S390_DIAG_H -#define _ASM_S390_DIAG_H - -/* - * Diagnose 10: Release pages - */ -extern void diag10(unsigned long addr); - -/* - * Diagnose 14: Input spool file manipulation - */ -extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); - -/* - * Diagnose 210: Get information about a virtual device - */ -struct diag210 { - u16 vrdcdvno; /* device number (input) */ - u16 vrdclen; /* data block length (input) */ - u8 vrdcvcla; /* virtual device class (output) */ - u8 vrdcvtyp; /* virtual device type (output) */ - u8 vrdcvsta; /* virtual device status (output) */ - u8 vrdcvfla; /* virtual device flags (output) */ - u8 vrdcrccl; /* real device class (output) */ - u8 vrdccrty; /* real device type (output) */ - u8 vrdccrmd; /* real device model (output) */ - u8 vrdccrft; /* real device feature (output) */ -} __attribute__((packed, aligned(4))); - -extern int diag210(struct diag210 *addr); - -#endif /* _ASM_S390_DIAG_H */ diff --git a/trunk/include/asm-s390/pgalloc.h b/trunk/include/asm-s390/pgalloc.h index e45d3c9a4b7e..56c8a6c80e2e 100644 --- a/trunk/include/asm-s390/pgalloc.h +++ b/trunk/include/asm-s390/pgalloc.h @@ -19,6 +19,8 @@ #define check_pgt_cache() do {} while (0) +extern void diag10(unsigned long addr); + /* * Page allocation orders. */ diff --git a/trunk/include/asm-sparc64/percpu.h b/trunk/include/asm-sparc64/percpu.h index caf8750792ff..a1f53a4da405 100644 --- a/trunk/include/asm-sparc64/percpu.h +++ b/trunk/include/asm-sparc64/percpu.h @@ -3,6 +3,8 @@ #include +register unsigned long __local_per_cpu_offset asm("g5"); + #ifdef CONFIG_SMP #define setup_per_cpu_areas() do { } while (0) @@ -23,8 +25,6 @@ extern unsigned long __per_cpu_shift; __typeof__(type) per_cpu__##name \ ____cacheline_aligned_in_smp -register unsigned long __local_per_cpu_offset asm("g5"); - /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset)) diff --git a/trunk/include/asm-sparc64/system.h b/trunk/include/asm-sparc64/system.h index 64891cb10f05..3f175fa7e6d2 100644 --- a/trunk/include/asm-sparc64/system.h +++ b/trunk/include/asm-sparc64/system.h @@ -141,7 +141,6 @@ do { \ * not preserve it's value. Hairy, but it lets us remove 2 loads * and 2 stores in this critical code path. -DaveM */ -#define EXTRA_CLOBBER ,"%l1" #define switch_to(prev, next, last) \ do { if (test_thread_flag(TIF_PERFCTR)) { \ unsigned long __tmp; \ @@ -164,33 +163,34 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ "rdpr %%wstate, %%o5\n\t" \ - "stx %%o6, [%%g6 + %3]\n\t" \ - "stb %%o5, [%%g6 + %2]\n\t" \ - "rdpr %%cwp, %%o5\n\t" \ + "stx %%o6, [%%g6 + %6]\n\t" \ "stb %%o5, [%%g6 + %5]\n\t" \ - "mov %1, %%g6\n\t" \ - "ldub [%1 + %5], %%g1\n\t" \ + "rdpr %%cwp, %%o5\n\t" \ + "stb %%o5, [%%g6 + %8]\n\t" \ + "mov %4, %%g6\n\t" \ + "ldub [%4 + %8], %%g1\n\t" \ "wrpr %%g1, %%cwp\n\t" \ - "ldx [%%g6 + %3], %%o6\n\t" \ - "ldub [%%g6 + %2], %%o5\n\t" \ - "ldub [%%g6 + %4], %%o7\n\t" \ + "ldx [%%g6 + %6], %%o6\n\t" \ + "ldub [%%g6 + %5], %%o5\n\t" \ + "ldub [%%g6 + %7], %%o7\n\t" \ "wrpr %%o5, 0x0, %%wstate\n\t" \ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ - "ldx [%%g6 + %6], %%g4\n\t" \ + "ldx [%%g6 + %9], %%g4\n\t" \ "brz,pt %%o7, 1f\n\t" \ " mov %%g7, %0\n\t" \ "b,a ret_from_syscall\n\t" \ "1:\n\t" \ - : "=&r" (last) \ + : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \ + "=r" (__local_per_cpu_offset) \ : "0" (task_thread_info(next)), \ "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ "i" (TI_CWP), "i" (TI_TASK) \ : "cc", \ "g1", "g2", "g3", "g7", \ - "l2", "l3", "l4", "l5", "l6", "l7", \ + "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ "i0", "i1", "i2", "i3", "i4", "i5", \ - "o0", "o1", "o2", "o3", "o4", "o5", "o7" EXTRA_CLOBBER);\ + "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ /* If you fuck with this, update ret_from_syscall code too. */ \ if (test_thread_flag(TIF_PERFCTR)) { \ write_pcr(current_thread_info()->pcr_reg); \ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 8938d59013c6..07fc57429b58 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2092,10 +2092,8 @@ #define PCI_DEVICE_ID_MPC8568 0x0021 #define PCI_DEVICE_ID_MPC8567E 0x0022 #define PCI_DEVICE_ID_MPC8567 0x0023 -#define PCI_DEVICE_ID_MPC8533E 0x0030 -#define PCI_DEVICE_ID_MPC8533 0x0031 -#define PCI_DEVICE_ID_MPC8544E 0x0032 -#define PCI_DEVICE_ID_MPC8544 0x0033 +#define PCI_DEVICE_ID_MPC8544E 0x0030 +#define PCI_DEVICE_ID_MPC8544 0x0031 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 8451dfc31d25..5c7c325b29cc 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -1085,12 +1085,10 @@ EXPORT_SYMBOL(unregister_console); static int __init disable_boot_consoles(void) { - if (console_drivers != NULL) { - if (console_drivers->flags & CON_BOOT) { - printk(KERN_INFO "turn off boot console %s%d\n", - console_drivers->name, console_drivers->index); - return unregister_console(console_drivers); - } + if (console_drivers->flags & CON_BOOT) { + printk(KERN_INFO "turn off boot console %s%d\n", + console_drivers->name, console_drivers->index); + return unregister_console(console_drivers); } return 0; } diff --git a/trunk/net/802/psnap.c b/trunk/net/802/psnap.c index 31128cb92a23..04ee43e7538f 100644 --- a/trunk/net/802/psnap.c +++ b/trunk/net/802/psnap.c @@ -55,9 +55,6 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, .type = __constant_htons(ETH_P_SNAP), }; - if (unlikely(!pskb_may_pull(skb, 5))) - goto drop; - rcu_read_lock(); proto = find_snap_client(skb_transport_header(skb)); if (proto) { @@ -65,18 +62,14 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, skb->transport_header += 5; skb_pull_rcsum(skb, 5); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); + } else { + skb->sk = NULL; + kfree_skb(skb); + rc = 1; } - rcu_read_unlock(); - - if (unlikely(!proto)) - goto drop; -out: + rcu_read_unlock(); return rc; - -drop: - kfree_skb(skb); - goto out; } /* diff --git a/trunk/net/dccp/ccids/ccid2.c b/trunk/net/dccp/ccids/ccid2.c index d29b88fe723c..248d20f4c7c4 100644 --- a/trunk/net/dccp/ccids/ccid2.c +++ b/trunk/net/dccp/ccids/ccid2.c @@ -298,7 +298,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) int rc; ccid2_pr_debug("allocating more space in history\n"); - rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any()); + rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); BUG_ON(rc); /* XXX what do we do? */ next = hctx->ccid2hctx_seqh->ccid2s_next; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 5dead399fe64..50d86e94d9ed 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -794,7 +794,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* * Copy a block of the IP datagram. */ - if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len)) + if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len)) BUG(); left -= len; diff --git a/trunk/net/irda/irmod.c b/trunk/net/irda/irmod.c index 8ba703da2797..1900937b3328 100644 --- a/trunk/net/irda/irmod.c +++ b/trunk/net/irda/irmod.c @@ -128,8 +128,8 @@ static int __init irda_init(void) out_err_3: #ifdef CONFIG_SYSCTL irda_sysctl_unregister(); - out_err_2: #endif + out_err_2: #ifdef CONFIG_PROC_FS irda_proc_unregister(); #endif diff --git a/trunk/net/irda/irnetlink.c b/trunk/net/irda/irnetlink.c index 1e429c929739..694ea4d92fa8 100644 --- a/trunk/net/irda/irnetlink.c +++ b/trunk/net/irda/irnetlink.c @@ -106,7 +106,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) } if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME, - dev->name)) + dev->name)); goto err_out; if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))