From: Stefan Richter Date: Mon, 2 Aug 2010 07:33:25 +0000 (+0200) Subject: Merge firewire branches to be released post v2.6.35 X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e78483c5aeb0d7fbb0e365802145f1045e62957e;p=openwrt%2Fstaging%2Fblogic.git Merge firewire branches to be released post v2.6.35 Conflicts: drivers/firewire/core-card.c drivers/firewire/core-cdev.c and forgotten #include in drivers/firewire/ohci.c Signed-off-by: Stefan Richter --- e78483c5aeb0d7fbb0e365802145f1045e62957e diff --cc MAINTAINERS index 02f75fccac20,70c9938f3f3e,2533fc45a44a..ac2ea0aada85 --- a/MAINTAINERS +++ b/MAINTAINERS @@@@ -971,28 -970,16 -950,6 +971,28 @@@@ M: Wan ZongShun +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Supported +F: arch/arm/mach-u300/ +F: drivers/i2c/busses/i2c-stu300.c +F: drivers/rtc/rtc-coh901331.c +F: drivers/watchdog/coh901327_wdt.c +F: drivers/dma/coh901318* ARM/U8500 ARM ARCHITECTURE M: Srinidhi Kasagar @@@@ -1007,27 -994,13 -964,6 +1007,27 @@@@ W: http://www.arm.linux.org.uk S: Maintained F: arch/arm/vfp/ ++ARM/VOIPAC PXA270 SUPPORT ++M: Marek Vasut ++L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ++S: Maintained ++F: arch/arm/mach-pxa/vpac270.c ++F: arch/arm/mach-pxa/include/mach-pxa/vpac270.h ++ ++ARM/ZIPIT Z2 SUPPORT ++M: Marek Vasut ++L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ++S: Maintained ++F: arch/arm/mach-pxa/z2.c ++F: arch/arm/mach-pxa/include/mach-pxa/z2.h ++ +ASC7621 HARDWARE MONITOR DRIVER +M: George Joseph +L: lm-sensors@lm-sensors.org +S: Maintained +F: Documentation/hwmon/asc7621 +F: drivers/hwmon/asc7621.c + ASUS ACPI EXTRAS DRIVER M: Corentin Chary M: Karol Kozimor @@@@ -1583,10 -1555,10 -1488,9 +1583,10 @@@@ F: include/linux/coda*. COMMON INTERNET FILE SYSTEM (CIFS) M: Steve French --L: linux-cifs-client@lists.samba.org (moderated for non-subscribers) ++L: linux-cifs@vger.kernel.org L: samba-technical@lists.samba.org (moderated for non-subscribers) W: http://linux-cifs.samba.org/ +Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git S: Supported F: Documentation/filesystems/cifs.txt @@@@ -2898,22 -2851,8 -2756,8 +2899,22 @@@@ T: git git://git.kernel.org/pub/scm/lin S: Maintained F: drivers/input/ ++INPUT MULTITOUCH (MT) PROTOCOL ++M: Henrik Rydberg ++L: linux-input@vger.kernel.org ++S: Maintained ++F: Documentation/input/multi-touch-protocol.txt ++K: \b(ABS|SYN)_MT_ ++ ++INTEL IDLE DRIVER ++M: Len Brown ++L: linux-pm@lists.linux-foundation.org ++T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git ++S: Supported ++F: drivers/idle/intel_idle.c ++ INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) -M: Sylvain Meyer +M: Maik Broemme L: linux-fbdev@vger.kernel.org S: Maintained F: Documentation/fb/intelfb.txt @@@@ -3166,15 -3104,15 -3008,8 +3167,15 @@@@ W: http://www.melware.d S: Maintained F: drivers/isdn/hardware/eicon/ +IT87 HARDWARE MONITORING DRIVER +M: Jean Delvare +L: lm-sensors@lm-sensors.org +S: Maintained +F: Documentation/hwmon/it87 +F: drivers/hwmon/it87.c + IVTV VIDEO4LINUX DRIVER --M: Andy Walls ++M: Andy Walls L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) L: linux-media@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git @@@@ -3340,19 -3275,18 -3171,8 +3341,19 @@@@ S: Maintaine F: include/linux/kexec.h F: kernel/kexec.c -KGDB +KEYS/KEYRINGS: +M: David Howells +L: keyrings@linux-nfs.org +S: Maintained +F: Documentation/keys.txt +F: include/linux/key.h +F: include/linux/key-type.h +F: include/keys/ +F: security/keys/ + - KGDB ++KGDB / KDB /debug_core M: Jason Wessel ++W: http://kgdb.wiki.kernel.org/ L: kgdb-bugreport@lists.sourceforge.net S: Maintained F: Documentation/DocBook/kgdb.tmpl @@@@ -4421,15 -4352,15 -4221,12 +4422,15 @@@@ PERFORMANCE EVENTS SUBSYSTE M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar +M: Arnaldo Carvalho de Melo S: Supported --F: kernel/perf_event.c ++F: kernel/perf_event*.c F: include/linux/perf_event.h - F: arch/*/kernel/perf_event.c - F: arch/*/kernel/*/perf_event.c - F: arch/*/kernel/*/*/perf_event.c -F: arch/*/*/kernel/perf_event.c ++F: arch/*/kernel/perf_event*.c ++F: arch/*/kernel/*/perf_event*.c ++F: arch/*/kernel/*/*/perf_event*.c F: arch/*/include/asm/perf_event.h --F: arch/*/lib/perf_event.c ++F: arch/*/lib/perf_event*.c F: arch/*/kernel/perf_callchain.c F: tools/perf/ @@@@ -4669,14 -4586,13 -4445,6 +4670,14 @@@@ S: Supporte F: Documentation/networking/LICENSE.qla3xxx F: drivers/net/qla3xxx.* +QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER +M: Amit Kumar Salecha ++M: Anirban Chakraborty +M: linux-driver@qlogic.com +L: netdev@vger.kernel.org +S: Supported +F: drivers/net/qlcnic/ + QLOGIC QLGE 10Gb ETHERNET DRIVER M: Ron Mercer M: linux-driver@qlogic.com @@@@ -5336,63 -5237,22 -5077,7 +5337,63 @@@@ T: git git://git.kernel.org/pub/scm/lin T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git S: Maintained F: arch/sparc/ ++F: drivers/sbus + +SPARC SERIAL DRIVERS +M: "David S. Miller" +L: sparclinux@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git +S: Maintained +F: drivers/serial/suncore.c +F: drivers/serial/suncore.h +F: drivers/serial/sunhv.c +F: drivers/serial/sunsab.c +F: drivers/serial/sunsab.h +F: drivers/serial/sunsu.c +F: drivers/serial/sunzilog.c +F: drivers/serial/sunzilog.h + ++SPEAR PLATFORM SUPPORT ++M: Viresh Kumar ++W: http://www.st.com/spear ++S: Maintained ++F: arch/arm/plat-spear/ ++ ++SPEAR3XX MACHINE SUPPORT ++M: Viresh Kumar ++W: http://www.st.com/spear ++S: Maintained ++F: arch/arm/mach-spear3xx/ ++ ++SPEAR6XX MACHINE SUPPORT ++M: Rajeev Kumar ++W: http://www.st.com/spear ++S: Maintained ++F: arch/arm/mach-spear6xx/ ++ ++SPEAR CLOCK FRAMEWORK SUPPORT ++M: Viresh Kumar ++W: http://www.st.com/spear ++S: Maintained ++F: arch/arm/mach-spear*/clock.c ++F: arch/arm/mach-spear*/include/mach/clkdev.h ++F: arch/arm/plat-spear/clock.c ++F: arch/arm/plat-spear/include/plat/clock.h and clkdev.h ++ ++SPEAR PAD MULTIPLEXING SUPPORT ++M: Viresh Kumar ++W: http://www.st.com/spear ++S: Maintained ++F: arch/arm/plat-spear/include/plat/padmux.h ++F: arch/arm/plat-spear/padmux.c ++F: arch/arm/mach-spear*/spear*xx.c ++F: arch/arm/mach-spear*/include/mach/generic.h ++F: arch/arm/mach-spear3xx/spear3*0.c ++F: arch/arm/mach-spear3xx/spear3*0_evb.c ++F: arch/arm/mach-spear6xx/spear600.c ++F: arch/arm/mach-spear6xx/spear600_evb.c + SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER M: Roger Wolff S: Supported @@@@ -5403,8 -5263,7 -5088,6 +5404,8 @@@@ SPI SUBSYSTE M: David Brownell M: Grant Likely L: spi-devel-general@lists.sourceforge.net +Q: http://patchwork.kernel.org/project/spi-devel-general/list/ ++T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: Documentation/spi/ F: drivers/spi/ diff --cc drivers/firewire/core-card.c index 371713ff0266,5045156c5313,417b8a4b1af1..be0492398ef9 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@@@ -228,23 -228,22 -273,21 +273,22 @@@@ void fw_schedule_bm_work(struct fw_car fw_card_put(card); } -- static void fw_card_bm_work(struct work_struct *work) ++ static void bm_work(struct work_struct *work) { -- struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root_device; ++ struct fw_card *card = container_of(work, struct fw_card, bm_work.work); - struct fw_device *root_device; ++ struct fw_device *root_device, *irm_device; struct fw_node *root_node; -- unsigned long flags; -- int root_id, new_root_id, irm_id, local_id; ++ int root_id, new_root_id, irm_id, bm_id, local_id; int gap_count, generation, grace, rcode; bool do_reset = false; bool root_device_is_running; bool root_device_is_cmc; ++ bool irm_is_1394_1995_only; -- spin_lock_irqsave(&card->lock, flags); ++ spin_lock_irq(&card->lock); if (card->local_node == NULL) { -- spin_unlock_irqrestore(&card->lock, flags); ++ spin_unlock_irq(&card->lock); goto out_put_card; } @@@@ -310,9 -296,9 -340,15 +354,15 @@@@ /* Another bus reset, BM work has been rescheduled. */ goto out; -- if (rcode == RCODE_COMPLETE && -- card->bm_transaction_data[0] != cpu_to_be32(0x3f)) { ++ bm_id = be32_to_cpu(card->bm_transaction_data[0]); + ++ spin_lock_irq(&card->lock); ++ if (rcode == RCODE_COMPLETE && generation == card->generation) ++ card->bm_node_id = ++ bm_id == 0x3f ? local_id : 0xffc0 | bm_id; ++ spin_unlock_irq(&card->lock); + ++ if (rcode == RCODE_COMPLETE && bm_id != 0x3f) { /* Somebody else is BM. Only act as IRM. */ if (local_id == irm_id) allocate_broadcast_channel(card, generation); @@@@ -438,7 -431,9 -500,8 +514,8 @@@@ void fw_card_initialize(struct fw_card kref_init(&card->kref); init_completion(&card->done); INIT_LIST_HEAD(&card->transaction_list); ++ INIT_LIST_HEAD(&card->phy_receiver_list); spin_lock_init(&card->lock); - setup_timer(&card->flush_timer, - flush_timer_callback, (unsigned long)card); card->local_node = NULL; @@@@ -563,14 -558,15 -644,5 +658,5 @@@@ void fw_core_remove_card(struct fw_car wait_for_completion(&card->done); WARN_ON(!list_empty(&card->transaction_list)); - del_timer_sync(&card->flush_timer); } EXPORT_SYMBOL(fw_core_remove_card); -- -- int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset) -- { -- int reg = short_reset ? 5 : 1; -- int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET; -- -- return card->driver->update_phy_reg(card, reg, 0, bit); -- } -- EXPORT_SYMBOL(fw_core_initiate_bus_reset); diff --cc drivers/firewire/core-cdev.c index 5bf106b9d791,14a34d99eea2,ba23646bb108..14bb7b7b5dd7 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@@@ -33,8 -33,8 -34,7 +34,8 @@@@ #include #include #include -- #include ++ #include /* required for linux/wait.h */ +#include #include #include #include @@@@ -959,23 -959,23 -1084,24 +1085,24 @@@@ static int ioctl_queue_iso(struct clien u.packet.sy = GET_SY(control); u.packet.header_length = GET_HEADER_LENGTH(control); -- if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { -- if (u.packet.header_length % 4 != 0) ++ switch (ctx->type) { ++ case FW_ISO_CONTEXT_TRANSMIT: ++ if (u.packet.header_length & 3) + return -EINVAL; - header_length = u.packet.header_length; - } else { - /* - * We require that header_length is a multiple of - * the fixed header size, ctx->header_size. - */ - if (ctx->header_size == 0) { - if (u.packet.header_length > 0) - return -EINVAL; - } else if (u.packet.header_length == 0 || - u.packet.header_length % ctx->header_size != 0) { ++ transmit_header_bytes = u.packet.header_length; ++ break; ++ ++ case FW_ISO_CONTEXT_RECEIVE: ++ if (u.packet.header_length == 0 || ++ u.packet.header_length % ctx->header_size != 0) + return -EINVAL; - header_length = u.packet.header_length; - } else { - /* - * We require that header_length is a multiple of - * the fixed header size, ctx->header_size. - */ - if (ctx->header_size == 0) { - if (u.packet.header_length > 0) - return -EINVAL; - } else if (u.packet.header_length == 0 || - u.packet.header_length % ctx->header_size != 0) { ++ break; ++ ++ case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL: ++ if (u.packet.payload_length == 0 || ++ u.packet.payload_length & 3) return -EINVAL; -- } -- header_length = 0; ++ break; } next = (struct fw_cdev_iso_packet __user *) diff --cc drivers/firewire/ohci.c index 9f627e758cfc,94b16e0340ae,4bda1c1b74ba..7f03540cabe8 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@@@ -32,11 -32,11 -34,11 +33,13 @@@@ #include #include #include ++ #include #include #include +#include #include #include +++#include #include #include @@@@ -236,17 -236,15 -247,19 +248,19 @@@@ static char ohci_driver_name[] = KBUILD #define QUIRK_CYCLE_TIMER 1 #define QUIRK_RESET_PACKET 2 #define QUIRK_BE_HEADERS 4 + #define QUIRK_NO_1394A 8 ++ #define QUIRK_NO_MSI 16 /* In case of multiple matches in ohci_quirks[], only the first one is used. */ static const struct { unsigned short vendor, device, flags; } ohci_quirks[] = { {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | - QUIRK_RESET_PACKET}, + QUIRK_RESET_PACKET | + QUIRK_NO_1394A}, {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, ++ {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, @@@@ -259,9 -257,10 -272,10 +273,10 @@@@ MODULE_PARM_DESC(quirks, "Chip quirks ( ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) + ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) ++ ", disable MSI = " __stringify(QUIRK_NO_MSI) ")"); - #ifdef CONFIG_FIREWIRE_OHCI_DEBUG - #define OHCI_PARAM_DEBUG_AT_AR 1 #define OHCI_PARAM_DEBUG_SELFIDS 2 #define OHCI_PARAM_DEBUG_IRQS 4 @@@@ -464,73 -460,29 -480,101 +481,101 @@@@ static inline void flush_writes(const s reg_read(ohci, OHCI1394_Version); } - static int ohci_update_phy_reg(struct fw_card *card, int addr, - int clear_bits, int set_bits) + static int read_phy_reg(struct fw_ohci *ohci, int addr) { - struct fw_ohci *ohci = fw_ohci(card); - u32 val, old; + u32 val; + int i; reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); - for (i = 0; i < 10; i++) { - flush_writes(ohci); - msleep(2); - val = reg_read(ohci, OHCI1394_PhyControl); - if ((val & OHCI1394_PhyControl_ReadDone) == 0) { - fw_error("failed to set phy reg bits.\n"); - return -EBUSY; ++ for (i = 0; i < 3 + 100; i++) { + val = reg_read(ohci, OHCI1394_PhyControl); + if (val & OHCI1394_PhyControl_ReadDone) + return OHCI1394_PhyControl_ReadData(val); + - msleep(1); ++ /* ++ * Try a few times without waiting. Sleeping is necessary ++ * only when the link/PHY interface is busy. ++ */ ++ if (i >= 3) ++ msleep(1); } + fw_error("failed to read phy reg\n"); + + return -EBUSY; + } + + static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) + { + int i; - old = OHCI1394_PhyControl_ReadData(val); - old = (old & ~clear_bits) | set_bits; reg_write(ohci, OHCI1394_PhyControl, - OHCI1394_PhyControl_Write(addr, old)); + OHCI1394_PhyControl_Write(addr, val)); - for (i = 0; i < 100; i++) { ++ for (i = 0; i < 3 + 100; i++) { + val = reg_read(ohci, OHCI1394_PhyControl); + if (!(val & OHCI1394_PhyControl_WritePending)) + return 0; - msleep(1); - return 0; ++ if (i >= 3) ++ msleep(1); + } + fw_error("failed to write phy reg\n"); + + return -EBUSY; + } + - static int ohci_update_phy_reg(struct fw_card *card, int addr, - int clear_bits, int set_bits) ++ static int update_phy_reg(struct fw_ohci *ohci, int addr, ++ int clear_bits, int set_bits) + { - struct fw_ohci *ohci = fw_ohci(card); - int ret; - - ret = read_phy_reg(ohci, addr); ++ int ret = read_phy_reg(ohci, addr); + if (ret < 0) + return ret; + + /* + * The interrupt status bits are cleared by writing a one bit. + * Avoid clearing them unless explicitly requested in set_bits. + */ + if (addr == 5) + clear_bits |= PHY_INT_STATUS_BITS; + + return write_phy_reg(ohci, addr, (ret & ~clear_bits) | set_bits); + } + + static int read_paged_phy_reg(struct fw_ohci *ohci, int page, int addr) + { + int ret; + - ret = ohci_update_phy_reg(&ohci->card, 7, PHY_PAGE_SELECT, page << 5); ++ ret = update_phy_reg(ohci, 7, PHY_PAGE_SELECT, page << 5); + if (ret < 0) + return ret; + + return read_phy_reg(ohci, addr); + } + ++ static int ohci_read_phy_reg(struct fw_card *card, int addr) ++ { ++ struct fw_ohci *ohci = fw_ohci(card); ++ int ret; ++ ++ mutex_lock(&ohci->phy_reg_mutex); ++ ret = read_phy_reg(ohci, addr); ++ mutex_unlock(&ohci->phy_reg_mutex); ++ ++ return ret; ++ } ++ ++ static int ohci_update_phy_reg(struct fw_card *card, int addr, ++ int clear_bits, int set_bits) ++ { ++ struct fw_ohci *ohci = fw_ohci(card); ++ int ret; ++ ++ mutex_lock(&ohci->phy_reg_mutex); ++ ret = update_phy_reg(ohci, addr, clear_bits, set_bits); ++ mutex_unlock(&ohci->phy_reg_mutex); ++ ++ return ret; + } + static int ar_context_add_page(struct ar_context *ctx) { struct device *dev = ctx->ohci->card.device; @@@@ -1543,64 -1495,13 -1675,64 +1681,64 @@@@ static void copy_config_rom(__be32 *des memset(&dest[length], 0, CONFIG_ROM_SIZE - size); } + static int configure_1394a_enhancements(struct fw_ohci *ohci) + { + bool enable_1394a; + int ret, clear, set, offset; + + /* Check if the driver should configure link and PHY. */ + if (!(reg_read(ohci, OHCI1394_HCControlSet) & + OHCI1394_HCControl_programPhyEnable)) + return 0; + + /* Paranoia: check whether the PHY supports 1394a, too. */ + enable_1394a = false; + ret = read_phy_reg(ohci, 2); + if (ret < 0) + return ret; + if ((ret & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { + ret = read_paged_phy_reg(ohci, 1, 8); + if (ret < 0) + return ret; + if (ret >= 1) + enable_1394a = true; + } + + if (ohci->quirks & QUIRK_NO_1394A) + enable_1394a = false; + + /* Configure PHY and link consistently. */ + if (enable_1394a) { + clear = 0; + set = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; + } else { + clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; + set = 0; + } - ret = ohci_update_phy_reg(&ohci->card, 5, clear, set); ++ ret = update_phy_reg(ohci, 5, clear, set); + if (ret < 0) + return ret; + + if (enable_1394a) + offset = OHCI1394_HCControlSet; + else + offset = OHCI1394_HCControlClear; + reg_write(ohci, offset, OHCI1394_HCControl_aPhyEnhanceEnable); + + /* Clean up: configuration has been taken care of. */ + reg_write(ohci, OHCI1394_HCControlClear, + OHCI1394_HCControl_programPhyEnable); + + return 0; + } + static int ohci_enable(struct fw_card *card, const __be32 *config_rom, size_t length) { struct fw_ohci *ohci = fw_ohci(card); struct pci_dev *dev = to_pci_dev(card->device); -- u32 lps; - int i; ++ u32 lps, seconds, version, irqs; + int i, ret; if (software_reset(ohci)) { fw_error("Failed to reset ohci card.\n"); @@@@ -1653,25 -1554,21 -1802,15 +1808,15 @@@@ reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); reg_write(ohci, OHCI1394_IntEventClear, ~0); reg_write(ohci, OHCI1394_IntMaskClear, ~0); -- reg_write(ohci, OHCI1394_IntMaskSet, -- OHCI1394_selfIDComplete | -- OHCI1394_RQPkt | OHCI1394_RSPkt | -- OHCI1394_reqTxComplete | OHCI1394_respTxComplete | -- OHCI1394_isochRx | OHCI1394_isochTx | -- OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | -- OHCI1394_cycleInconsistent | OHCI1394_regAccessFail | -- OHCI1394_masterIntEnable); -- if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) -- reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); + + ret = configure_1394a_enhancements(ohci); + if (ret < 0) + return ret; /* Activate link_on bit and contender bit in our self ID packets.*/ - if (ohci_update_phy_reg(card, 4, 0, - PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) - return -EIO; + ret = ohci_update_phy_reg(card, 4, 0, PHY_LINK_ACTIVE | PHY_CONTENDER); + if (ret < 0) + return ret; /* * When the link is not yet enabled, the atomic config rom @@@@ -2052,42 -1949,42 -2292,62 +2298,62 @@@@ static struct fw_iso_context *ohci_allo int type, int channel, size_t header_size) { struct fw_ohci *ohci = fw_ohci(card); -- struct iso_context *ctx, *list; -- descriptor_callback_t callback; -- u64 *channels, dont_care = ~0ULL; -- u32 *mask, regs; ++ struct iso_context *uninitialized_var(ctx); ++ descriptor_callback_t uninitialized_var(callback); ++ u64 *uninitialized_var(channels); ++ u32 *uninitialized_var(mask), uninitialized_var(regs); unsigned long flags; -- int index, ret = -ENOMEM; ++ int index, ret = -EBUSY; + - if (type == FW_ISO_CONTEXT_TRANSMIT) { - channels = &dont_care; - mask = &ohci->it_context_mask; - list = ohci->it_context_list; ++ spin_lock_irqsave(&ohci->lock, flags); + - if (type == FW_ISO_CONTEXT_TRANSMIT) { - channels = &dont_care; - mask = &ohci->it_context_mask; - list = ohci->it_context_list; ++ switch (type) { ++ case FW_ISO_CONTEXT_TRANSMIT: ++ mask = &ohci->it_context_mask; callback = handle_it_packet; -- } else { ++ index = ffs(*mask) - 1; ++ if (index >= 0) { ++ *mask &= ~(1 << index); ++ regs = OHCI1394_IsoXmitContextBase(index); ++ ctx = &ohci->it_context_list[index]; ++ } ++ break; ++ ++ case FW_ISO_CONTEXT_RECEIVE: channels = &ohci->ir_context_channels; -- mask = &ohci->ir_context_mask; -- list = ohci->ir_context_list; ++ mask = &ohci->ir_context_mask; callback = handle_ir_packet_per_buffer; -- } ++ index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1; ++ if (index >= 0) { ++ *channels &= ~(1ULL << channel); ++ *mask &= ~(1 << index); ++ regs = OHCI1394_IsoRcvContextBase(index); ++ ctx = &ohci->ir_context_list[index]; ++ } ++ break; -- spin_lock_irqsave(&ohci->lock, flags); -- index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1; -- if (index >= 0) { -- *channels &= ~(1ULL << channel); -- *mask &= ~(1 << index); ++ case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL: ++ mask = &ohci->ir_context_mask; ++ callback = handle_ir_buffer_fill; ++ index = !ohci->mc_allocated ? ffs(*mask) - 1 : -1; ++ if (index >= 0) { ++ ohci->mc_allocated = true; ++ *mask &= ~(1 << index); ++ regs = OHCI1394_IsoRcvContextBase(index); ++ ctx = &ohci->ir_context_list[index]; ++ } ++ break; ++ ++ default: ++ index = -1; ++ ret = -ENOSYS; } ++ spin_unlock_irqrestore(&ohci->lock, flags); if (index < 0) -- return ERR_PTR(-EBUSY); - - if (type == FW_ISO_CONTEXT_TRANSMIT) - regs = OHCI1394_IsoXmitContextBase(index); - else - regs = OHCI1394_IsoRcvContextBase(index); ++ return ERR_PTR(ret); - if (type == FW_ISO_CONTEXT_TRANSMIT) - regs = OHCI1394_IsoXmitContextBase(index); - else - regs = OHCI1394_IsoRcvContextBase(index); - -- ctx = &list[index]; memset(ctx, 0, sizeof(*ctx)); ctx->header_length = 0; ctx->header = (void *) __get_free_page(GFP_KERNEL);