提交 aa77677e 编写于 作者: L Linus Torvalds

Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1519 commits)
  staging: et131x: Remove redundant check and return statement
  staging: et131x: Mainly whitespace changes to appease checkpatch
  staging: et131x: Remove last of the forward declarations
  staging: et131x: Remove even more forward declarations
  staging: et131x: Remove yet more forward declarations
  staging: et131x: Remove more forward declarations
  staging: et131x: Remove forward declaration of et131x_adapter_setup
  staging: et131x: Remove some forward declarations
  staging: et131x: Remove unused rx_ring.recv_packet_pool
  staging: et131x: Remove call to find pci pm capability
  staging: et131x: Remove redundant et131x_reset_recv() call
  staging: et131x: Remove unused rx_ring.recv_buffer_pool
  Staging: bcm: Fix three initialization errors in InterfaceDld.c
  Staging: bcm: Fix coding style issues in InterfaceDld.c
  staging:iio:dac: Add AD5360 driver
  staging:iio:trigger:bfin-timer: Fix compile error
  Staging: vt6655: add some range checks before memcpy()
  Staging: vt6655: whitespace fixes to iotcl.c
  Staging: vt6656: add some range checks before memcpy()
  Staging: vt6656: whitespace cleanups in ioctl.c
  ...

Fix up conflicts in:
 - drivers/{Kconfig,Makefile}, drivers/staging/{Kconfig,Makefile}:
	vg driver movement
 - drivers/staging/brcm80211/brcmfmac/{dhd_linux.c,mac80211_if.c}:
	driver removal vs now stale changes
 - drivers/staging/rtl8192e/r8192E_core.c:
	driver removal vs now stale changes
 - drivers/staging/et131x/et131*:
	driver consolidation into one file, tried to do fixups
...@@ -6171,7 +6171,7 @@ S: Maintained ...@@ -6171,7 +6171,7 @@ S: Maintained
STAGING SUBSYSTEM STAGING SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@suse.de> M: Greg Kroah-Hartman <gregkh@suse.de>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
L: devel@driverdev.osuosl.org L: devel@driverdev.osuosl.org
S: Maintained S: Maintained
F: drivers/staging/ F: drivers/staging/
...@@ -6212,6 +6212,11 @@ M: David Rowe <david@rowetel.com> ...@@ -6212,6 +6212,11 @@ M: David Rowe <david@rowetel.com>
S: Odd Fixes S: Odd Fixes
F: drivers/staging/echo/ F: drivers/staging/echo/
STAGING - ET131X NETWORK DRIVER
M: Mark Einon <mark.einon@gmail.com>
S: Odd Fixes
F: drivers/staging/et131x/
STAGING - FLARION FT1000 DRIVERS STAGING - FLARION FT1000 DRIVERS
M: Marek Belisko <marek.belisko@gmail.com> M: Marek Belisko <marek.belisko@gmail.com>
S: Odd Fixes S: Odd Fixes
...@@ -6240,6 +6245,13 @@ W: http://www.lirc.org/ ...@@ -6240,6 +6245,13 @@ W: http://www.lirc.org/
S: Odd Fixes S: Odd Fixes
F: drivers/staging/lirc/ F: drivers/staging/lirc/
STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
M: Julian Andres Klode <jak@jak-linux.org>
M: Marc Dietrich <marvin24@gmx.de>
L: ac100@lists.launchpad.net (moderated for non-subscribers)
S: Maintained
F: drivers/staging/nvec/
STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
M: Andres Salomon <dilinger@queued.net> M: Andres Salomon <dilinger@queued.net>
M: Chris Ball <cjb@laptop.org> M: Chris Ball <cjb@laptop.org>
......
...@@ -189,5 +189,6 @@ ...@@ -189,5 +189,6 @@
#define HV_STATUS_INVALID_HYPERCALL_CODE 2 #define HV_STATUS_INVALID_HYPERCALL_CODE 2
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3 #define HV_STATUS_INVALID_HYPERCALL_INPUT 3
#define HV_STATUS_INVALID_ALIGNMENT 4 #define HV_STATUS_INVALID_ALIGNMENT 4
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
#endif #endif
...@@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig" ...@@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig"
source "drivers/virt/Kconfig" source "drivers/virt/Kconfig"
source "drivers/hv/Kconfig"
source "drivers/devfreq/Kconfig" source "drivers/devfreq/Kconfig"
endmenu endmenu
...@@ -129,5 +129,6 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ ...@@ -129,5 +129,6 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
# Virtualization drivers # Virtualization drivers
obj-$(CONFIG_VIRT_DRIVERS) += virt/ obj-$(CONFIG_VIRT_DRIVERS) += virt/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_PM_DEVFREQ) += devfreq/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/
/*
* atari_SCC.h: Definitions for the Am8530 Serial Communications Controller
*
* Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*
*/
#ifndef _SCC_H
#define _SCC_H
#include <linux/delay.h>
/* Special configuration ioctls for the Atari SCC5380 Serial
* Communications Controller
*/
/* ioctl command codes */
#define TIOCGATSCC 0x54c0 /* get SCC configuration */
#define TIOCSATSCC 0x54c1 /* set SCC configuration */
#define TIOCDATSCC 0x54c2 /* reset configuration to defaults */
/* Clock sources */
#define CLK_RTxC 0
#define CLK_TRxC 1
#define CLK_PCLK 2
/* baud_bases for the common clocks in the Atari. These are the real
* frequencies divided by 16.
*/
#define SCC_BAUD_BASE_TIMC 19200 /* 0.3072 MHz from TT-MFP, Timer C */
#define SCC_BAUD_BASE_BCLK 153600 /* 2.4576 MHz */
#define SCC_BAUD_BASE_PCLK4 229500 /* 3.6720 MHz */
#define SCC_BAUD_BASE_PCLK 503374 /* 8.0539763 MHz */
#define SCC_BAUD_BASE_NONE 0 /* for not connected or unused
* clock sources */
/* The SCC clock configuration structure */
struct scc_clock_config {
unsigned RTxC_base; /* base_baud of RTxC */
unsigned TRxC_base; /* base_baud of TRxC */
unsigned PCLK_base; /* base_baud of PCLK, both channels! */
struct {
unsigned clksrc; /* CLK_RTxC, CLK_TRxC or CLK_PCLK */
unsigned divisor; /* divisor for base baud, valid values:
* see below */
} baud_table[17]; /* For 50, 75, 110, 135, 150, 200, 300,
* 600, 1200, 1800, 2400, 4800, 9600,
* 19200, 38400, 57600 and 115200 bps.
* The last two could be replaced by
* other rates > 38400 if they're not
* possible.
*/
};
/* The following divisors are valid:
*
* - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use
* the BRG)
*
* - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible)
*
* - CLK_PCLK: >= 4 and even (no direct modes, only BRG)
*
*/
struct scc_port {
struct gs_port gs;
volatile unsigned char *ctrlp;
volatile unsigned char *datap;
int x_char; /* xon/xoff character */
int c_dcd;
int channel;
struct scc_port *port_a; /* Reference to port A and B */
struct scc_port *port_b; /* structs for reg access */
};
#define SCC_MAGIC 0x52696368
/***********************************************************************/
/* */
/* Register Names */
/* */
/***********************************************************************/
/* The SCC documentation gives no explicit names to the registers,
* they're just called WR0..15 and RR0..15. To make the source code
* better readable and make the transparent write reg read access (see
* below) possible, I christen them here with self-invented names.
* Note that (real) read registers are assigned numbers 16..31. WR7'
* has number 33.
*/
#define COMMAND_REG 0 /* wo */
#define INT_AND_DMA_REG 1 /* wo */
#define INT_VECTOR_REG 2 /* rw, common to both channels */
#define RX_CTRL_REG 3 /* rw */
#define AUX1_CTRL_REG 4 /* rw */
#define TX_CTRL_REG 5 /* rw */
#define SYNC_ADR_REG 6 /* wo */
#define SYNC_CHAR_REG 7 /* wo */
#define SDLC_OPTION_REG 33 /* wo */
#define TX_DATA_REG 8 /* wo */
#define MASTER_INT_CTRL 9 /* wo, common to both channels */
#define AUX2_CTRL_REG 10 /* rw */
#define CLK_CTRL_REG 11 /* wo */
#define TIMER_LOW_REG 12 /* rw */
#define TIMER_HIGH_REG 13 /* rw */
#define DPLL_CTRL_REG 14 /* wo */
#define INT_CTRL_REG 15 /* rw */
#define STATUS_REG 16 /* ro */
#define SPCOND_STATUS_REG 17 /* wo */
/* RR2 is WR2 for Channel A, Channel B gives vector + current status: */
#define CURR_VECTOR_REG 18 /* Ch. B only, Ch. A for rw */
#define INT_PENDING_REG 19 /* Channel A only! */
/* RR4 is WR4, if b6(MR7') == 1 */
/* RR5 is WR5, if b6(MR7') == 1 */
#define FS_FIFO_LOW_REG 22 /* ro */
#define FS_FIFO_HIGH_REG 23 /* ro */
#define RX_DATA_REG 24 /* ro */
/* RR9 is WR3, if b6(MR7') == 1 */
#define DPLL_STATUS_REG 26 /* ro */
/* RR11 is WR10, if b6(MR7') == 1 */
/* RR12 is WR12 */
/* RR13 is WR13 */
/* RR14 not present */
/* RR15 is WR15 */
/***********************************************************************/
/* */
/* Register Values */
/* */
/***********************************************************************/
/* WR0: COMMAND_REG "CR" */
#define CR_RX_CRC_RESET 0x40
#define CR_TX_CRC_RESET 0x80
#define CR_TX_UNDERRUN_RESET 0xc0
#define CR_EXTSTAT_RESET 0x10
#define CR_SEND_ABORT 0x18
#define CR_ENAB_INT_NEXT_RX 0x20
#define CR_TX_PENDING_RESET 0x28
#define CR_ERROR_RESET 0x30
#define CR_HIGHEST_IUS_RESET 0x38
/* WR1: INT_AND_DMA_REG "IDR" */
#define IDR_EXTSTAT_INT_ENAB 0x01
#define IDR_TX_INT_ENAB 0x02
#define IDR_PARERR_AS_SPCOND 0x04
#define IDR_RX_INT_DISAB 0x00
#define IDR_RX_INT_FIRST 0x08
#define IDR_RX_INT_ALL 0x10
#define IDR_RX_INT_SPCOND 0x18
#define IDR_RX_INT_MASK 0x18
#define IDR_WAITREQ_RX 0x20
#define IDR_WAITREQ_IS_REQ 0x40
#define IDR_WAITREQ_ENAB 0x80
/* WR3: RX_CTRL_REG "RCR" */
#define RCR_RX_ENAB 0x01
#define RCR_DISCARD_SYNC_CHARS 0x02
#define RCR_ADDR_SEARCH 0x04
#define RCR_CRC_ENAB 0x08
#define RCR_SEARCH_MODE 0x10
#define RCR_AUTO_ENAB_MODE 0x20
#define RCR_CHSIZE_MASK 0xc0
#define RCR_CHSIZE_5 0x00
#define RCR_CHSIZE_6 0x40
#define RCR_CHSIZE_7 0x80
#define RCR_CHSIZE_8 0xc0
/* WR4: AUX1_CTRL_REG "A1CR" */
#define A1CR_PARITY_MASK 0x03
#define A1CR_PARITY_NONE 0x00
#define A1CR_PARITY_ODD 0x01
#define A1CR_PARITY_EVEN 0x03
#define A1CR_MODE_MASK 0x0c
#define A1CR_MODE_SYNCR 0x00
#define A1CR_MODE_ASYNC_1 0x04
#define A1CR_MODE_ASYNC_15 0x08
#define A1CR_MODE_ASYNC_2 0x0c
#define A1CR_SYNCR_MODE_MASK 0x30
#define A1CR_SYNCR_MONOSYNC 0x00
#define A1CR_SYNCR_BISYNC 0x10
#define A1CR_SYNCR_SDLC 0x20
#define A1CR_SYNCR_EXTCSYNC 0x30
#define A1CR_CLKMODE_MASK 0xc0
#define A1CR_CLKMODE_x1 0x00
#define A1CR_CLKMODE_x16 0x40
#define A1CR_CLKMODE_x32 0x80
#define A1CR_CLKMODE_x64 0xc0
/* WR5: TX_CTRL_REG "TCR" */
#define TCR_TX_CRC_ENAB 0x01
#define TCR_RTS 0x02
#define TCR_USE_CRC_CCITT 0x00
#define TCR_USE_CRC_16 0x04
#define TCR_TX_ENAB 0x08
#define TCR_SEND_BREAK 0x10
#define TCR_CHSIZE_MASK 0x60
#define TCR_CHSIZE_5 0x00
#define TCR_CHSIZE_6 0x20
#define TCR_CHSIZE_7 0x40
#define TCR_CHSIZE_8 0x60
#define TCR_DTR 0x80
/* WR7': SLDC_OPTION_REG "SOR" */
#define SOR_AUTO_TX_ENAB 0x01
#define SOR_AUTO_EOM_RESET 0x02
#define SOR_AUTO_RTS_MODE 0x04
#define SOR_NRZI_DISAB_HIGH 0x08
#define SOR_ALT_DTRREQ_TIMING 0x10
#define SOR_READ_CRC_CHARS 0x20
#define SOR_EXTENDED_REG_ACCESS 0x40
/* WR9: MASTER_INT_CTRL "MIC" */
#define MIC_VEC_INCL_STAT 0x01
#define MIC_NO_VECTOR 0x02
#define MIC_DISAB_LOWER_CHAIN 0x04
#define MIC_MASTER_INT_ENAB 0x08
#define MIC_STATUS_HIGH 0x10
#define MIC_IGN_INTACK 0x20
#define MIC_NO_RESET 0x00
#define MIC_CH_A_RESET 0x40
#define MIC_CH_B_RESET 0x80
#define MIC_HARD_RESET 0xc0
/* WR10: AUX2_CTRL_REG "A2CR" */
#define A2CR_SYNC_6 0x01
#define A2CR_LOOP_MODE 0x02
#define A2CR_ABORT_ON_UNDERRUN 0x04
#define A2CR_MARK_IDLE 0x08
#define A2CR_GO_ACTIVE_ON_POLL 0x10
#define A2CR_CODING_MASK 0x60
#define A2CR_CODING_NRZ 0x00
#define A2CR_CODING_NRZI 0x20
#define A2CR_CODING_FM1 0x40
#define A2CR_CODING_FM0 0x60
#define A2CR_PRESET_CRC_1 0x80
/* WR11: CLK_CTRL_REG "CCR" */
#define CCR_TRxCOUT_MASK 0x03
#define CCR_TRxCOUT_XTAL 0x00
#define CCR_TRxCOUT_TXCLK 0x01
#define CCR_TRxCOUT_BRG 0x02
#define CCR_TRxCOUT_DPLL 0x03
#define CCR_TRxC_OUTPUT 0x04
#define CCR_TXCLK_MASK 0x18
#define CCR_TXCLK_RTxC 0x00
#define CCR_TXCLK_TRxC 0x08
#define CCR_TXCLK_BRG 0x10
#define CCR_TXCLK_DPLL 0x18
#define CCR_RXCLK_MASK 0x60
#define CCR_RXCLK_RTxC 0x00
#define CCR_RXCLK_TRxC 0x20
#define CCR_RXCLK_BRG 0x40
#define CCR_RXCLK_DPLL 0x60
#define CCR_RTxC_XTAL 0x80
/* WR14: DPLL_CTRL_REG "DCR" */
#define DCR_BRG_ENAB 0x01
#define DCR_BRG_USE_PCLK 0x02
#define DCR_DTRREQ_IS_REQ 0x04
#define DCR_AUTO_ECHO 0x08
#define DCR_LOCAL_LOOPBACK 0x10
#define DCR_DPLL_EDGE_SEARCH 0x20
#define DCR_DPLL_ERR_RESET 0x40
#define DCR_DPLL_DISAB 0x60
#define DCR_DPLL_CLK_BRG 0x80
#define DCR_DPLL_CLK_RTxC 0xa0
#define DCR_DPLL_FM 0xc0
#define DCR_DPLL_NRZI 0xe0
/* WR15: INT_CTRL_REG "ICR" */
#define ICR_OPTIONREG_SELECT 0x01
#define ICR_ENAB_BRG_ZERO_INT 0x02
#define ICR_USE_FS_FIFO 0x04
#define ICR_ENAB_DCD_INT 0x08
#define ICR_ENAB_SYNC_INT 0x10
#define ICR_ENAB_CTS_INT 0x20
#define ICR_ENAB_UNDERRUN_INT 0x40
#define ICR_ENAB_BREAK_INT 0x80
/* RR0: STATUS_REG "SR" */
#define SR_CHAR_AVAIL 0x01
#define SR_BRG_ZERO 0x02
#define SR_TX_BUF_EMPTY 0x04
#define SR_DCD 0x08
#define SR_SYNC_ABORT 0x10
#define SR_CTS 0x20
#define SR_TX_UNDERRUN 0x40
#define SR_BREAK 0x80
/* RR1: SPCOND_STATUS_REG "SCSR" */
#define SCSR_ALL_SENT 0x01
#define SCSR_RESIDUAL_MASK 0x0e
#define SCSR_PARITY_ERR 0x10
#define SCSR_RX_OVERRUN 0x20
#define SCSR_CRC_FRAME_ERR 0x40
#define SCSR_END_OF_FRAME 0x80
/* RR3: INT_PENDING_REG "IPR" */
#define IPR_B_EXTSTAT 0x01
#define IPR_B_TX 0x02
#define IPR_B_RX 0x04
#define IPR_A_EXTSTAT 0x08
#define IPR_A_TX 0x10
#define IPR_A_RX 0x20
/* RR7: FS_FIFO_HIGH_REG "FFHR" */
#define FFHR_CNT_MASK 0x3f
#define FFHR_IS_FROM_FIFO 0x40
#define FFHR_FIFO_OVERRUN 0x80
/* RR10: DPLL_STATUS_REG "DSR" */
#define DSR_ON_LOOP 0x02
#define DSR_ON_LOOP_SENDING 0x10
#define DSR_TWO_CLK_MISSING 0x40
#define DSR_ONE_CLK_MISSING 0x80
/***********************************************************************/
/* */
/* Register Access */
/* */
/***********************************************************************/
/* The SCC needs 3.5 PCLK cycles recovery time between to register
* accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
* 125 ns = 437.5 ns. This is too short for udelay().
* 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be
* quite right
*/
#define scc_reg_delay() \
do { \
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) \
__asm__ __volatile__ ( " nop; nop"); \
else if (MACH_IS_ATARI) \
__asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
} while (0)
static unsigned char scc_shadow[2][16];
/* The following functions should relax the somehow complicated
* register access of the SCC. _SCCwrite() stores all written values
* (except for WR0 and WR8) in shadow registers for later recall. This
* removes the burden of remembering written values as needed. The
* extra work of storing the value doesn't count, since a delay is
* needed after a SCC access anyway. Additionally, _SCCwrite() manages
* writes to WR0 and WR8 differently, because these can be accessed
* directly with less overhead. Another special case are WR7 and WR7'.
* _SCCwrite automatically checks what of this registers is selected
* and changes b0 of WR15 if needed.
*
* _SCCread() for standard read registers is straightforward, except
* for RR2 (split into two "virtual" registers: one for the value
* written to WR2 (from the shadow) and one for the vector including
* status from RR2, Ch. B) and RR3. The latter must be read from
* Channel A, because it reads as all zeros on Ch. B. RR0 and RR8 can
* be accessed directly as before.
*
* The two inline function contain complicated switch statements. But
* I rely on regno and final_delay being constants, so gcc can reduce
* the whole stuff to just some assembler statements.
*
* _SCCwrite and _SCCread aren't intended to be used directly under
* normal circumstances. The macros SCCread[_ND] and SCCwrite[_ND] are
* for that purpose. They assume that a local variable 'port' is
* declared and pointing to the port's scc_struct entry. The
* variants with "_NB" appended should be used if no other SCC
* accesses follow immediately (within 0.5 usecs). They just skip the
* final delay nops.
*
* Please note that accesses to SCC registers should only take place
* when interrupts are turned off (at least if SCC interrupts are
* enabled). Otherwise, an interrupt could interfere with the
* two-stage accessing process.
*
*/
static __inline__ void _SCCwrite(
struct scc_port *port,
unsigned char *shadow,
volatile unsigned char *_scc_del,
int regno,
unsigned char val, int final_delay )
{
switch( regno ) {
case COMMAND_REG:
/* WR0 can be written directly without pointing */
*port->ctrlp = val;
break;
case SYNC_CHAR_REG:
/* For WR7, first set b0 of WR15 to 0, if needed */
if (shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT) {
*port->ctrlp = 15;
shadow[INT_CTRL_REG] &= ~ICR_OPTIONREG_SELECT;
scc_reg_delay();
*port->ctrlp = shadow[INT_CTRL_REG];
scc_reg_delay();
}
goto normal_case;
case SDLC_OPTION_REG:
/* For WR7', first set b0 of WR15 to 1, if needed */
if (!(shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT)) {
*port->ctrlp = 15;
shadow[INT_CTRL_REG] |= ICR_OPTIONREG_SELECT;
scc_reg_delay();
*port->ctrlp = shadow[INT_CTRL_REG];
scc_reg_delay();
}
*port->ctrlp = 7;
shadow[8] = val; /* WR7' shadowed at WR8 */
scc_reg_delay();
*port->ctrlp = val;
break;
case TX_DATA_REG: /* WR8 */
/* TX_DATA_REG can be accessed directly on some h/w */
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
{
*port->ctrlp = regno;
scc_reg_delay();
*port->ctrlp = val;
}
else
*port->datap = val;
break;
case MASTER_INT_CTRL:
*port->ctrlp = regno;
val &= 0x3f; /* bits 6..7 are the reset commands */
scc_shadow[0][regno] = val;
scc_reg_delay();
*port->ctrlp = val;
break;
case DPLL_CTRL_REG:
*port->ctrlp = regno;
val &= 0x1f; /* bits 5..7 are the DPLL commands */
shadow[regno] = val;
scc_reg_delay();
*port->ctrlp = val;
break;
case 1 ... 6:
case 10 ... 13:
case 15:
normal_case:
*port->ctrlp = regno;
shadow[regno] = val;
scc_reg_delay();
*port->ctrlp = val;
break;
default:
printk( "Bad SCC write access to WR%d\n", regno );
break;
}
if (final_delay)
scc_reg_delay();
}
static __inline__ unsigned char _SCCread(
struct scc_port *port,
unsigned char *shadow,
volatile unsigned char *_scc_del,
int regno, int final_delay )
{
unsigned char rv;
switch( regno ) {
/* --- real read registers --- */
case STATUS_REG:
rv = *port->ctrlp;
break;
case INT_PENDING_REG:
/* RR3: read only from Channel A! */
port = port->port_a;
goto normal_case;
case RX_DATA_REG:
/* RR8 can be accessed directly on some h/w */
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
{
*port->ctrlp = 8;
scc_reg_delay();
rv = *port->ctrlp;
}
else
rv = *port->datap;
break;
case CURR_VECTOR_REG:
/* RR2 (vector including status) from Ch. B */
port = port->port_b;
goto normal_case;
/* --- reading write registers: access the shadow --- */
case 1 ... 7:
case 10 ... 15:
return shadow[regno]; /* no final delay! */
/* WR7' is special, because it is shadowed at the place of WR8 */
case SDLC_OPTION_REG:
return shadow[8]; /* no final delay! */
/* WR9 is special too, because it is common for both channels */
case MASTER_INT_CTRL:
return scc_shadow[0][9]; /* no final delay! */
default:
printk( "Bad SCC read access to %cR%d\n", (regno & 16) ? 'R' : 'W',
regno & ~16 );
break;
case SPCOND_STATUS_REG:
case FS_FIFO_LOW_REG:
case FS_FIFO_HIGH_REG:
case DPLL_STATUS_REG:
normal_case:
*port->ctrlp = regno & 0x0f;
scc_reg_delay();
rv = *port->ctrlp;
break;
}
if (final_delay)
scc_reg_delay();
return rv;
}
#define SCC_ACCESS_INIT(port) \
unsigned char *_scc_shadow = &scc_shadow[port->channel][0]
#define SCCwrite(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),1)
#define SCCwrite_NB(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),0)
#define SCCread(reg) _SCCread(port,_scc_shadow,scc_del,(reg),1)
#define SCCread_NB(reg) _SCCread(port,_scc_shadow,scc_del,(reg),0)
#define SCCmod(reg,and,or) SCCwrite((reg),(SCCread(reg)&(and))|(or))
#endif /* _SCC_H */
config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && PCI
help
Select this option to run Linux as a Hyper-V client operating
system.
config HYPERV_UTILS
tristate "Microsoft Hyper-V Utilities driver"
depends on HYPERV && CONNECTOR && NLS
help
Select this option to enable the Hyper-V Utilities.
obj-$(CONFIG_HYPERV) += hv_vmbus.o
obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
hv_vmbus-y := vmbus_drv.o \
hv.o connection.o channel.o \
channel_mgmt.o ring_buffer.o
hv_utils-y := hv_util.o hv_kvp.o
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/hyperv.h>
#include "hyperv.h"
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
#define NUM_PAGES_SPANNED(addr, len) \ #define NUM_PAGES_SPANNED(addr, len) \
...@@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, ...@@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
struct hv_monitor_page *monitorpage; struct hv_monitor_page *monitorpage;
u8 monitor_group = (u8)channel->offermsg.monitorid / 32; u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
u8 monitor_offset = (u8)channel->offermsg.monitorid % 32; u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
/* u32 monitorBit = 1 << monitorOffset; */
debuginfo->relid = channel->offermsg.child_relid; debuginfo->relid = channel->offermsg.child_relid;
debuginfo->state = channel->state; debuginfo->state = channel->state;
memcpy(&debuginfo->interfacetype, memcpy(&debuginfo->interfacetype,
&channel->offermsg.offer.if_type, sizeof(struct hv_guid)); &channel->offermsg.offer.if_type, sizeof(uuid_le));
memcpy(&debuginfo->interface_instance, memcpy(&debuginfo->interface_instance,
&channel->offermsg.offer.if_instance, &channel->offermsg.offer.if_instance,
sizeof(struct hv_guid)); sizeof(uuid_le));
monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages; monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
...@@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
u32 recv_ringbuffer_size, void *userdata, u32 userdatalen, u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
void (*onchannelcallback)(void *context), void *context) void (*onchannelcallback)(void *context), void *context)
{ {
struct vmbus_channel_open_channel *openMsg; struct vmbus_channel_open_channel *open_msg;
struct vmbus_channel_msginfo *openInfo = NULL; struct vmbus_channel_msginfo *open_info = NULL;
void *in, *out; void *in, *out;
unsigned long flags; unsigned long flags;
int ret, t, err = 0; int ret, t, err = 0;
...@@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
} }
/* Create and init the channel open message */ /* Create and init the channel open message */
openInfo = kmalloc(sizeof(*openInfo) + open_info = kmalloc(sizeof(*open_info) +
sizeof(struct vmbus_channel_open_channel), sizeof(struct vmbus_channel_open_channel),
GFP_KERNEL); GFP_KERNEL);
if (!openInfo) { if (!open_info) {
err = -ENOMEM; err = -ENOMEM;
goto errorout; goto errorout;
} }
init_completion(&openInfo->waitevent); init_completion(&open_info->waitevent);
openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
openMsg->openid = newchannel->offermsg.child_relid; open_msg->openid = newchannel->offermsg.child_relid;
openMsg->child_relid = newchannel->offermsg.child_relid; open_msg->child_relid = newchannel->offermsg.child_relid;
openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
PAGE_SHIFT; PAGE_SHIFT;
openMsg->server_contextarea_gpadlhandle = 0; open_msg->server_contextarea_gpadlhandle = 0;
if (userdatalen > MAX_USER_DEFINED_BYTES) { if (userdatalen > MAX_USER_DEFINED_BYTES) {
err = -EINVAL; err = -EINVAL;
...@@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
} }
if (userdatalen) if (userdatalen)
memcpy(openMsg->userdata, userdata, userdatalen); memcpy(open_msg->userdata, userdata, userdatalen);
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_add_tail(&openInfo->msglistentry, list_add_tail(&open_info->msglistentry,
&vmbus_connection.chn_msg_list); &vmbus_connection.chn_msg_list);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
ret = vmbus_post_msg(openMsg, ret = vmbus_post_msg(open_msg,
sizeof(struct vmbus_channel_open_channel)); sizeof(struct vmbus_channel_open_channel));
if (ret != 0) if (ret != 0)
goto cleanup; goto cleanup;
t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
if (t == 0) { if (t == 0) {
err = -ETIMEDOUT; err = -ETIMEDOUT;
goto errorout; goto errorout;
} }
if (openInfo->response.open_result.status) if (open_info->response.open_result.status)
err = openInfo->response.open_result.status; err = open_info->response.open_result.status;
cleanup: cleanup:
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_del(&openInfo->msglistentry); list_del(&open_info->msglistentry);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
kfree(openInfo); kfree(open_info);
return err; return err;
errorout: errorout:
...@@ -234,56 +233,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -234,56 +233,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
hv_ringbuffer_cleanup(&newchannel->inbound); hv_ringbuffer_cleanup(&newchannel->inbound);
free_pages((unsigned long)out, free_pages((unsigned long)out,
get_order(send_ringbuffer_size + recv_ringbuffer_size)); get_order(send_ringbuffer_size + recv_ringbuffer_size));
kfree(openInfo); kfree(open_info);
return err; return err;
} }
EXPORT_SYMBOL_GPL(vmbus_open); EXPORT_SYMBOL_GPL(vmbus_open);
/*
* dump_gpadl_body - Dump the gpadl body message to the console for
* debugging purposes.
*/
static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len)
{
int i;
int pfncount;
pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
sizeof(u64);
DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
for (i = 0; i < pfncount; i++)
DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu",
i, gpadl->pfn[i]);
}
/*
* dump_gpadl_header - Dump the gpadl header message to the console for
* debugging purposes.
*/
static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl)
{
int i, j;
int pagecount;
DPRINT_DBG(VMBUS,
"gpadl header - relid %d, range count %d, range buflen %d",
gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
for (i = 0; i < gpadl->rangecount; i++) {
pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT;
pagecount = (pagecount > 26) ? 26 : pagecount;
DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
"page count %d", i, gpadl->range[i].byte_count,
gpadl->range[i].byte_offset, pagecount);
for (j = 0; j < pagecount; j++)
DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
gpadl->range[i].pfn_array[j]);
}
}
/* /*
* create_gpadl_header - Creates a gpadl for the specified buffer * create_gpadl_header - Creates a gpadl for the specified buffer
*/ */
...@@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, ...@@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
{ {
struct vmbus_channel_gpadl_header *gpadlmsg; struct vmbus_channel_gpadl_header *gpadlmsg;
struct vmbus_channel_gpadl_body *gpadl_body; struct vmbus_channel_gpadl_body *gpadl_body;
/* struct vmbus_channel_gpadl_created *gpadlCreated; */
struct vmbus_channel_msginfo *msginfo = NULL; struct vmbus_channel_msginfo *msginfo = NULL;
struct vmbus_channel_msginfo *submsginfo; struct vmbus_channel_msginfo *submsginfo;
u32 msgcount; u32 msgcount;
...@@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, ...@@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
gpadlmsg->child_relid = channel->offermsg.child_relid; gpadlmsg->child_relid = channel->offermsg.child_relid;
gpadlmsg->gpadl = next_gpadl_handle; gpadlmsg->gpadl = next_gpadl_handle;
dump_gpadl_header(gpadlmsg);
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_add_tail(&msginfo->msglistentry, list_add_tail(&msginfo->msglistentry,
...@@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, ...@@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
CHANNELMSG_GPADL_BODY; CHANNELMSG_GPADL_BODY;
gpadl_body->gpadl = next_gpadl_handle; gpadl_body->gpadl = next_gpadl_handle;
dump_gpadl_body(gpadl_body, submsginfo->msgsize -
sizeof(*submsginfo));
ret = vmbus_post_msg(gpadl_body, ret = vmbus_post_msg(gpadl_body,
submsginfo->msgsize - submsginfo->msgsize -
sizeof(*submsginfo)); sizeof(*submsginfo));
...@@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) ...@@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
unsigned long flags; unsigned long flags;
int ret, t; int ret, t;
/* ASSERT(gpadl_handle != 0); */
info = kmalloc(sizeof(*info) + info = kmalloc(sizeof(*info) +
sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
if (!info) if (!info)
...@@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel) ...@@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel)
{ {
struct vmbus_channel_close_channel *msg; struct vmbus_channel_close_channel *msg;
int ret; int ret;
unsigned long flags;
/* Stop callback and cancel the timer asap */ /* Stop callback and cancel the timer asap */
spin_lock_irqsave(&channel->inbound_lock, flags);
channel->onchannel_callback = NULL; channel->onchannel_callback = NULL;
spin_unlock_irqrestore(&channel->inbound_lock, flags);
/* Send a closing message */ /* Send a closing message */
...@@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, ...@@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
u32 packetlen; u32 packetlen;
u32 userlen; u32 userlen;
int ret; int ret;
unsigned long flags;
*buffer_actual_len = 0; *buffer_actual_len = 0;
*requestid = 0; *requestid = 0;
spin_lock_irqsave(&channel->inbound_lock, flags);
ret = hv_ringbuffer_peek(&channel->inbound, &desc, ret = hv_ringbuffer_peek(&channel->inbound, &desc,
sizeof(struct vmpacket_descriptor)); sizeof(struct vmpacket_descriptor));
if (ret != 0) { if (ret != 0)
spin_unlock_irqrestore(&channel->inbound_lock, flags);
return 0; return 0;
}
packetlen = desc.len8 << 3; packetlen = desc.len8 << 3;
userlen = packetlen - (desc.offset8 << 3); userlen = packetlen - (desc.offset8 << 3);
...@@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, ...@@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
*buffer_actual_len = userlen; *buffer_actual_len = userlen;
if (userlen > bufferlen) { if (userlen > bufferlen) {
spin_unlock_irqrestore(&channel->inbound_lock, flags);
pr_err("Buffer too small - got %d needs %d\n", pr_err("Buffer too small - got %d needs %d\n",
bufferlen, userlen); bufferlen, userlen);
...@@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, ...@@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen, ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
(desc.offset8 << 3)); (desc.offset8 << 3));
spin_unlock_irqrestore(&channel->inbound_lock, flags);
return 0; return 0;
} }
...@@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, ...@@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
u32 packetlen; u32 packetlen;
u32 userlen; u32 userlen;
int ret; int ret;
unsigned long flags;
*buffer_actual_len = 0; *buffer_actual_len = 0;
*requestid = 0; *requestid = 0;
spin_lock_irqsave(&channel->inbound_lock, flags);
ret = hv_ringbuffer_peek(&channel->inbound, &desc, ret = hv_ringbuffer_peek(&channel->inbound, &desc,
sizeof(struct vmpacket_descriptor)); sizeof(struct vmpacket_descriptor));
if (ret != 0) { if (ret != 0)
spin_unlock_irqrestore(&channel->inbound_lock, flags);
return 0; return 0;
}
packetlen = desc.len8 << 3; packetlen = desc.len8 << 3;
...@@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, ...@@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
*buffer_actual_len = packetlen; *buffer_actual_len = packetlen;
if (packetlen > bufferlen) { if (packetlen > bufferlen) {
spin_unlock_irqrestore(&channel->inbound_lock, flags);
pr_err("Buffer too small - needed %d bytes but " pr_err("Buffer too small - needed %d bytes but "
"got space for only %d bytes\n", "got space for only %d bytes\n",
packetlen, bufferlen); packetlen, bufferlen);
return -2; return -ENOBUFS;
} }
*requestid = desc.trans_id; *requestid = desc.trans_id;
...@@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, ...@@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
/* Copy over the entire packet to the user buffer */ /* Copy over the entire packet to the user buffer */
ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0); ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
spin_unlock_irqrestore(&channel->inbound_lock, flags);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/hyperv.h>
#include "hyperv.h"
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
struct vmbus_channel_message_table_entry { struct vmbus_channel_message_table_entry {
...@@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry { ...@@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry {
#define MAX_MSG_TYPES 4 #define MAX_MSG_TYPES 4
#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 #define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
static const struct hv_guid static const uuid_le
supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
/* Storage - SCSI */ /* Storage - SCSI */
{ {
.data = { .b = {
0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
} }
...@@ -54,7 +54,7 @@ static const struct hv_guid ...@@ -54,7 +54,7 @@ static const struct hv_guid
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
/* Network */ /* Network */
{ {
.data = { .b = {
0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
} }
...@@ -63,7 +63,7 @@ static const struct hv_guid ...@@ -63,7 +63,7 @@ static const struct hv_guid
/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
/* Input */ /* Input */
{ {
.data = { .b = {
0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
} }
...@@ -72,7 +72,7 @@ static const struct hv_guid ...@@ -72,7 +72,7 @@ static const struct hv_guid
/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ /* {32412632-86cb-44a2-9b5c-50d1417354f5} */
/* IDE */ /* IDE */
{ {
.data = { .b = {
0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
} }
...@@ -80,7 +80,7 @@ static const struct hv_guid ...@@ -80,7 +80,7 @@ static const struct hv_guid
/* 0E0B6031-5213-4934-818B-38D90CED39DB */ /* 0E0B6031-5213-4934-818B-38D90CED39DB */
/* Shutdown */ /* Shutdown */
{ {
.data = { .b = {
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
} }
...@@ -88,7 +88,7 @@ static const struct hv_guid ...@@ -88,7 +88,7 @@ static const struct hv_guid
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
/* TimeSync */ /* TimeSync */
{ {
.data = { .b = {
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
} }
...@@ -96,7 +96,7 @@ static const struct hv_guid ...@@ -96,7 +96,7 @@ static const struct hv_guid
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */ /* {57164f39-9115-4e78-ab55-382f3bd5422d} */
/* Heartbeat */ /* Heartbeat */
{ {
.data = { .b = {
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
} }
...@@ -104,7 +104,7 @@ static const struct hv_guid ...@@ -104,7 +104,7 @@ static const struct hv_guid
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
/* KVP */ /* KVP */
{ {
.data = { .b = {
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
} }
...@@ -114,7 +114,7 @@ static const struct hv_guid ...@@ -114,7 +114,7 @@ static const struct hv_guid
/** /**
* prep_negotiate_resp() - Create default response for Hyper-V Negotiate message * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
* @icmsghdrp: Pointer to msg header structure * @icmsghdrp: Pointer to msg header structure
* @icmsg_negotiate: Pointer to negotiate message structure * @icmsg_negotiate: Pointer to negotiate message structure
* @buf: Raw buffer channel data * @buf: Raw buffer channel data
...@@ -128,9 +128,8 @@ static const struct hv_guid ...@@ -128,9 +128,8 @@ static const struct hv_guid
* *
* Mainly used by Hyper-V drivers. * Mainly used by Hyper-V drivers.
*/ */
void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
struct icmsg_negotiate *negop, struct icmsg_negotiate *negop, u8 *buf)
u8 *buf)
{ {
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
icmsghdrp->icmsgsize = 0x10; icmsghdrp->icmsgsize = 0x10;
...@@ -156,119 +155,7 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, ...@@ -156,119 +155,7 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
negop->icmsg_vercnt = 1; negop->icmsg_vercnt = 1;
} }
} }
EXPORT_SYMBOL(prep_negotiate_resp); EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
/**
* chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK
* Hyper-V requests
* @context: Pointer to argument structure.
*
* Set up the default handler for non device driver specific requests
* from Hyper-V. This stub responds to the default negotiate messages
* that come in for every non IDE/SCSI/Network request.
* This behavior is normally overwritten in the hv_utils driver. That
* driver handles requests like graceful shutdown, heartbeats etc.
*
* Mainly used by Hyper-V drivers.
*/
void chn_cb_negotiate(void *context)
{
struct vmbus_channel *channel = context;
u8 *buf;
u32 buflen, recvlen;
u64 requestid;
struct icmsg_hdr *icmsghdrp;
struct icmsg_negotiate *negop = NULL;
if (channel->util_index >= 0) {
/*
* This is a properly initialized util channel.
* Route this callback appropriately and setup state
* so that we don't need to reroute again.
*/
if (hv_cb_utils[channel->util_index].callback != NULL) {
/*
* The util driver has established a handler for
* this service; do the magic.
*/
channel->onchannel_callback =
hv_cb_utils[channel->util_index].callback;
(hv_cb_utils[channel->util_index].callback)(channel);
return;
}
}
buflen = PAGE_SIZE;
buf = kmalloc(buflen, GFP_ATOMIC);
vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
if (recvlen > 0) {
icmsghdrp = (struct icmsg_hdr *)&buf[
sizeof(struct vmbuspipe_hdr)];
prep_negotiate_resp(icmsghdrp, negop, buf);
icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
| ICMSGHDRFLAG_RESPONSE;
vmbus_sendpacket(channel, buf,
recvlen, requestid,
VM_PKT_DATA_INBAND, 0);
}
kfree(buf);
}
EXPORT_SYMBOL(chn_cb_negotiate);
/*
* Function table used for message responses for non IDE/SCSI/Network type
* messages. (Such as KVP/Shutdown etc)
*/
struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
/* 0E0B6031-5213-4934-818B-38D90CED39DB */
/* Shutdown */
{
.msg_type = HV_SHUTDOWN_MSG,
.data = {
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
},
.log_msg = "Shutdown channel functionality initialized"
},
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
/* TimeSync */
{
.msg_type = HV_TIMESYNC_MSG,
.data = {
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
},
.log_msg = "Timesync channel functionality initialized"
},
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
/* Heartbeat */
{
.msg_type = HV_HEARTBEAT_MSG,
.data = {
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
},
.log_msg = "Heartbeat channel functionality initialized"
},
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
/* KVP */
{
.data = {
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
},
.log_msg = "KVP channel functionality initialized"
},
};
EXPORT_SYMBOL(hv_cb_utils);
/* /*
* alloc_channel - Allocate and initialize a vmbus channel object * alloc_channel - Allocate and initialize a vmbus channel object
...@@ -309,7 +196,7 @@ static void release_channel(struct work_struct *work) ...@@ -309,7 +196,7 @@ static void release_channel(struct work_struct *work)
/* /*
* free_channel - Release the resources used by the vmbus channel object * free_channel - Release the resources used by the vmbus channel object
*/ */
void free_channel(struct vmbus_channel *channel) static void free_channel(struct vmbus_channel *channel)
{ {
/* /*
...@@ -333,7 +220,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work) ...@@ -333,7 +220,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
struct vmbus_channel, struct vmbus_channel,
work); work);
vmbus_child_device_unregister(channel->device_obj); vmbus_device_unregister(channel->device_obj);
} }
/* /*
...@@ -348,7 +235,6 @@ static void vmbus_process_offer(struct work_struct *work) ...@@ -348,7 +235,6 @@ static void vmbus_process_offer(struct work_struct *work)
struct vmbus_channel *channel; struct vmbus_channel *channel;
bool fnew = true; bool fnew = true;
int ret; int ret;
int cnt;
unsigned long flags; unsigned long flags;
/* The next possible work is rescind handling */ /* The next possible work is rescind handling */
...@@ -358,12 +244,10 @@ static void vmbus_process_offer(struct work_struct *work) ...@@ -358,12 +244,10 @@ static void vmbus_process_offer(struct work_struct *work)
spin_lock_irqsave(&vmbus_connection.channel_lock, flags); spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
if (!memcmp(&channel->offermsg.offer.if_type, if (!uuid_le_cmp(channel->offermsg.offer.if_type,
&newchannel->offermsg.offer.if_type, newchannel->offermsg.offer.if_type) &&
sizeof(struct hv_guid)) && !uuid_le_cmp(channel->offermsg.offer.if_instance,
!memcmp(&channel->offermsg.offer.if_instance, newchannel->offermsg.offer.if_instance)) {
&newchannel->offermsg.offer.if_instance,
sizeof(struct hv_guid))) {
fnew = false; fnew = false;
break; break;
} }
...@@ -385,7 +269,7 @@ static void vmbus_process_offer(struct work_struct *work) ...@@ -385,7 +269,7 @@ static void vmbus_process_offer(struct work_struct *work)
* We need to set the DeviceObject field before calling * We need to set the DeviceObject field before calling
* vmbus_child_dev_add() * vmbus_child_dev_add()
*/ */
newchannel->device_obj = vmbus_child_device_create( newchannel->device_obj = vmbus_device_create(
&newchannel->offermsg.offer.if_type, &newchannel->offermsg.offer.if_type,
&newchannel->offermsg.offer.if_instance, &newchannel->offermsg.offer.if_instance,
newchannel); newchannel);
...@@ -395,7 +279,7 @@ static void vmbus_process_offer(struct work_struct *work) ...@@ -395,7 +279,7 @@ static void vmbus_process_offer(struct work_struct *work)
* binding which eventually invokes the device driver's AddDevice() * binding which eventually invokes the device driver's AddDevice()
* method. * method.
*/ */
ret = vmbus_child_device_register(newchannel->device_obj); ret = vmbus_device_register(newchannel->device_obj);
if (ret != 0) { if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n", pr_err("unable to add child device object (relid %d)\n",
newchannel->offermsg.child_relid); newchannel->offermsg.child_relid);
...@@ -412,48 +296,26 @@ static void vmbus_process_offer(struct work_struct *work) ...@@ -412,48 +296,26 @@ static void vmbus_process_offer(struct work_struct *work)
* can cleanup properly * can cleanup properly
*/ */
newchannel->state = CHANNEL_OPEN_STATE; newchannel->state = CHANNEL_OPEN_STATE;
newchannel->util_index = -1; /* Invalid index */
/* Open IC channels */
for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
if (memcmp(&newchannel->offermsg.offer.if_type,
&hv_cb_utils[cnt].data,
sizeof(struct hv_guid)) == 0 &&
vmbus_open(newchannel, 2 * PAGE_SIZE,
2 * PAGE_SIZE, NULL, 0,
chn_cb_negotiate,
newchannel) == 0) {
hv_cb_utils[cnt].channel = newchannel;
newchannel->util_index = cnt;
pr_info("%s\n", hv_cb_utils[cnt].log_msg);
}
}
} }
} }
/* /*
* vmbus_onoffer - Handler for channel offers from vmbus in parent partition. * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
* *
* We ignore all offers except network and storage offers. For each network and
* storage offers, we create a channel object and queue a work item to the
* channel object to process the offer synchronously
*/ */
static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
{ {
struct vmbus_channel_offer_channel *offer; struct vmbus_channel_offer_channel *offer;
struct vmbus_channel *newchannel; struct vmbus_channel *newchannel;
struct hv_guid *guidtype; uuid_le *guidtype;
struct hv_guid *guidinstance; uuid_le *guidinstance;
int i; int i;
int fsupported = 0; int fsupported = 0;
offer = (struct vmbus_channel_offer_channel *)hdr; offer = (struct vmbus_channel_offer_channel *)hdr;
for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
if (memcmp(&offer->offer.if_type, if (!uuid_le_cmp(offer->offer.if_type,
&supported_device_classes[i], supported_device_classes[i])) {
sizeof(struct hv_guid)) == 0) {
fsupported = 1; fsupported = 1;
break; break;
} }
......
...@@ -25,11 +25,12 @@ ...@@ -25,11 +25,12 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/hyperv.h>
#include "hyperv.h" #include <asm/hyperv.h>
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
...@@ -49,10 +50,6 @@ int vmbus_connect(void) ...@@ -49,10 +50,6 @@ int vmbus_connect(void)
struct vmbus_channel_initiate_contact *msg; struct vmbus_channel_initiate_contact *msg;
unsigned long flags; unsigned long flags;
/* Make sure we are not connecting or connected */
if (vmbus_connection.conn_state != DISCONNECTED)
return -EISCONN;
/* Initialize the vmbus connection */ /* Initialize the vmbus connection */
vmbus_connection.conn_state = CONNECTING; vmbus_connection.conn_state = CONNECTING;
vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
...@@ -214,8 +211,7 @@ struct vmbus_channel *relid2channel(u32 relid) ...@@ -214,8 +211,7 @@ struct vmbus_channel *relid2channel(u32 relid)
static void process_chn_event(u32 relid) static void process_chn_event(u32 relid)
{ {
struct vmbus_channel *channel; struct vmbus_channel *channel;
unsigned long flags;
/* ASSERT(relId > 0); */
/* /*
* Find the channel based on this relid and invokes the * Find the channel based on this relid and invokes the
...@@ -223,11 +219,27 @@ static void process_chn_event(u32 relid) ...@@ -223,11 +219,27 @@ static void process_chn_event(u32 relid)
*/ */
channel = relid2channel(relid); channel = relid2channel(relid);
if (channel) { if (!channel) {
channel->onchannel_callback(channel->channel_callback_context);
} else {
pr_err("channel not found for relid - %u\n", relid); pr_err("channel not found for relid - %u\n", relid);
return;
} }
/*
* A channel once created is persistent even when there
* is no driver handling the device. An unloading driver
* sets the onchannel_callback to NULL under the
* protection of the channel inbound_lock. Thus, checking
* and invoking the driver specific callback takes care of
* orderly unloading of the driver.
*/
spin_lock_irqsave(&channel->inbound_lock, flags);
if (channel->onchannel_callback != NULL)
channel->onchannel_callback(channel->channel_callback_context);
else
pr_err("no channel callback for relid - %u\n", relid);
spin_unlock_irqrestore(&channel->inbound_lock, flags);
} }
/* /*
...@@ -248,16 +260,17 @@ void vmbus_on_event(unsigned long data) ...@@ -248,16 +260,17 @@ void vmbus_on_event(unsigned long data)
if (!recv_int_page[dword]) if (!recv_int_page[dword])
continue; continue;
for (bit = 0; bit < 32; bit++) { for (bit = 0; bit < 32; bit++) {
if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) { if (sync_test_and_clear_bit(bit,
(unsigned long *)&recv_int_page[dword])) {
relid = (dword << 5) + bit; relid = (dword << 5) + bit;
if (relid == 0) { if (relid == 0)
/* /*
* Special case - vmbus * Special case - vmbus
* channel protocol msg * channel protocol msg
*/ */
continue; continue;
}
process_chn_event(relid); process_chn_event(relid);
} }
} }
...@@ -270,10 +283,25 @@ void vmbus_on_event(unsigned long data) ...@@ -270,10 +283,25 @@ void vmbus_on_event(unsigned long data)
int vmbus_post_msg(void *buffer, size_t buflen) int vmbus_post_msg(void *buffer, size_t buflen)
{ {
union hv_connection_id conn_id; union hv_connection_id conn_id;
int ret = 0;
int retries = 0;
conn_id.asu32 = 0; conn_id.asu32 = 0;
conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID; conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
return hv_post_message(conn_id, 1, buffer, buflen);
/*
* hv_post_message() can have transient failures because of
* insufficient resources. Retry the operation a couple of
* times before giving up.
*/
while (retries < 3) {
ret = hv_post_message(conn_id, 1, buffer, buflen);
if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
return ret;
retries++;
msleep(100);
}
return ret;
} }
/* /*
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/hyperv.h>
#include "hyperv.h" #include <asm/hyperv.h>
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
/* The one and only */ /* The one and only */
...@@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) ...@@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
u64 hv_status = 0; u64 hv_status = 0;
u64 input_address = (input) ? virt_to_phys(input) : 0; u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0;
volatile void *hypercall_page = hv_context.hypercall_page; void *hypercall_page = hv_context.hypercall_page;
__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
__asm__ __volatile__("call *%3" : "=a" (hv_status) : __asm__ __volatile__("call *%3" : "=a" (hv_status) :
...@@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) ...@@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
u64 output_address = (output) ? virt_to_phys(output) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0;
u32 output_address_hi = output_address >> 32; u32 output_address_hi = output_address >> 32;
u32 output_address_lo = output_address & 0xFFFFFFFF; u32 output_address_lo = output_address & 0xFFFFFFFF;
volatile void *hypercall_page = hv_context.hypercall_page; void *hypercall_page = hv_context.hypercall_page;
__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
"=a"(hv_status_lo) : "d" (control_hi), "=a"(hv_status_lo) : "d" (control_hi),
...@@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output) ...@@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output)
*/ */
int hv_init(void) int hv_init(void)
{ {
int ret = 0;
int max_leaf; int max_leaf;
union hv_x64_msr_hypercall_contents hypercall_msr; union hv_x64_msr_hypercall_contents hypercall_msr;
void *virtaddr = NULL; void *virtaddr = NULL;
...@@ -164,11 +163,7 @@ int hv_init(void) ...@@ -164,11 +163,7 @@ int hv_init(void)
goto cleanup; goto cleanup;
max_leaf = query_hypervisor_info(); max_leaf = query_hypervisor_info();
/* HvQueryHypervisorFeatures(maxLeaf); */
/*
* We only support running on top of Hyper-V
*/
rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
if (hv_context.guestid != 0) if (hv_context.guestid != 0)
...@@ -181,10 +176,6 @@ int hv_init(void) ...@@ -181,10 +176,6 @@ int hv_init(void)
/* See if the hypercall page is already set */ /* See if the hypercall page is already set */
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
/*
* Allocate the hypercall page memory
* virtaddr = osd_page_alloc(1);
*/
virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
if (!virtaddr) if (!virtaddr)
...@@ -222,7 +213,7 @@ int hv_init(void) ...@@ -222,7 +213,7 @@ int hv_init(void)
hv_context.signal_event_param->flag_number = 0; hv_context.signal_event_param->flag_number = 0;
hv_context.signal_event_param->rsvdz = 0; hv_context.signal_event_param->rsvdz = 0;
return ret; return 0;
cleanup: cleanup:
if (virtaddr) { if (virtaddr) {
...@@ -233,8 +224,8 @@ int hv_init(void) ...@@ -233,8 +224,8 @@ int hv_init(void)
vfree(virtaddr); vfree(virtaddr);
} }
ret = -1;
return ret; return -ENOTSUPP;
} }
/* /*
...@@ -378,7 +369,7 @@ void hv_synic_init(void *irqarg) ...@@ -378,7 +369,7 @@ void hv_synic_init(void *irqarg)
shared_sint.as_uint64 = 0; shared_sint.as_uint64 = 0;
shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
shared_sint.masked = false; shared_sint.masked = false;
shared_sint.auto_eoi = true; shared_sint.auto_eoi = false;
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#include <linux/nls.h> #include <linux/nls.h>
#include <linux/connector.h> #include <linux/connector.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/hyperv.h>
#include "hyperv.h"
#include "hv_kvp.h" #include "hv_kvp.h"
...@@ -44,21 +44,24 @@ ...@@ -44,21 +44,24 @@
static struct { static struct {
bool active; /* transaction status - active or not */ bool active; /* transaction status - active or not */
int recv_len; /* number of bytes received. */ int recv_len; /* number of bytes received. */
int index; /* current index */
struct vmbus_channel *recv_channel; /* chn we got the request */ struct vmbus_channel *recv_channel; /* chn we got the request */
u64 recv_req_id; /* request ID. */ u64 recv_req_id; /* request ID. */
} kvp_transaction; } kvp_transaction;
static int kvp_send_key(int index); static void kvp_send_key(struct work_struct *dummy);
#define TIMEOUT_FIRED 1
static void kvp_respond_to_host(char *key, char *value, int error); static void kvp_respond_to_host(char *key, char *value, int error);
static void kvp_work_func(struct work_struct *dummy); static void kvp_work_func(struct work_struct *dummy);
static void kvp_register(void); static void kvp_register(void);
static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func); static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL }; static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
static const char kvp_name[] = "kvp_kernel_module"; static const char kvp_name[] = "kvp_kernel_module";
static int timeout_fired;
static u8 *recv_buffer; static u8 *recv_buffer;
/* /*
* Register the kernel component with the user-level daemon. * Register the kernel component with the user-level daemon.
...@@ -90,8 +93,7 @@ kvp_work_func(struct work_struct *dummy) ...@@ -90,8 +93,7 @@ kvp_work_func(struct work_struct *dummy)
* If the timer fires, the user-mode component has not responded; * If the timer fires, the user-mode component has not responded;
* process the pending transaction. * process the pending transaction.
*/ */
kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired); kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
timeout_fired = 1;
} }
/* /*
...@@ -121,10 +123,11 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) ...@@ -121,10 +123,11 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
} }
} }
static int static void
kvp_send_key(int index) kvp_send_key(struct work_struct *dummy)
{ {
struct cn_msg *msg; struct cn_msg *msg;
int index = kvp_transaction.index;
msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
...@@ -136,9 +139,8 @@ kvp_send_key(int index) ...@@ -136,9 +139,8 @@ kvp_send_key(int index)
msg->len = sizeof(struct hv_ku_msg); msg->len = sizeof(struct hv_ku_msg);
cn_netlink_send(msg, 0, GFP_ATOMIC); cn_netlink_send(msg, 0, GFP_ATOMIC);
kfree(msg); kfree(msg);
return 0;
} }
return 1; return;
} }
/* /*
...@@ -177,6 +179,15 @@ kvp_respond_to_host(char *key, char *value, int error) ...@@ -177,6 +179,15 @@ kvp_respond_to_host(char *key, char *value, int error)
channel = kvp_transaction.recv_channel; channel = kvp_transaction.recv_channel;
req_id = kvp_transaction.recv_req_id; req_id = kvp_transaction.recv_req_id;
kvp_transaction.active = false;
if (channel->onchannel_callback == NULL)
/*
* We have raced with util driver being unloaded;
* silently return.
*/
return;
icmsghdrp = (struct icmsg_hdr *) icmsghdrp = (struct icmsg_hdr *)
&recv_buffer[sizeof(struct vmbuspipe_hdr)]; &recv_buffer[sizeof(struct vmbuspipe_hdr)];
kvp_msg = (struct hv_kvp_msg *) kvp_msg = (struct hv_kvp_msg *)
...@@ -217,7 +228,6 @@ kvp_respond_to_host(char *key, char *value, int error) ...@@ -217,7 +228,6 @@ kvp_respond_to_host(char *key, char *value, int error)
vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
VM_PKT_DATA_INBAND, 0); VM_PKT_DATA_INBAND, 0);
kvp_transaction.active = false;
} }
/* /*
...@@ -243,10 +253,6 @@ void hv_kvp_onchannelcallback(void *context) ...@@ -243,10 +253,6 @@ void hv_kvp_onchannelcallback(void *context)
struct icmsg_negotiate *negop = NULL; struct icmsg_negotiate *negop = NULL;
if (kvp_transaction.active)
return;
vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid); vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
if (recvlen > 0) { if (recvlen > 0) {
...@@ -254,7 +260,7 @@ void hv_kvp_onchannelcallback(void *context) ...@@ -254,7 +260,7 @@ void hv_kvp_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)]; sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
prep_negotiate_resp(icmsghdrp, negop, recv_buffer); vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
} else { } else {
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
sizeof(struct vmbuspipe_hdr) + sizeof(struct vmbuspipe_hdr) +
...@@ -282,6 +288,7 @@ void hv_kvp_onchannelcallback(void *context) ...@@ -282,6 +288,7 @@ void hv_kvp_onchannelcallback(void *context)
kvp_transaction.recv_channel = channel; kvp_transaction.recv_channel = channel;
kvp_transaction.recv_req_id = requestid; kvp_transaction.recv_req_id = requestid;
kvp_transaction.active = true; kvp_transaction.active = true;
kvp_transaction.index = kvp_data->index;
/* /*
* Get the information from the * Get the information from the
...@@ -292,8 +299,8 @@ void hv_kvp_onchannelcallback(void *context) ...@@ -292,8 +299,8 @@ void hv_kvp_onchannelcallback(void *context)
* Set a timeout to deal with * Set a timeout to deal with
* user-mode not responding. * user-mode not responding.
*/ */
kvp_send_key(kvp_data->index); schedule_work(&kvp_sendkey_work);
schedule_delayed_work(&kvp_work, 100); schedule_delayed_work(&kvp_work, 5*HZ);
return; return;
...@@ -312,16 +319,14 @@ void hv_kvp_onchannelcallback(void *context) ...@@ -312,16 +319,14 @@ void hv_kvp_onchannelcallback(void *context)
} }
int int
hv_kvp_init(void) hv_kvp_init(struct hv_util_service *srv)
{ {
int err; int err;
err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback); err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
if (err) if (err)
return err; return err;
recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); recv_buffer = srv->recv_buffer;
if (!recv_buffer)
return -ENOMEM;
return 0; return 0;
} }
...@@ -330,5 +335,5 @@ void hv_kvp_deinit(void) ...@@ -330,5 +335,5 @@ void hv_kvp_deinit(void)
{ {
cn_del_callback(&kvp_id); cn_del_callback(&kvp_id);
cancel_delayed_work_sync(&kvp_work); cancel_delayed_work_sync(&kvp_work);
kfree(recv_buffer); cancel_work_sync(&kvp_sendkey_work);
} }
...@@ -175,7 +175,7 @@ struct hv_kvp_msg { ...@@ -175,7 +175,7 @@ struct hv_kvp_msg {
struct hv_kvp_msg_enumerate kvp_data; struct hv_kvp_msg_enumerate kvp_data;
}; };
int hv_kvp_init(void); int hv_kvp_init(struct hv_util_service *);
void hv_kvp_deinit(void); void hv_kvp_deinit(void);
void hv_kvp_onchannelcallback(void *); void hv_kvp_onchannelcallback(void *);
......
...@@ -26,15 +26,31 @@ ...@@ -26,15 +26,31 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/dmi.h> #include <linux/hyperv.h>
#include <linux/pci.h>
#include "hyperv.h"
#include "hv_kvp.h" #include "hv_kvp.h"
static u8 *shut_txf_buf;
static u8 *time_txf_buf; static void shutdown_onchannelcallback(void *context);
static u8 *hbeat_txf_buf; static struct hv_util_service util_shutdown = {
.util_cb = shutdown_onchannelcallback,
};
static void timesync_onchannelcallback(void *context);
static struct hv_util_service util_timesynch = {
.util_cb = timesync_onchannelcallback,
};
static void heartbeat_onchannelcallback(void *context);
static struct hv_util_service util_heartbeat = {
.util_cb = heartbeat_onchannelcallback,
};
static struct hv_util_service util_kvp = {
.util_cb = hv_kvp_onchannelcallback,
.util_init = hv_kvp_init,
.util_deinit = hv_kvp_deinit,
};
static void shutdown_onchannelcallback(void *context) static void shutdown_onchannelcallback(void *context)
{ {
...@@ -42,6 +58,7 @@ static void shutdown_onchannelcallback(void *context) ...@@ -42,6 +58,7 @@ static void shutdown_onchannelcallback(void *context)
u32 recvlen; u32 recvlen;
u64 requestid; u64 requestid;
u8 execute_shutdown = false; u8 execute_shutdown = false;
u8 *shut_txf_buf = util_shutdown.recv_buffer;
struct shutdown_msg_data *shutdown_msg; struct shutdown_msg_data *shutdown_msg;
...@@ -56,7 +73,7 @@ static void shutdown_onchannelcallback(void *context) ...@@ -56,7 +73,7 @@ static void shutdown_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)]; sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
} else { } else {
shutdown_msg = shutdown_msg =
(struct shutdown_msg_data *)&shut_txf_buf[ (struct shutdown_msg_data *)&shut_txf_buf[
...@@ -91,7 +108,7 @@ static void shutdown_onchannelcallback(void *context) ...@@ -91,7 +108,7 @@ static void shutdown_onchannelcallback(void *context)
} }
if (execute_shutdown == true) if (execute_shutdown == true)
orderly_poweroff(false); orderly_poweroff(true);
} }
/* /*
...@@ -108,6 +125,24 @@ static inline void do_adj_guesttime(u64 hosttime) ...@@ -108,6 +125,24 @@ static inline void do_adj_guesttime(u64 hosttime)
do_settimeofday(&host_ts); do_settimeofday(&host_ts);
} }
/*
* Set the host time in a process context.
*/
struct adj_time_work {
struct work_struct work;
u64 host_time;
};
static void hv_set_host_time(struct work_struct *work)
{
struct adj_time_work *wrk;
wrk = container_of(work, struct adj_time_work, work);
do_adj_guesttime(wrk->host_time);
kfree(wrk);
}
/* /*
* Synchronize time with host after reboot, restore, etc. * Synchronize time with host after reboot, restore, etc.
* *
...@@ -121,17 +156,26 @@ static inline void do_adj_guesttime(u64 hosttime) ...@@ -121,17 +156,26 @@ static inline void do_adj_guesttime(u64 hosttime)
*/ */
static inline void adj_guesttime(u64 hosttime, u8 flags) static inline void adj_guesttime(u64 hosttime, u8 flags)
{ {
struct adj_time_work *wrk;
static s32 scnt = 50; static s32 scnt = 50;
wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
if (wrk == NULL)
return;
wrk->host_time = hosttime;
if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
do_adj_guesttime(hosttime); INIT_WORK(&wrk->work, hv_set_host_time);
schedule_work(&wrk->work);
return; return;
} }
if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
scnt--; scnt--;
do_adj_guesttime(hosttime); INIT_WORK(&wrk->work, hv_set_host_time);
} schedule_work(&wrk->work);
} else
kfree(wrk);
} }
/* /*
...@@ -144,6 +188,7 @@ static void timesync_onchannelcallback(void *context) ...@@ -144,6 +188,7 @@ static void timesync_onchannelcallback(void *context)
u64 requestid; u64 requestid;
struct icmsg_hdr *icmsghdrp; struct icmsg_hdr *icmsghdrp;
struct ictimesync_data *timedatap; struct ictimesync_data *timedatap;
u8 *time_txf_buf = util_timesynch.recv_buffer;
vmbus_recvpacket(channel, time_txf_buf, vmbus_recvpacket(channel, time_txf_buf,
PAGE_SIZE, &recvlen, &requestid); PAGE_SIZE, &recvlen, &requestid);
...@@ -153,7 +198,7 @@ static void timesync_onchannelcallback(void *context) ...@@ -153,7 +198,7 @@ static void timesync_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)]; sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
} else { } else {
timedatap = (struct ictimesync_data *)&time_txf_buf[ timedatap = (struct ictimesync_data *)&time_txf_buf[
sizeof(struct vmbuspipe_hdr) + sizeof(struct vmbuspipe_hdr) +
...@@ -182,6 +227,7 @@ static void heartbeat_onchannelcallback(void *context) ...@@ -182,6 +227,7 @@ static void heartbeat_onchannelcallback(void *context)
u64 requestid; u64 requestid;
struct icmsg_hdr *icmsghdrp; struct icmsg_hdr *icmsghdrp;
struct heartbeat_msg_data *heartbeat_msg; struct heartbeat_msg_data *heartbeat_msg;
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
vmbus_recvpacket(channel, hbeat_txf_buf, vmbus_recvpacket(channel, hbeat_txf_buf,
PAGE_SIZE, &recvlen, &requestid); PAGE_SIZE, &recvlen, &requestid);
...@@ -191,7 +237,7 @@ static void heartbeat_onchannelcallback(void *context) ...@@ -191,7 +237,7 @@ static void heartbeat_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr)]; sizeof(struct vmbuspipe_hdr)];
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
} else { } else {
heartbeat_msg = heartbeat_msg =
(struct heartbeat_msg_data *)&hbeat_txf_buf[ (struct heartbeat_msg_data *)&hbeat_txf_buf[
...@@ -210,92 +256,94 @@ static void heartbeat_onchannelcallback(void *context) ...@@ -210,92 +256,94 @@ static void heartbeat_onchannelcallback(void *context)
} }
} }
static const struct pci_device_id __initconst static int util_probe(struct hv_device *dev,
hv_utils_pci_table[] __maybe_unused = { const struct hv_vmbus_device_id *dev_id)
{ PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
{ 0 }
};
MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
static const struct dmi_system_id __initconst
hv_utils_dmi_table[] __maybe_unused = {
{
.ident = "Hyper-V",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
},
},
{ },
};
MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
static int __init init_hyperv_utils(void)
{ {
pr_info("Registering HyperV Utility Driver\n"); struct hv_util_service *srv =
(struct hv_util_service *)dev_id->driver_data;
if (hv_kvp_init()) int ret;
return -ENODEV;
if (!dmi_check_system(hv_utils_dmi_table))
return -ENODEV;
shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
pr_info("Unable to allocate memory for receive buffer\n"); if (!srv->recv_buffer)
kfree(shut_txf_buf);
kfree(time_txf_buf);
kfree(hbeat_txf_buf);
return -ENOMEM; return -ENOMEM;
if (srv->util_init) {
ret = srv->util_init(srv);
if (ret) {
ret = -ENODEV;
goto error1;
}
} }
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
srv->util_cb, dev->channel);
if (ret)
goto error;
hv_set_drvdata(dev, srv);
return 0;
hv_cb_utils[HV_TIMESYNC_MSG].callback = &timesync_onchannelcallback; error:
if (srv->util_deinit)
srv->util_deinit();
error1:
kfree(srv->recv_buffer);
return ret;
}
hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; static int util_remove(struct hv_device *dev)
{
struct hv_util_service *srv = hv_get_drvdata(dev);
hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback; vmbus_close(dev->channel);
if (srv->util_deinit)
srv->util_deinit();
kfree(srv->recv_buffer);
return 0; return 0;
} }
static void exit_hyperv_utils(void) static const struct hv_vmbus_device_id id_table[] = {
{ /* Shutdown guid */
pr_info("De-Registered HyperV Utility Driver\n"); { VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
.driver_data = (unsigned long)&util_shutdown },
/* Time synch guid */
{ VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
.driver_data = (unsigned long)&util_timesynch },
/* Heartbeat guid */
{ VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
.driver_data = (unsigned long)&util_heartbeat },
/* KVP guid */
{ VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6)
.driver_data = (unsigned long)&util_kvp },
{ },
};
if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL) MODULE_DEVICE_TABLE(vmbus, id_table);
hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
&chn_cb_negotiate;
hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL) /* The one and only one */
hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = static struct hv_driver util_drv = {
&chn_cb_negotiate; .name = "hv_util",
hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL; .id_table = id_table,
.probe = util_probe,
.remove = util_remove,
};
if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL) static int __init init_hyperv_utils(void)
hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = {
&chn_cb_negotiate; pr_info("Registering HyperV Utility Driver\n");
hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
if (hv_cb_utils[HV_KVP_MSG].channel != NULL) return vmbus_driver_register(&util_drv);
hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback = }
&chn_cb_negotiate;
hv_cb_utils[HV_KVP_MSG].callback = NULL;
hv_kvp_deinit(); static void exit_hyperv_utils(void)
{
pr_info("De-Registered HyperV Utility Driver\n");
kfree(shut_txf_buf); vmbus_driver_unregister(&util_drv);
kfree(time_txf_buf);
kfree(hbeat_txf_buf);
} }
module_init(init_hyperv_utils); module_init(init_hyperv_utils);
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <asm/sync_bitops.h> #include <asm/sync_bitops.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/hyperv.h>
#include "hyperv.h"
/* /*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
...@@ -451,8 +450,8 @@ enum { ...@@ -451,8 +450,8 @@ enum {
/* #define VMBUS_PORT_ID 11 */ /* #define VMBUS_PORT_ID 11 */
/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ /* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
static const struct hv_guid VMBUS_SERVICE_ID = { static const uuid_le VMBUS_SERVICE_ID = {
.data = { .b = {
0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
}, },
...@@ -530,8 +529,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info, ...@@ -530,8 +529,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info); u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
struct hv_ring_buffer_debug_info *debug_info); struct hv_ring_buffer_debug_info *debug_info);
...@@ -601,12 +598,12 @@ extern struct vmbus_connection vmbus_connection; ...@@ -601,12 +598,12 @@ extern struct vmbus_connection vmbus_connection;
/* General vmbus interface */ /* General vmbus interface */
struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_device *vmbus_device_create(uuid_le *type,
struct hv_guid *instance, uuid_le *instance,
struct vmbus_channel *channel); struct vmbus_channel *channel);
int vmbus_child_device_register(struct hv_device *child_device_obj); int vmbus_device_register(struct hv_device *child_device_obj);
void vmbus_child_device_unregister(struct hv_device *device_obj); void vmbus_device_unregister(struct hv_device *device_obj);
/* static void */ /* static void */
/* VmbusChildDeviceDestroy( */ /* VmbusChildDeviceDestroy( */
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hyperv.h>
#include "hyperv.h"
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
/* Amount of space to write to */ /* Amount of space to write to */
#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) #define BYTES_AVAIL_TO_WRITE(r, w, z) \
((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
/* /*
...@@ -171,37 +172,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info) ...@@ -171,37 +172,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
return (u64)ring_info->ring_buffer->write_index << 32; return (u64)ring_info->ring_buffer->write_index << 32;
} }
/*
*
* hv_dump_ring_info()
*
* Dump out to console the ring buffer info
*
*/
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
{
u32 bytes_avail_towrite;
u32 bytes_avail_toread;
hv_get_ringbuffer_availbytes(ring_info,
&bytes_avail_toread,
&bytes_avail_towrite);
DPRINT(VMBUS,
DEBUG_RING_LVL,
"%s <<ringinfo %p buffer %p avail write %u "
"avail read %u read idx %u write idx %u>>",
prefix,
ring_info,
ring_info->ring_buffer->buffer,
bytes_avail_towrite,
bytes_avail_toread,
ring_info->ring_buffer->read_index,
ring_info->ring_buffer->write_index);
}
/* /*
* *
* hv_copyfrom_ringbuffer() * hv_copyfrom_ringbuffer()
...@@ -390,7 +360,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, ...@@ -390,7 +360,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
/* is empty since the read index == write index */ /* is empty since the read index == write index */
if (bytes_avail_towrite <= totalbytes_towrite) { if (bytes_avail_towrite <= totalbytes_towrite) {
spin_unlock_irqrestore(&outring_info->ring_lock, flags); spin_unlock_irqrestore(&outring_info->ring_lock, flags);
return -1; return -EAGAIN;
} }
/* Write to the ring buffer */ /* Write to the ring buffer */
...@@ -450,7 +420,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, ...@@ -450,7 +420,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
spin_unlock_irqrestore(&Inring_info->ring_lock, flags); spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
return -1; return -EAGAIN;
} }
/* Convert to byte offset */ /* Convert to byte offset */
...@@ -496,7 +466,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, ...@@ -496,7 +466,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
if (bytes_avail_toread < buflen) { if (bytes_avail_toread < buflen) {
spin_unlock_irqrestore(&inring_info->ring_lock, flags); spin_unlock_irqrestore(&inring_info->ring_lock, flags);
return -1; return -EAGAIN;
} }
next_read_location = next_read_location =
......
...@@ -46,8 +46,6 @@ source "drivers/staging/wlan-ng/Kconfig" ...@@ -46,8 +46,6 @@ source "drivers/staging/wlan-ng/Kconfig"
source "drivers/staging/echo/Kconfig" source "drivers/staging/echo/Kconfig"
source "drivers/staging/comedi/Kconfig" source "drivers/staging/comedi/Kconfig"
source "drivers/staging/olpc_dcon/Kconfig" source "drivers/staging/olpc_dcon/Kconfig"
...@@ -66,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig" ...@@ -66,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rts_pstor/Kconfig" source "drivers/staging/rts_pstor/Kconfig"
source "drivers/staging/rts5139/Kconfig"
source "drivers/staging/frontier/Kconfig" source "drivers/staging/frontier/Kconfig"
source "drivers/staging/pohmelfs/Kconfig" source "drivers/staging/pohmelfs/Kconfig"
......
...@@ -15,8 +15,6 @@ obj-$(CONFIG_USBIP_CORE) += usbip/ ...@@ -15,8 +15,6 @@ obj-$(CONFIG_USBIP_CORE) += usbip/
obj-$(CONFIG_W35UND) += winbond/ obj-$(CONFIG_W35UND) += winbond/
obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_ASUS_OLED) += asus_oled/ obj-$(CONFIG_ASUS_OLED) += asus_oled/
...@@ -26,6 +24,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/ ...@@ -26,6 +24,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
obj-$(CONFIG_RTS5139) += rts5139/
obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_SPECTRA) += spectra/
obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_POHMELFS) += pohmelfs/
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h>
#include "altera.h" #include "altera.h"
#include "altera-exprt.h" #include "altera-exprt.h"
#include "altera-jtag.h" #include "altera-jtag.h"
...@@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p, ...@@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p,
act_proc_attribute = act_proc_attribute =
(p[proc_table + (13 * act_proc_id) + 8] & 0x03); (p[proc_table + (13 * act_proc_id) + 8] & 0x03);
procptr = (struct altera_procinfo *) procptr =
kzalloc(sizeof(struct altera_procinfo), kzalloc(sizeof(struct altera_procinfo),
GFP_KERNEL); GFP_KERNEL);
......
此差异已折叠。
此差异已折叠。
...@@ -139,8 +139,7 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) ...@@ -139,8 +139,7 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE); BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE);
} }
static int static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
int retval; int retval;
...@@ -281,8 +280,9 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -281,8 +280,9 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
int i = 0; int i = 0;
for (i = 0; i < MAXIMUM_USB_TCB; i++) { for (i = 0; i < MAXIMUM_USB_TCB; i++) {
if ((psIntfAdapter->asUsbTcb[i].urb = psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
if (psIntfAdapter->asUsbTcb[i].urb == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
"Can't allocate Tx urb for index %d\n", i); "Can't allocate Tx urb for index %d\n", i);
return -ENOMEM; return -ENOMEM;
...@@ -290,14 +290,17 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -290,14 +290,17 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
} }
for (i = 0; i < MAXIMUM_USB_RCB; i++) { for (i = 0; i < MAXIMUM_USB_RCB; i++) {
if ((psIntfAdapter->asUsbRcb[i].urb = psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
if (psIntfAdapter->asUsbRcb[i].urb == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
"Can't allocate Rx urb for index %d\n", i); "Can't allocate Rx urb for index %d\n", i);
return -ENOMEM; return -ENOMEM;
} }
if ((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer =
kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) { psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
"Can't allocate Rx buffer for index %d\n", i); "Can't allocate Rx buffer for index %d\n", i);
return -ENOMEM; return -ENOMEM;
...@@ -389,32 +392,32 @@ static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descripto ...@@ -389,32 +392,32 @@ static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descripto
static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd)); return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd);
} }
static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd)); return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd);
} }
static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd)); return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd);
} }
static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd)); return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd);
} }
static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd)); return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd);
} }
static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
{ {
return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
} }
static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
...@@ -462,7 +465,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -462,7 +465,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
if (bBcm16 == TRUE) { if (bBcm16 == TRUE) {
/* selecting alternate setting one as a default setting for High Speed modem. */ /* selecting alternate setting one as a default setting for High Speed modem. */
if (psIntfAdapter->bHighSpeedDevice) if (psIntfAdapter->bHighSpeedDevice)
retval= usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1); retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
"BCM16 is applicable on this dongle\n"); "BCM16 is applicable on this dongle\n");
if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) { if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) {
...@@ -497,7 +500,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -497,7 +500,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) { if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
/* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */ /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
UINT _uiData = ntohl(EP2_CFG_INT); UINT _uiData = ntohl(EP2_CFG_INT);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
"Reverting Bulk to INT as it is in Full Speed mode.\n"); "Reverting Bulk to INT as it is in Full Speed mode.\n");
BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE); BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE);
} }
...@@ -579,7 +582,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -579,7 +582,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
psIntfAdapter->sIntrOut.int_out_size = buffer_size; psIntfAdapter->sIntrOut.int_out_size = buffer_size;
psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress; psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress;
psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval;
psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, GFP_KERNEL); psIntfAdapter->sIntrOut.int_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!psIntfAdapter->sIntrOut.int_out_buffer) { if (!psIntfAdapter->sIntrOut.int_out_buffer) {
dev_err(&psIntfAdapter->udev->dev, dev_err(&psIntfAdapter->udev->dev,
"could not allocate interrupt_out_buffer\n"); "could not allocate interrupt_out_buffer\n");
...@@ -641,8 +644,8 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) ...@@ -641,8 +644,8 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
static int InterfaceResume(struct usb_interface *intf) static int InterfaceResume(struct usb_interface *intf)
{ {
PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
mdelay(100);
mdelay(100);
psIntfAdapter->bSuspended = FALSE; psIntfAdapter->bSuspended = FALSE;
StartInterruptUrb(psIntfAdapter); StartInterruptUrb(psIntfAdapter);
......
#include "headers.h" #include "headers.h"
INT INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr,
UINT addr, PVOID buff,
PVOID buff, INT len)
INT len)
{ {
int retval = 0; int retval = 0;
USHORT usRetries = 0 ; USHORT usRetries = 0;
if(psIntfAdapter == NULL )
{ if (psIntfAdapter == NULL) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL"); BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
return -EINVAL ; return -EINVAL;
} }
if(psIntfAdapter->psAdapter->device_removed == TRUE) if (psIntfAdapter->psAdapter->device_removed == TRUE) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
return -ENODEV; return -ENODEV;
} }
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus");
return -EACCES; return -EACCES;
} }
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
return -EACCES; return -EACCES;
} }
psIntfAdapter->psAdapter->DeviceAccess = TRUE ; psIntfAdapter->psAdapter->DeviceAccess = TRUE;
do { do {
retval = usb_control_msg(psIntfAdapter->udev, retval = usb_control_msg(psIntfAdapter->udev,
usb_rcvctrlpipe(psIntfAdapter->udev,0), usb_rcvctrlpipe(psIntfAdapter->udev, 0),
0x02, 0x02,
0xC2, 0xC2,
(addr & 0xFFFF), (addr & 0xFFFF),
((addr >> 16) & 0xFFFF), ((addr >> 16) & 0xFFFF),
buff, buff,
len, len,
5000); 5000);
usRetries++ ; usRetries++;
if(-ENODEV == retval) if (-ENODEV == retval) {
{ psIntfAdapter->psAdapter->device_removed = TRUE;
psIntfAdapter->psAdapter->device_removed =TRUE;
break; break;
} }
}while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) ); } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
if(retval < 0) if (retval < 0) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval, usRetries);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries); psIntfAdapter->psAdapter->DeviceAccess = FALSE;
psIntfAdapter->psAdapter->DeviceAccess = FALSE ; return retval;
return retval; } else {
} BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
else psIntfAdapter->psAdapter->DeviceAccess = FALSE;
{ return STATUS_SUCCESS;
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
return STATUS_SUCCESS;
} }
} }
INT INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr,
UINT addr, PVOID buff,
PVOID buff, INT len)
INT len)
{ {
int retval = 0; int retval = 0;
USHORT usRetries = 0 ; USHORT usRetries = 0;
if(psIntfAdapter == NULL ) if (psIntfAdapter == NULL) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
return -EINVAL; return -EINVAL;
} }
if(psIntfAdapter->psAdapter->device_removed == TRUE)
{
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed"); if (psIntfAdapter->psAdapter->device_removed == TRUE) {
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
return -ENODEV; return -ENODEV;
} }
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus...");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
return -EACCES; return -EACCES;
} }
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
return -EACCES; return -EACCES;
} }
psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
do{ psIntfAdapter->psAdapter->DeviceAccess = TRUE;
do {
retval = usb_control_msg(psIntfAdapter->udev, retval = usb_control_msg(psIntfAdapter->udev,
usb_sndctrlpipe(psIntfAdapter->udev,0), usb_sndctrlpipe(psIntfAdapter->udev, 0),
0x01, 0x01,
0x42, 0x42,
(addr & 0xFFFF), (addr & 0xFFFF),
((addr >> 16) & 0xFFFF), ((addr >> 16) & 0xFFFF),
buff, buff,
len, len,
5000); 5000);
usRetries++ ; usRetries++;
if(-ENODEV == retval) if (-ENODEV == retval) {
{ psIntfAdapter->psAdapter->device_removed = TRUE;
psIntfAdapter->psAdapter->device_removed = TRUE ;
break; break;
} }
}while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES)); } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
if(retval < 0) if (retval < 0) {
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries); psIntfAdapter->psAdapter->DeviceAccess = FALSE;
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
return retval; return retval;
} } else {
else psIntfAdapter->psAdapter->DeviceAccess = FALSE;
{ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
INT INT BcmRDM(PVOID arg,
BcmRDM(PVOID arg, UINT addr,
UINT addr, PVOID buff,
PVOID buff, INT len)
INT len)
{ {
return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
} }
INT INT BcmWRM(PVOID arg,
BcmWRM(PVOID arg, UINT addr,
UINT addr, PVOID buff,
PVOID buff, INT len)
INT len)
{ {
return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
} }
INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter) INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter)
{ {
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
INT status = STATUS_SUCCESS ; INT status = STATUS_SUCCESS;
/* /*
usb_clear_halt - tells device to clear endpoint halt/stall condition * usb_clear_halt - tells device to clear endpoint halt/stall condition
@dev: device whose endpoint is halted * @dev: device whose endpoint is halted
@pipe: endpoint "pipe" being cleared * @pipe: endpoint "pipe" being cleared
@ Context: !in_interrupt () * @ Context: !in_interrupt ()
*
usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code. * usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
This is used to clear halt conditions for bulk and interrupt endpoints only. * This is used to clear halt conditions for bulk and interrupt endpoints only.
Control and isochronous endpoints never halts. * Control and isochronous endpoints never halts.
*
Any URBs queued for such an endpoint should normally be unlinked by the driver * Any URBs queued for such an endpoint should normally be unlinked by the driver
before clearing the halt condition. * before clearing the halt condition.
*
*/ */
//Killing all the submitted urbs to different end points. /* Killing all the submitted urbs to different end points. */
Bcm_kill_all_URBs(psIntfAdapter); Bcm_kill_all_URBs(psIntfAdapter);
/* clear the halted/stalled state for every end point */
status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sIntrIn.int_in_pipe);
if (status != STATUS_SUCCESS)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
//clear the halted/stalled state for every end point status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_pipe);
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe); if (status != STATUS_SUCCESS)
if(status != STATUS_SUCCESS) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe); status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe);
if(status != STATUS_SUCCESS) if (status != STATUS_SUCCESS)
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe); return status;
if(status != STATUS_SUCCESS)
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
return status ;
} }
VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
{ {
struct urb *tempUrb = NULL; struct urb *tempUrb = NULL;
UINT i; UINT i;
/** /*
* usb_kill_urb - cancel a transfer request and wait for it to finish * usb_kill_urb - cancel a transfer request and wait for it to finish
* @urb: pointer to URB describing a previously submitted request, * @urb: pointer to URB describing a previously submitted request,
* returns nothing as it is void returned API. * returns nothing as it is void returned API.
* *
* This routine cancels an in-progress request. It is guaranteed that * This routine cancels an in-progress request. It is guaranteed that
* upon return all completion handlers will have finished and the URB * upon return all completion handlers will have finished and the URB
* will be totally idle and available for reuse * will be totally idle and available for reuse
*
* This routine may not be used in an interrupt context (such as a bottom * This routine may not be used in an interrupt context (such as a bottom
* half or a completion handler), or when holding a spinlock, or in other * half or a completion handler), or when holding a spinlock, or in other
* situations where the caller can't schedule(). * situations where the caller can't schedule().
* *
**/ */
/* Cancel submitted Interrupt-URB's */ /* Cancel submitted Interrupt-URB's */
if(psIntfAdapter->psInterruptUrb != NULL) if (psIntfAdapter->psInterruptUrb != NULL) {
{ if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) usb_kill_urb(psIntfAdapter->psInterruptUrb);
usb_kill_urb(psIntfAdapter->psInterruptUrb);
} }
/* Cancel All submitted TX URB's */ /* Cancel All submitted TX URB's */
for(i = 0; i < MAXIMUM_USB_TCB; i++) for (i = 0; i < MAXIMUM_USB_TCB; i++) {
{
tempUrb = psIntfAdapter->asUsbTcb[i].urb; tempUrb = psIntfAdapter->asUsbTcb[i].urb;
if(tempUrb) if (tempUrb) {
{ if (tempUrb->status == -EINPROGRESS)
if(tempUrb->status == -EINPROGRESS)
usb_kill_urb(tempUrb); usb_kill_urb(tempUrb);
} }
} }
for(i = 0; i < MAXIMUM_USB_RCB; i++) for (i = 0; i < MAXIMUM_USB_RCB; i++) {
{
tempUrb = psIntfAdapter->asUsbRcb[i].urb; tempUrb = psIntfAdapter->asUsbRcb[i].urb;
if(tempUrb) if (tempUrb) {
{ if (tempUrb->status == -EINPROGRESS)
if(tempUrb->status == -EINPROGRESS) usb_kill_urb(tempUrb);
usb_kill_urb(tempUrb);
} }
} }
...@@ -253,13 +226,12 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) ...@@ -253,13 +226,12 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
VOID putUsbSuspend(struct work_struct *work) VOID putUsbSuspend(struct work_struct *work)
{ {
PS_INTERFACE_ADAPTER psIntfAdapter = NULL ; PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
struct usb_interface *intf = NULL ; struct usb_interface *intf = NULL;
psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork); psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork);
intf=psIntfAdapter->interface ; intf = psIntfAdapter->interface;
if(psIntfAdapter->bSuspended == FALSE) if (psIntfAdapter->bSuspended == FALSE)
usb_autopm_put_interface(intf); usb_autopm_put_interface(intf);
} }
/************************************* /*************************************
* Macros.h * Macros.h
**************************************/ **************************************/
#ifndef __MACROS_H__ #ifndef __MACROS_H__
#define __MACROS_H__ #define __MACROS_H__
#define TX_TIMER_PERIOD 10 //10 msec #define TX_TIMER_PERIOD 10 /*10 msec*/
#define MAX_CLASSIFIERS 100 #define MAX_CLASSIFIERS 100
//#define MAX_CLASSIFIERS_PER_SF 20 /* #define MAX_CLASSIFIERS_PER_SF 20 */
#define MAX_TARGET_DSX_BUFFERS 24 #define MAX_TARGET_DSX_BUFFERS 24
#define MAX_CNTRL_PKTS 100 #define MAX_CNTRL_PKTS 100
#define MAX_DATA_PKTS 200 #define MAX_DATA_PKTS 200
#define MAX_ETH_SIZE 1536 #define MAX_ETH_SIZE 1536
#define MAX_CNTL_PKT_SIZE 2048 #define MAX_CNTL_PKT_SIZE 2048
#define MTU_SIZE 1400 #define MTU_SIZE 1400
...@@ -20,102 +20,102 @@ ...@@ -20,102 +20,102 @@
#define MAC_ADDR_REGISTER 0xbf60d000 #define MAC_ADDR_REGISTER 0xbf60d000
///////////Quality of Service/////////////////////////// /* Quality of Service */
#define NO_OF_QUEUES 17 #define NO_OF_QUEUES 17
#define HiPriority NO_OF_QUEUES-1 #define HiPriority (NO_OF_QUEUES-1)
#define LowPriority 0 #define LowPriority 0
#define BE 2 #define BE 2
#define rtPS 4 #define rtPS 4
#define ERTPS 5 #define ERTPS 5
#define UGS 6 #define UGS 6
#define BE_BUCKET_SIZE 1024*1024*100 //32kb #define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */
#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb #define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */
#define MAX_ALLOWED_RATE 1024*1024*100 #define MAX_ALLOWED_RATE (1024*1024*100)
#define TX_PACKET_THRESHOLD 10 #define TX_PACKET_THRESHOLD 10
#define XSECONDS 1*HZ #define XSECONDS (1*HZ)
#define DSC_ACTIVATE_REQUEST 248 #define DSC_ACTIVATE_REQUEST 248
#define QUEUE_DEPTH_OFFSET 0x1fc01000 #define QUEUE_DEPTH_OFFSET 0x1fc01000
#define MAX_DEVICE_DESC_SIZE 2040 #define MAX_DEVICE_DESC_SIZE 2040
#define MAX_CTRL_QUEUE_LEN 100 #define MAX_CTRL_QUEUE_LEN 100
#define MAX_APP_QUEUE_LEN 200 #define MAX_APP_QUEUE_LEN 200
#define MAX_LATENCY_ALLOWED 0xFFFFFFFF #define MAX_LATENCY_ALLOWED 0xFFFFFFFF
#define DEFAULT_UG_INTERVAL 250 #define DEFAULT_UG_INTERVAL 250
#define DEFAULT_UGI_FACTOR 4 #define DEFAULT_UGI_FACTOR 4
#define DEFAULT_PERSFCOUNT 60 #define DEFAULT_PERSFCOUNT 60
#define MAX_CONNECTIONS 10 #define MAX_CONNECTIONS 10
#define MAX_CLASS_NAME_LENGTH 32 #define MAX_CLASS_NAME_LENGTH 32
#define ETH_LENGTH_OF_ADDRESS 6 #define ETH_LENGTH_OF_ADDRESS 6
#define MAX_MULTICAST_ADDRESSES 32 #define MAX_MULTICAST_ADDRESSES 32
#define IP_LENGTH_OF_ADDRESS 4 #define IP_LENGTH_OF_ADDRESS 4
#define IP_PACKET_ONLY_MODE 0 #define IP_PACKET_ONLY_MODE 0
#define ETH_PACKET_TUNNELING_MODE 1 #define ETH_PACKET_TUNNELING_MODE 1
////////////Link Request////////////// /* Link Request */
#define SET_MAC_ADDRESS_REQUEST 0 #define SET_MAC_ADDRESS_REQUEST 0
#define SYNC_UP_REQUEST 1 #define SYNC_UP_REQUEST 1
#define SYNCED_UP 2 #define SYNCED_UP 2
#define LINK_UP_REQUEST 3 #define LINK_UP_REQUEST 3
#define LINK_CONNECTED 4 #define LINK_CONNECTED 4
#define SYNC_UP_NOTIFICATION 2 #define SYNC_UP_NOTIFICATION 2
#define LINK_UP_NOTIFICATION 4 #define LINK_UP_NOTIFICATION 4
#define LINK_NET_ENTRY 0x0002 #define LINK_NET_ENTRY 0x0002
#define HMC_STATUS 0x0004 #define HMC_STATUS 0x0004
#define LINK_UP_CONTROL_REQ 0x83 #define LINK_UP_CONTROL_REQ 0x83
#define STATS_POINTER_REQ_STATUS 0x86 #define STATS_POINTER_REQ_STATUS 0x86
#define NETWORK_ENTRY_REQ_PAYLOAD 198 #define NETWORK_ENTRY_REQ_PAYLOAD 198
#define LINK_DOWN_REQ_PAYLOAD 226 #define LINK_DOWN_REQ_PAYLOAD 226
#define SYNC_UP_REQ_PAYLOAD 228 #define SYNC_UP_REQ_PAYLOAD 228
#define STATISTICS_POINTER_REQ 237 #define STATISTICS_POINTER_REQ 237
#define LINK_UP_REQ_PAYLOAD 245 #define LINK_UP_REQ_PAYLOAD 245
#define LINK_UP_ACK 246 #define LINK_UP_ACK 246
#define STATS_MSG_SIZE 4 #define STATS_MSG_SIZE 4
#define INDEX_TO_DATA 4 #define INDEX_TO_DATA 4
#define GO_TO_IDLE_MODE_PAYLOAD 210 #define GO_TO_IDLE_MODE_PAYLOAD 210
#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 #define COME_UP_FROM_IDLE_MODE_PAYLOAD 211
#define IDLE_MODE_SF_UPDATE_MSG 187 #define IDLE_MODE_SF_UPDATE_MSG 187
#define SKB_RESERVE_ETHERNET_HEADER 16 #define SKB_RESERVE_ETHERNET_HEADER 16
#define SKB_RESERVE_PHS_BYTES 32 #define SKB_RESERVE_PHS_BYTES 32
#define IP_PACKET_ONLY_MODE 0 #define IP_PACKET_ONLY_MODE 0
#define ETH_PACKET_TUNNELING_MODE 1 #define ETH_PACKET_TUNNELING_MODE 1
#define ETH_CS_802_3 1 #define ETH_CS_802_3 1
#define ETH_CS_802_1Q_VLAN 3 #define ETH_CS_802_1Q_VLAN 3
#define IPV4_CS 1 #define IPV4_CS 1
#define IPV6_CS 2 #define IPV6_CS 2
#define ETH_CS_MASK 0x3f #define ETH_CS_MASK 0x3f
/** \brief Validity bit maps for TLVs in packet classification rule */ /** \brief Validity bit maps for TLVs in packet classification rule */
#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 #define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0
#define PKT_CLASSIFICATION_VLANID_VALID 1 #define PKT_CLASSIFICATION_VLANID_VALID 1
#ifndef MIN #ifndef MIN
#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b)) #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#endif #endif
/*Leader related terms */ /*Leader related terms */
#define LEADER_STATUS 0x00 #define LEADER_STATUS 0x00
#define LEADER_STATUS_TCP_ACK 0x1 #define LEADER_STATUS_TCP_ACK 0x1
#define LEADER_SIZE sizeof(LEADER) #define LEADER_SIZE sizeof(LEADER)
#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) #define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND)
#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) #define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND)
#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest) #define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest))
#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) #define IDLE_REQ_SIZE sizeof(PACKETTOSEND)
#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024 #define MAX_TRANSFER_CTRL_BYTE_USB (2*1024)
#define GET_MAILBOX1_REG_REQUEST 0x87 #define GET_MAILBOX1_REG_REQUEST 0x87
#define GET_MAILBOX1_REG_RESPONSE 0x67 #define GET_MAILBOX1_REG_RESPONSE 0x67
...@@ -124,40 +124,40 @@ ...@@ -124,40 +124,40 @@
#define TRANSMIT_NETWORK_DATA 0x00 #define TRANSMIT_NETWORK_DATA 0x00
#define RECEIVED_NETWORK_DATA 0x20 #define RECEIVED_NETWORK_DATA 0x20
#define CM_RESPONSES 0xA0 #define CM_RESPONSES 0xA0
#define STATUS_RSP 0xA1 #define STATUS_RSP 0xA1
#define LINK_CONTROL_RESP 0xA2 #define LINK_CONTROL_RESP 0xA2
#define IDLE_MODE_STATUS 0xA3 #define IDLE_MODE_STATUS 0xA3
#define STATS_POINTER_RESP 0xA6 #define STATS_POINTER_RESP 0xA6
#define MGMT_MSG_INFO_SW_STATUS 0xA7 #define MGMT_MSG_INFO_SW_STATUS 0xA7
#define AUTH_SS_HOST_MSG 0xA8 #define AUTH_SS_HOST_MSG 0xA8
#define CM_DSA_ACK_PAYLOAD 247 #define CM_DSA_ACK_PAYLOAD 247
#define CM_DSC_ACK_PAYLOAD 248 #define CM_DSC_ACK_PAYLOAD 248
#define CM_DSD_ACK_PAYLOAD 249 #define CM_DSD_ACK_PAYLOAD 249
#define CM_DSDEACTVATE 250 #define CM_DSDEACTVATE 250
#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 #define TOTAL_MASKED_ADDRESS_IN_BYTES 32
#define MAC_REQ 0 #define MAC_REQ 0
#define LINK_RESP 1 #define LINK_RESP 1
#define RSSI_INDICATION 2 #define RSSI_INDICATION 2
#define SS_INFO 4 #define SS_INFO 4
#define STATISTICS_INFO 5 #define STATISTICS_INFO 5
#define CM_INDICATION 6 #define CM_INDICATION 6
#define PARAM_RESP 7 #define PARAM_RESP 7
#define BUFFER_1K 1024 #define BUFFER_1K 1024
#define BUFFER_2K BUFFER_1K*2 #define BUFFER_2K (BUFFER_1K*2)
#define BUFFER_4K BUFFER_2K*2 #define BUFFER_4K (BUFFER_2K*2)
#define BUFFER_8K BUFFER_4K*2 #define BUFFER_8K (BUFFER_4K*2)
#define BUFFER_16K BUFFER_8K*2 #define BUFFER_16K (BUFFER_8K*2)
#define DOWNLINK_DIR 0 #define DOWNLINK_DIR 0
#define UPLINK_DIR 1 #define UPLINK_DIR 1
#define BCM_SIGNATURE "BECEEM" #define BCM_SIGNATURE "BECEEM"
#define GPIO_OUTPUT_REGISTER 0x0F00003C #define GPIO_OUTPUT_REGISTER 0x0F00003C
#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 #define BCM_GPIO_OUTPUT_SET_REG 0x0F000040
#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 #define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044
#define GPIO_MODE_REGISTER 0x0F000034 #define GPIO_MODE_REGISTER 0x0F000034
...@@ -165,44 +165,43 @@ ...@@ -165,44 +165,43 @@
typedef struct _LINK_STATE { typedef struct _LINK_STATE {
UCHAR ucLinkStatus; UCHAR ucLinkStatus;
UCHAR bIdleMode; UCHAR bIdleMode;
UCHAR bShutdownMode; UCHAR bShutdownMode;
}LINK_STATE, *PLINK_STATE; } LINK_STATE, *PLINK_STATE;
enum enLinkStatus { enum enLinkStatus {
WAIT_FOR_SYNC = 1, WAIT_FOR_SYNC = 1,
PHY_SYNC_ACHIVED = 2, PHY_SYNC_ACHIVED = 2,
LINKUP_IN_PROGRESS = 3, LINKUP_IN_PROGRESS = 3,
LINKUP_DONE = 4, LINKUP_DONE = 4,
DREG_RECEIVED = 5, DREG_RECEIVED = 5,
LINK_STATUS_RESET_RECEIVED = 6, LINK_STATUS_RESET_RECEIVED = 6,
PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7,
LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8,
COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9 COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW = 9
}; };
typedef enum _E_PHS_DSC_ACTION typedef enum _E_PHS_DSC_ACTION {
{ eAddPHSRule = 0,
eAddPHSRule=0,
eSetPHSRule, eSetPHSRule,
eDeletePHSRule, eDeletePHSRule,
eDeleteAllPHSRules eDeleteAllPHSRules
}E_PHS_DSC_ACTION; } E_PHS_DSC_ACTION;
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac #define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host #define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */
#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000 #define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */
#define MINIMUM_PENDING_DESCRIPTORS 5 #define MINIMUM_PENDING_DESCRIPTORS 5
#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC #define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC
#define SHUTDOWN_ACK_FROM_DRIVER 0x1 #define SHUTDOWN_ACK_FROM_DRIVER 0x1
#define SHUTDOWN_NACK_FROM_DRIVER 0x2 #define SHUTDOWN_NACK_FROM_DRIVER 0x2
#define LINK_SYNC_UP_SUBTYPE 0x0001 #define LINK_SYNC_UP_SUBTYPE 0x0001
#define LINK_SYNC_DOWN_SUBTYPE 0x0001 #define LINK_SYNC_DOWN_SUBTYPE 0x0001
...@@ -226,9 +225,9 @@ typedef enum _E_PHS_DSC_ACTION ...@@ -226,9 +225,9 @@ typedef enum _E_PHS_DSC_ACTION
#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) #define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10)
#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) #define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN)
#define AUTO_LINKUP_ENABLE 0x2 #define AUTO_LINKUP_ENABLE 0x2
#define AUTO_SYNC_DISABLE 0x1 #define AUTO_SYNC_DISABLE 0x1
#define AUTO_FIRM_DOWNLOAD 0x1 #define AUTO_FIRM_DOWNLOAD 0x1
#define SETTLE_DOWN_TIME 50 #define SETTLE_DOWN_TIME 50
...@@ -242,9 +241,9 @@ typedef enum _E_PHS_DSC_ACTION ...@@ -242,9 +241,9 @@ typedef enum _E_PHS_DSC_ACTION
#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 #define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3
#define IDLE_MODE_PAYLOAD_LENGTH 8 #define IDLE_MODE_PAYLOAD_LENGTH 8
#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer)) #define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer))
#define IPV4 4 #define IPV4 4
#define IP_VERSION(byte) (((byte&0xF0)>>4)) #define IP_VERSION(byte) (((byte&0xF0)>>4))
#define SET_MAC_ADDRESS 193 #define SET_MAC_ADDRESS 193
#define SET_MAC_ADDRESS_RESPONSE 236 #define SET_MAC_ADDRESS_RESPONSE 236
...@@ -263,15 +262,15 @@ typedef enum _E_PHS_DSC_ACTION ...@@ -263,15 +262,15 @@ typedef enum _E_PHS_DSC_ACTION
#define INVALID_QUEUE_INDEX NO_OF_QUEUES #define INVALID_QUEUE_INDEX NO_OF_QUEUES
#define INVALID_PID (pid_t)-1 #define INVALID_PID ((pid_t)-1)
#define DDR_80_MHZ 0 #define DDR_80_MHZ 0
#define DDR_100_MHZ 1 #define DDR_100_MHZ 1
#define DDR_120_MHZ 2 // Additional Frequency for T3LP #define DDR_120_MHZ 2 /* Additional Frequency for T3LP */
#define DDR_133_MHZ 3 #define DDR_133_MHZ 3
#define DDR_140_MHZ 4 // Not Used (Reserved for future) #define DDR_140_MHZ 4 /* Not Used (Reserved for future) */
#define DDR_160_MHZ 5 // Additional Frequency for T3LP #define DDR_160_MHZ 5 /* Additional Frequency for T3LP */
#define DDR_180_MHZ 6 // Not Used (Reserved for future) #define DDR_180_MHZ 6 /* Not Used (Reserved for future) */
#define DDR_200_MHZ 7 // Not Used (Reserved for future) #define DDR_200_MHZ 7 /* Not Used (Reserved for future) */
#define MIPS_200_MHZ 0 #define MIPS_200_MHZ 0
#define MIPS_160_MHZ 1 #define MIPS_160_MHZ 1
...@@ -291,27 +290,27 @@ typedef enum _E_PHS_DSC_ACTION ...@@ -291,27 +290,27 @@ typedef enum _E_PHS_DSC_ACTION
#define EEPROM_REJECT_REG_3 0x0f003008 #define EEPROM_REJECT_REG_3 0x0f003008
#define EEPROM_REJECT_REG_4 0x0f003020 #define EEPROM_REJECT_REG_4 0x0f003020
#define EEPROM_REJECT_MASK 0x0fffffff #define EEPROM_REJECT_MASK 0x0fffffff
#define VSG_MODE 0x3 #define VSG_MODE 0x3
/* Idle Mode Related Registers */ /* Idle Mode Related Registers */
#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C #define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC #define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e #define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
#define DEVICE_INT_OUT_EP_REG0 0x0F011870 #define DEVICE_INT_OUT_EP_REG0 0x0F011870
#define DEVICE_INT_OUT_EP_REG1 0x0F011874 #define DEVICE_INT_OUT_EP_REG1 0x0F011874
#define BIN_FILE "/lib/firmware/macxvi200.bin" #define BIN_FILE "/lib/firmware/macxvi200.bin"
#define CFG_FILE "/lib/firmware/macxvi.cfg" #define CFG_FILE "/lib/firmware/macxvi.cfg"
#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 #define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128
#define MIN_VAL(x,y) ((x)<(y)?(x):(y)) #define MIN_VAL(x, y) ((x) < (y) ? (x) : (y))
#define MAC_ADDRESS_SIZE 6 #define MAC_ADDRESS_SIZE 6
#define EEPROM_COMMAND_Q_REG 0x0F003018 #define EEPROM_COMMAND_Q_REG 0x0F003018
#define EEPROM_READ_DATA_Q_REG 0x0F003020 #define EEPROM_READ_DATA_Q_REG 0x0F003020
#define CHIP_ID_REG 0x0F000000 #define CHIP_ID_REG 0x0F000000
#define GPIO_MODE_REG 0x0F000034 #define GPIO_MODE_REG 0x0F000034
#define GPIO_OUTPUT_REG 0x0F00003C #define GPIO_OUTPUT_REG 0x0F00003C
#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50 #define WIMAX_MAX_ALLOWED_RATE (1024*1024*50)
#define T3 0xbece0300 #define T3 0xbece0300
#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 #define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400
...@@ -319,31 +318,29 @@ typedef enum _E_PHS_DSC_ACTION ...@@ -319,31 +318,29 @@ typedef enum _E_PHS_DSC_ACTION
#define RWM_READ 0 #define RWM_READ 0
#define RWM_WRITE 1 #define RWM_WRITE 1
#define T3LPB 0xbece3300 #define T3LPB 0xbece3300
#define BCS220_2 0xbece3311 #define BCS220_2 0xbece3311
#define BCS220_2BC 0xBECE3310 #define BCS220_2BC 0xBECE3310
#define BCS250_BC 0xbece3301 #define BCS250_BC 0xbece3301
#define BCS220_3 0xbece3321 #define BCS220_3 0xbece3321
#define HPM_CONFIG_LDO145 0x0F000D54 #define HPM_CONFIG_LDO145 0x0F000D54
#define HPM_CONFIG_MSW 0x0F000D58 #define HPM_CONFIG_MSW 0x0F000D58
#define T3B 0xbece0310 #define T3B 0xbece0310
typedef enum eNVM_TYPE typedef enum eNVM_TYPE {
{
NVM_AUTODETECT = 0, NVM_AUTODETECT = 0,
NVM_EEPROM, NVM_EEPROM,
NVM_FLASH, NVM_FLASH,
NVM_UNKNOWN NVM_UNKNOWN
}NVM_TYPE; } NVM_TYPE;
typedef enum ePMU_MODES typedef enum ePMU_MODES {
{
HYBRID_MODE_7C = 0, HYBRID_MODE_7C = 0,
INTERNAL_MODE_6 = 1, INTERNAL_MODE_6 = 1,
HYBRID_MODE_6 = 2 HYBRID_MODE_6 = 2
}PMU_MODE; } PMU_MODE;
#define MAX_RDM_WRM_RETIRES 1 #define MAX_RDM_WRM_RETIRES 1
...@@ -360,4 +357,4 @@ enum eAbortPattern { ...@@ -360,4 +357,4 @@ enum eAbortPattern {
#define SKB_CB_LATENCY_OFFSET 1 #define SKB_CB_LATENCY_OFFSET 1
#define SKB_CB_TCPACK_OFFSET 2 #define SKB_CB_TCPACK_OFFSET 2
#endif //__MACROS_H__ #endif /* __MACROS_H__ */
此差异已折叠。
...@@ -74,4 +74,6 @@ ...@@ -74,4 +74,6 @@
#define DRV_VERSION VER_FILEVERSION_STR #define DRV_VERSION VER_FILEVERSION_STR
#define PFX DRV_NAME " " #define PFX DRV_NAME " "
extern struct class *bcm_class;
#endif #endif
...@@ -4013,7 +4013,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) ...@@ -4013,7 +4013,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
if(uiTotalDataToCopy < ISOLength) if(uiTotalDataToCopy < ISOLength)
{ {
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
return STATUS_FAILURE; Status = STATUS_FAILURE;
goto out;
} }
uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
...@@ -4026,7 +4027,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) ...@@ -4026,7 +4027,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
if(uiTotalDataToCopy < ISOLength) if(uiTotalDataToCopy < ISOLength)
{ {
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
return STATUS_FAILURE; Status = STATUS_FAILURE;
goto out;
} }
uiTotalDataToCopy = ISOLength; uiTotalDataToCopy = ISOLength;
...@@ -4143,7 +4145,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) ...@@ -4143,7 +4145,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
if(uiTotalDataToCopy < ISOLength) if(uiTotalDataToCopy < ISOLength)
{ {
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
return STATUS_FAILURE; Status = STATUS_FAILURE;
goto out;
} }
uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
...@@ -4156,7 +4159,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) ...@@ -4156,7 +4159,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
if(uiTotalDataToCopy < ISOLength) if(uiTotalDataToCopy < ISOLength)
{ {
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
return STATUS_FAILURE; Status = STATUS_FAILURE;
goto out;
} }
uiTotalDataToCopy = ISOLength; uiTotalDataToCopy = ISOLength;
...@@ -4257,6 +4261,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) ...@@ -4257,6 +4261,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
} }
out:
kfree(Buff); kfree(Buff);
return Status; return Status;
......
config BRCMUTIL
tristate
default n
config BRCMSMAC
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
default n
depends on PCI
depends on WLAN && MAC80211
depends on X86 || MIPS
select BRCMUTIL
select FW_LOADER
select CRC_CCITT
---help---
This module adds support for PCIe wireless adapters based on Broadcom
IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
be called brcmsmac.ko.
config BRCMFMAC
tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
default n
depends on MMC
depends on WLAN && CFG80211
depends on X86 || MIPS
select BRCMUTIL
select FW_LOADER
select WIRELESS_EXT
select WEXT_PRIV
---help---
This module adds support for embedded wireless adapters based on
Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
wireless extensions subsystem. If you choose to build a module,
it'll be called brcmfmac.ko.
config BRCMDBG
bool "Broadcom driver debug functions"
default n
depends on BRCMSMAC || BRCMFMAC
---help---
Selecting this enables additional code for debug purposes.
#
# Makefile fragment for Broadcom 802.11n Networking Device Driver
#
# Copyright (c) 2010 Broadcom Corporation
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# common flags
subdir-ccflags-y := -DBCMDMA32
subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
obj-$(CONFIG_BRCMUTIL) += brcmutil/
obj-$(CONFIG_BRCMFMAC) += brcmfmac/
obj-$(CONFIG_BRCMSMAC) += brcmsmac/
refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
To Do List for Broadcom Mac80211 driver before getting in mainline
Bugs
====
- none known at this moment
brcmfmac
=====================
- ASSERTS deprecated in mainline, replace by warning + error handling
brcm80211 info page
=====================
http://linuxwireless.org/en/users/Drivers/brcm80211
#
# Makefile fragment for Broadcom 802.11n Networking Device Driver
#
# Copyright (c) 2010 Broadcom Corporation
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ccflags-y := \
-DBRCMF_FIRSTREAD=64 \
-DBRCMF_SDALIGN=64 \
-DMAX_HDR_READ=64
ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS
ccflags-y += \
-Idrivers/staging/brcm80211/brcmfmac \
-Idrivers/staging/brcm80211/include
DHDOFILES = \
wl_cfg80211.o \
dhd_cdc.o \
dhd_common.o \
dhd_sdio.o \
dhd_linux.o \
bcmsdh.o \
bcmsdh_sdmmc.o
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
brcmfmac-objs += $(DHDOFILES)
/*
* Copyright (c) 2011 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _bcmchip_h_
#define _bcmchip_h_
/* bcm4329 */
/* SDIO device core, ID 0x829 */
#define BCM4329_CORE_BUS_BASE 0x18011000
/* internal memory core, ID 0x80e */
#define BCM4329_CORE_SOCRAM_BASE 0x18003000
/* ARM Cortex M3 core, ID 0x82a */
#define BCM4329_CORE_ARM_BASE 0x18002000
#define BCM4329_RAMSIZE 0x48000
/* firmware name */
#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
#endif /* _bcmchip_h_ */
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCMF_BUS_H_
#define _BRCMF_BUS_H_
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef BRCMF_SDALIGN
#define BRCMF_SDALIGN 32
#endif
#if !ISPOWEROF2(BRCMF_SDALIGN)
#error BRCMF_SDALIGN is not a power of 2!
#endif
/*
* Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
*/
/* dongle ram module parameter */
extern int brcmf_dongle_memsize;
/* Tx/Rx bounds module parameters */
extern uint brcmf_txbound;
extern uint brcmf_rxbound;
/* Watchdog timer interval */
extern uint brcmf_watchdog_ms;
/* Indicate (dis)interest in finding dongles. */
extern int brcmf_bus_register(void);
extern void brcmf_bus_unregister(void);
/* Stop bus module: clear pending frames, disable data flow */
extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex);
/* Initialize bus module: prepare for communication w/dongle */
extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex);
/* Send a data frame to the dongle. Callee disposes of txp. */
extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
/* Send/receive a control message to/from the dongle.
* Expects caller to enforce a single outstanding transaction.
*/
extern int
brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
extern int
brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
/* Check for and handle local prot-specific iovar commands */
extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
void *params, int plen, void *arg, int len,
bool set);
/* Add bus dump output to a buffer */
extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr,
struct brcmu_strbuf *strbuf);
/* Clear any bus counters */
extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr);
extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
#endif /* _BRCMF_BUS_H_ */
此差异已折叠。
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCMF_DBG_H_
#define _BRCMF_DBG_H_
#if defined(BCMDBG)
#define BRCMF_ERROR(args) \
do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \
printk args; } while (0)
#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \
printk args; } while (0)
#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \
printk args; } while (0)
#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \
printk args; } while (0)
#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \
printk args; } while (0)
#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \
printk args; } while (0)
#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \
printk args; } while (0)
#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \
printk args; } while (0)
#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \
printk args; } while (0)
#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
#else /* (defined BCMDBG) || (defined BCMDBG) */
#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0)
#define BRCMF_TRACE(args)
#define BRCMF_INFO(args)
#define BRCMF_DATA(args)
#define BRCMF_CTL(args)
#define BRCMF_TIMER(args)
#define BRCMF_INTR(args)
#define BRCMF_GLOM(args)
#define BRCMF_EVENT(args)
#define BRCMF_DATA_ON() 0
#define BRCMF_CTL_ON() 0
#define BRCMF_HDRS_ON() 0
#define BRCMF_BYTES_ON() 0
#define BRCMF_GLOM_ON() 0
#endif /* defined(BCMDBG) */
extern int brcmf_msg_level;
#endif /* _BRCMF_DBG_H_ */
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCMF_PROTO_H_
#define _BRCMF_PROTO_H_
#ifndef IOCTL_RESP_TIMEOUT
#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
#endif
#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT
#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */
#endif
/*
* Exported from the brcmf protocol module (brcmf_cdc)
*/
/* Linkage, sets prot link and updates hdrlen in pub */
extern int brcmf_proto_attach(struct brcmf_pub *drvr);
/* Unlink, frees allocated protocol memory (including brcmf_proto) */
extern void brcmf_proto_detach(struct brcmf_pub *drvr);
/* Initialize protocol: sync w/dongle state.
* Sets dongle media info (iswl, drv_version, mac address).
*/
extern int brcmf_proto_init(struct brcmf_pub *drvr);
/* Stop protocol: sync w/dongle state. */
extern void brcmf_proto_stop(struct brcmf_pub *drvr);
/* Add any protocol-specific data header.
* Caller must reserve prot_hdrlen prepend space.
*/
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
struct sk_buff *txp);
/* Remove any protocol-specific data header. */
extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
struct sk_buff *rxp);
/* Use protocol to issue ioctl to dongle */
extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx,
struct brcmf_ioctl *ioc, void *buf, int len);
/* Add prot dump output to a buffer */
extern void brcmf_proto_dump(struct brcmf_pub *drvr,
struct brcmu_strbuf *strbuf);
/* Update local copy of dongle statistics */
extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc,
void *buf, uint buflen);
extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr);
extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len);
#endif /* _BRCMF_PROTO_H_ */
此差异已折叠。
#
# Makefile fragment for Broadcom 802.11n Networking Device Driver
#
# Copyright (c) 2010 Broadcom Corporation
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ccflags-y := \
-DWLC_HIGH \
-DWLC_LOW \
-DSTA \
-DWME \
-DWL11N \
-DDBAND \
-DBCMNVRAMR \
-Idrivers/staging/brcm80211/brcmsmac \
-Idrivers/staging/brcm80211/brcmsmac/phy \
-Idrivers/staging/brcm80211/include
BRCMSMAC_OFILES := \
mac80211_if.o \
ucode_loader.o \
alloc.o \
ampdu.o \
antsel.o \
bmac.o \
channel.o \
main.o \
phy_shim.o \
pmu.o \
rate.o \
stf.o \
aiutils.o \
phy/phy_cmn.o \
phy/phy_lcn.o \
phy/phy_n.o \
phy/phytbl_lcn.o \
phy/phytbl_n.o \
phy/phy_qmath.o \
otp.o \
srom.o \
dma.o \
nicpci.o
MODULEPFX := brcmsmac
obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
$(MODULEPFX)-objs = $(BRCMSMAC_OFILES)
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
extern struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err,
uint devid);
extern void brcms_c_detach_mfree(struct brcms_c_info *wlc);
此差异已折叠。
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCM_AMPDU_H_
#define _BRCM_AMPDU_H_
extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
struct brcms_txq_info *qi,
struct sk_buff **aggp, int prec);
extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, struct tx_status *txs);
extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
#endif /* _BRCM_AMPDU_H_ */
此差异已折叠。
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCM_ANTSEL_H_
#define _BRCM_ANTSEL_H_
extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
extern void brcms_c_antsel_detach(struct antsel_info *asi);
extern void brcms_c_antsel_init(struct antsel_info *asi);
extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
bool sel,
u8 id, u8 fbid, u8 *antcfg,
u8 *fbantcfg);
extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
#endif /* _BRCM_ANTSEL_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册