diff --git a/[refs] b/[refs] index 52bea6a0fa8f..a8e913aa6f74 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 76f901eb4659779ecacd0e4eba49f55442daef53 +refs/heads/master: 2dad9d4d057a080a4ad59c705b3e388af6794576 diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd index 679ce3543122..d535757799fe 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ b/trunk/Documentation/ABI/testing/sysfs-block-rssd @@ -6,21 +6,13 @@ Description: This is a read-only file. Dumps below driver information and hardware registers. - S ACTive - Command Issue + - Allocated - Completed - PORT IRQ STAT - HOST IRQ STAT - - Allocated - - Commands in Q What: /sys/block/rssd*/status Date: April 2012 KernelVersion: 3.4 Contact: Asai Thambi S P -Description: This is a read-only file. Indicates the status of the device. - -What: /sys/block/rssd*/flags -Date: May 2012 -KernelVersion: 3.5 -Contact: Asai Thambi S P -Description: This is a read-only file. Dumps the flags in port and driver - data structure +Description: This is a read-only file. Indicates the status of the device. diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-fcoe b/trunk/Documentation/ABI/testing/sysfs-bus-fcoe deleted file mode 100644 index 469d09c02f6b..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-bus-fcoe +++ /dev/null @@ -1,77 +0,0 @@ -What: /sys/bus/fcoe/ctlr_X -Date: March 2012 -KernelVersion: TBD -Contact: Robert Love , devel@open-fcoe.org -Description: 'FCoE Controller' instances on the fcoe bus -Attributes: - - fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing - this value will change the dev_loss_tmo for all - FCFs discovered by this controller. - - lesb_link_fail: Link Error Status Block (LESB) link failure count. - - lesb_vlink_fail: Link Error Status Block (LESB) virtual link - failure count. - - lesb_miss_fka: Link Error Status Block (LESB) missed FCoE - Initialization Protocol (FIP) Keep-Alives (FKA). - - lesb_symb_err: Link Error Status Block (LESB) symbolic error count. - - lesb_err_block: Link Error Status Block (LESB) block error count. - - lesb_fcs_error: Link Error Status Block (LESB) Fibre Channel - Serivces error count. - -Notes: ctlr_X (global increment starting at 0) - -What: /sys/bus/fcoe/fcf_X -Date: March 2012 -KernelVersion: TBD -Contact: Robert Love , devel@open-fcoe.org -Description: 'FCoE FCF' instances on the fcoe bus. A FCF is a Fibre Channel - Forwarder, which is a FCoE switch that can accept FCoE - (Ethernet) packets, unpack them, and forward the embedded - Fibre Channel frames into a FC fabric. It can also take - outbound FC frames and pack them in Ethernet packets to - be sent to their destination on the Ethernet segment. -Attributes: - - fabric_name: Identifies the fabric that the FCF services. - - switch_name: Identifies the FCF. - - priority: The switch's priority amongst other FCFs on the same - fabric. - - selected: 1 indicates that the switch has been selected for use; - 0 indicates that the swich will not be used. - - fc_map: The Fibre Channel MAP - - vfid: The Virtual Fabric ID - - mac: The FCF's MAC address - - fka_peroid: The FIP Keep-Alive peroid - - fabric_state: The internal kernel state - "Unknown" - Initialization value - "Disconnected" - No link to the FCF/fabric - "Connected" - Host is connected to the FCF - "Deleted" - FCF is being removed from the system - - dev_loss_tmo: The device loss timeout peroid for this FCF. - -Notes: A device loss infrastructre similar to the FC Transport's - is present in fcoe_sysfs. It is nice to have so that a - link flapping adapter doesn't continually advance the count - used to identify the discovered FCF. FCFs will exist in a - "Disconnected" state until either the timer expires and the - FCF becomes "Deleted" or the FCF is rediscovered and becomes - "Connected." - - -Users: The first user of this interface will be the fcoeadm application, - which is commonly packaged in the fcoe-utils package. diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 56000b33340b..ebaffe208ccb 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -606,9 +606,3 @@ Why: There are two mci drivers: at91-mci and atmel-mci. The PDC support Who: Ludovic Desroches ---------------------------- - -What: net/wanrouter/ -When: June 2013 -Why: Unsupported/unmaintained/unused since 2.6 - ----------------------------- diff --git a/trunk/Documentation/power/charger-manager.txt b/trunk/Documentation/power/charger-manager.txt index b4f7f4b23f64..fdcca991df30 100644 --- a/trunk/Documentation/power/charger-manager.txt +++ b/trunk/Documentation/power/charger-manager.txt @@ -44,16 +44,6 @@ Charger Manager supports the following: Normally, the platform will need to resume and suspend some devices that are used by Charger Manager. -* Support for premature full-battery event handling - If the battery voltage drops by "fullbatt_vchkdrop_uV" after - "fullbatt_vchkdrop_ms" from the full-battery event, the framework - restarts charging. This check is also performed while suspended by - setting wakeup time accordingly and using suspend_again. - -* Support for uevent-notify - With the charger-related events, the device sends - notification to users with UEVENT. - 2. Global Charger-Manager Data related with suspend_again ======================================================== In order to setup Charger Manager with suspend-again feature @@ -65,7 +55,7 @@ if there are multiple batteries. If there are multiple batteries, the multiple instances of Charger Manager share the same charger_global_desc and it will manage in-suspend monitoring for all instances of Charger Manager. -The user needs to provide all the three entries properly in order to activate +The user needs to provide all the two entries properly in order to activate in-suspend monitoring: struct charger_global_desc { @@ -84,11 +74,6 @@ bool (*rtc_only_wakeup)(void); same struct. If there is any other wakeup source triggered the wakeup, it should return false. If the "rtc" is the only wakeup reason, it should return true. - -bool assume_timer_stops_in_suspend; - : if true, Charger Manager assumes that - the timer (CM uses jiffies as timer) stops during suspend. Then, CM - assumes that the suspend-duration is same as the alarm length. }; 3. How to setup suspend_again @@ -126,16 +111,6 @@ enum polling_modes polling_mode; CM_POLL_CHARGING_ONLY: poll this battery if and only if the battery is being charged. -unsigned int fullbatt_vchkdrop_ms; -unsigned int fullbatt_vchkdrop_uV; - : If both have non-zero values, Charger Manager will check the - battery voltage drop fullbatt_vchkdrop_ms after the battery is fully - charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger - Manager will try to recharge the battery by disabling and enabling - chargers. Recharge with voltage drop condition only (without delay - condition) is needed to be implemented with hardware interrupts from - fuel gauges or charger devices/chips. - unsigned int fullbatt_uV; : If specified with a non-zero value, Charger Manager assumes that the battery is full (capacity = 100) if the battery is not being @@ -147,8 +122,6 @@ unsigned int polling_interval_ms; this battery every polling_interval_ms or more frequently. enum data_source battery_present; - : CM_BATTERY_PRESENT: assume that the battery exists. - CM_NO_BATTERY: assume that the battery does not exists. CM_FUEL_GAUGE: get battery presence information from fuel gauge. CM_CHARGER_STAT: get battery presence from chargers. @@ -178,17 +151,7 @@ bool measure_battery_temp; the value of measure_battery_temp. }; -5. Notify Charger-Manager of charger events: cm_notify_event() -========================================================= -If there is an charger event is required to notify -Charger Manager, a charger device driver that triggers the event can call -cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager. -In the function, psy is the charger driver's power_supply pointer, which is -associated with Charger-Manager. The parameter "type" -is the same as irq's type (enum cm_event_types). The event message "msg" is -optional and is effective only if the event type is "UNDESCRIBED" or "OTHERS". - -6. Other Considerations +5. Other Considerations ======================= At the charger/battery-related events such as battery-pulled-out, diff --git a/trunk/Documentation/power/power_supply_class.txt b/trunk/Documentation/power/power_supply_class.txt index 211831d4095f..9f16c5178b66 100644 --- a/trunk/Documentation/power/power_supply_class.txt +++ b/trunk/Documentation/power/power_supply_class.txt @@ -84,8 +84,6 @@ are already charged or discharging, 'n/a' can be displayed (or HEALTH - represents health of the battery, values corresponds to POWER_SUPPLY_HEALTH_*, defined in battery.h. -VOLTAGE_OCV - open circuit voltage of the battery. - VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and minimal power supply voltages. Maximal/minimal means values of voltages when battery considered "full"/"empty" at normal conditions. Yes, there is diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 55f0fda602ec..64e675d6d478 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5337,7 +5337,7 @@ M: David Woodhouse T: git git://git.infradead.org/battery-2.6.git S: Maintained F: include/linux/power_supply.h -F: drivers/power/ +F: drivers/power/power_supply* PNP SUPPORT M: Adam Belay @@ -6657,7 +6657,7 @@ F: include/linux/taskstats* F: kernel/taskstats.c TC CLASSIFIER -M: Jamal Hadi Salim +M: Jamal Hadi Salim L: netdev@vger.kernel.org S: Maintained F: include/linux/pkt_cls.h diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index b649c5904a4f..5e7601301b41 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -525,7 +525,7 @@ config ARCH_IXP4XX select ARCH_HAS_DMA_SET_COHERENT_MASK select CLKSRC_MMIO select CPU_XSCALE - select ARCH_REQUIRE_GPIOLIB + select GENERIC_GPIO select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select NEED_MACH_IO_H diff --git a/trunk/arch/arm/boot/dts/exynos5250.dtsi b/trunk/arch/arm/boot/dts/exynos5250.dtsi index 4272b2949228..5ca0cdb76413 100644 --- a/trunk/arch/arm/boot/dts/exynos5250.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5250.dtsi @@ -30,22 +30,6 @@ reg = <0x10481000 0x1000>, <0x10482000 0x2000>; }; - combiner:interrupt-controller@10440000 { - compatible = "samsung,exynos4210-combiner"; - #interrupt-cells = <2>; - interrupt-controller; - samsung,combiner-nr = <32>; - reg = <0x10440000 0x1000>; - interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, - <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, - <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, - <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, - <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, - <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, - <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, - <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; - }; - watchdog { compatible = "samsung,s3c2410-wdt"; reg = <0x101D0000 0x100>; diff --git a/trunk/arch/arm/boot/dts/lpc32xx.dtsi b/trunk/arch/arm/boot/dts/lpc32xx.dtsi index 3f5dad801a98..2d696866f71c 100644 --- a/trunk/arch/arm/boot/dts/lpc32xx.dtsi +++ b/trunk/arch/arm/boot/dts/lpc32xx.dtsi @@ -215,8 +215,45 @@ gpio: gpio@40028000 { compatible = "nxp,lpc3220-gpio"; reg = <0x40028000 0x1000>; - gpio-controller; - #gpio-cells = <3>; /* bank, pin, flags */ + /* create a private address space for enumeration */ + #address-cells = <1>; + #size-cells = <0>; + + gpio_p0: gpio-bank@0 { + gpio-controller; + #gpio-cells = <2>; + reg = <0>; + }; + + gpio_p1: gpio-bank@1 { + gpio-controller; + #gpio-cells = <2>; + reg = <1>; + }; + + gpio_p2: gpio-bank@2 { + gpio-controller; + #gpio-cells = <2>; + reg = <2>; + }; + + gpio_p3: gpio-bank@3 { + gpio-controller; + #gpio-cells = <2>; + reg = <3>; + }; + + gpi_p3: gpio-bank@4 { + gpio-controller; + #gpio-cells = <2>; + reg = <4>; + }; + + gpo_p3: gpio-bank@5 { + gpio-controller; + #gpio-cells = <2>; + reg = <5>; + }; }; watchdog@4003C000 { diff --git a/trunk/arch/arm/boot/dts/phy3250.dts b/trunk/arch/arm/boot/dts/phy3250.dts index c4ff6d1a018b..0167e86314c0 100644 --- a/trunk/arch/arm/boot/dts/phy3250.dts +++ b/trunk/arch/arm/boot/dts/phy3250.dts @@ -131,13 +131,13 @@ compatible = "gpio-leds"; led0 { - gpios = <&gpio 5 1 1>; /* GPO_P3 1, GPIO 80, active low */ + gpios = <&gpo_p3 1 1>; /* GPO_P3 1, GPIO 80, active low */ linux,default-trigger = "heartbeat"; default-state = "off"; }; led1 { - gpios = <&gpio 5 14 1>; /* GPO_P3 14, GPIO 93, active low */ + gpios = <&gpo_p3 14 1>; /* GPO_P3 14, GPIO 93, active low */ linux,default-trigger = "timer"; default-state = "off"; }; diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 7e1091d91af8..941b161ab78c 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -73,10 +73,7 @@ #address-cells = <0>; interrupt-controller; reg = <0x2c001000 0x1000>, - <0x2c002000 0x1000>, - <0x2c004000 0x2000>, - <0x2c006000 0x2000>; - interrupts = <1 9 0xf04>; + <0x2c002000 0x100>; }; memory-controller@7ffd0000 { @@ -96,14 +93,6 @@ <0 91 4>; }; - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - }; - pmu { compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; interrupts = <0 68 4>, diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts index 18917a0f8604..6905e66d4748 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -77,18 +77,13 @@ timer@2c000600 { compatible = "arm,cortex-a5-twd-timer"; - reg = <0x2c000600 0x20>; - interrupts = <1 13 0x304>; - }; - - watchdog@2c000620 { - compatible = "arm,cortex-a5-twd-wdt"; - reg = <0x2c000620 0x20>; - interrupts = <1 14 0x304>; + reg = <0x2c000600 0x38>; + interrupts = <1 2 0x304>, + <1 3 0x304>; }; gic: interrupt-controller@2c001000 { - compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic"; + compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; #address-cells = <0>; interrupt-controller; diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts index 3f0c736d31d6..da778693be54 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -105,13 +105,8 @@ timer@1e000600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1e000600 0x20>; - interrupts = <1 13 0xf04>; - }; - - watchdog@1e000620 { - compatible = "arm,cortex-a9-twd-wdt"; - reg = <0x1e000620 0x20>; - interrupts = <1 14 0xf04>; + interrupts = <1 2 0xf04>, + <1 3 0xf04>; }; gic: interrupt-controller@1e001000 { diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index 573be57d3d28..43ebe9094411 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -62,8 +62,6 @@ config SOC_EXYNOS5250 default y depends on ARCH_EXYNOS5 select SAMSUNG_DMADEV - select S5P_PM if PM - select S5P_SLEEP if PM help Enable EXYNOS5250 SoC support diff --git a/trunk/arch/arm/mach-exynos/Makefile b/trunk/arch/arm/mach-exynos/Makefile index 9b58024f7d43..440a637c76f1 100644 --- a/trunk/arch/arm/mach-exynos/Makefile +++ b/trunk/arch/arm/mach-exynos/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_EXYNOS) += pmu.o +obj-$(CONFIG_ARCH_EXYNOS4) += pmu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c index fefa336be2b4..5aa460b01fdf 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos5.c @@ -30,56 +30,7 @@ #ifdef CONFIG_PM_SLEEP static struct sleep_save exynos5_clock_save[] = { - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_GSCL), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_DISP1), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_MFC), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_G3D), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_GEN), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_FSYS), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIC), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIS), - SAVE_ITEM(EXYNOS5_CLKGATE_BLOCK), - SAVE_ITEM(EXYNOS5_CLKDIV_TOP0), - SAVE_ITEM(EXYNOS5_CLKDIV_TOP1), - SAVE_ITEM(EXYNOS5_CLKDIV_GSCL), - SAVE_ITEM(EXYNOS5_CLKDIV_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKDIV_GEN), - SAVE_ITEM(EXYNOS5_CLKDIV_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS0), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS1), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS2), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS3), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC0), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC1), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC2), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC3), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC4), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC5), - SAVE_ITEM(EXYNOS5_SCLK_DIV_ISP), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP0), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP1), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP2), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP3), - SAVE_ITEM(EXYNOS5_CLKSRC_GSCL), - SAVE_ITEM(EXYNOS5_CLKSRC_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKSRC_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKSRC_FSYS), - SAVE_ITEM(EXYNOS5_CLKSRC_PERIC0), - SAVE_ITEM(EXYNOS5_CLKSRC_PERIC1), - SAVE_ITEM(EXYNOS5_SCLK_SRC_ISP), - SAVE_ITEM(EXYNOS5_EPLL_CON0), - SAVE_ITEM(EXYNOS5_EPLL_CON1), - SAVE_ITEM(EXYNOS5_EPLL_CON2), - SAVE_ITEM(EXYNOS5_VPLL_CON0), - SAVE_ITEM(EXYNOS5_VPLL_CON1), - SAVE_ITEM(EXYNOS5_VPLL_CON2), + /* will be implemented */ }; #endif diff --git a/trunk/arch/arm/mach-exynos/cpuidle.c b/trunk/arch/arm/mach-exynos/cpuidle.c index cff0595d0d35..26dac2893b8e 100644 --- a/trunk/arch/arm/mach-exynos/cpuidle.c +++ b/trunk/arch/arm/mach-exynos/cpuidle.c @@ -100,7 +100,7 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, exynos4_set_wakeupmask(); /* Set value of power down register for aftr mode */ - exynos_sys_powerdown_conf(SYS_AFTR); + exynos4_sys_powerdown_conf(SYS_AFTR); __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); diff --git a/trunk/arch/arm/mach-exynos/include/mach/pm-core.h b/trunk/arch/arm/mach-exynos/include/mach/pm-core.h index a67ecfaf1216..9d8da51e35ca 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/trunk/arch/arm/mach-exynos/include/mach/pm-core.h @@ -33,7 +33,7 @@ static inline void s3c_pm_arch_prepare_irqs(void) __raw_writel(tmp, S5P_WAKEUP_MASK); __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); - __raw_writel(s3c_irqwake_eintmask & 0xFFFFFFFE, S5P_EINT_WAKEUP_MASK); + __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); } static inline void s3c_pm_arch_stop_clocks(void) diff --git a/trunk/arch/arm/mach-exynos/include/mach/pmu.h b/trunk/arch/arm/mach-exynos/include/mach/pmu.h index 7c27c2d4bf44..e76b7faba66b 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/pmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/pmu.h @@ -23,12 +23,12 @@ enum sys_powerdown { }; extern unsigned long l2x0_regs_phys; -struct exynos_pmu_conf { +struct exynos4_pmu_conf { void __iomem *reg; unsigned int val[NUM_SYS_POWERDOWN]; }; -extern void exynos_sys_powerdown_conf(enum sys_powerdown mode); +extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); extern void s3c_cpu_resume(void); #endif /* __ASM_ARCH_PMU_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h index 8c9b38c9c504..b78b5f3ad9c0 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -274,51 +274,36 @@ #define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500) +#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130) #define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134) -#define EXYNOS5_EPLL_CON2 EXYNOS_CLKREG(0x10138) #define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) #define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) -#define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148) #define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) #define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) -#define EXYNOS5_CLKSRC_TOP1 EXYNOS_CLKREG(0x10214) -#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C) #define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220) #define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C) -#define EXYNOS5_CLKSRC_MAUDIO EXYNOS_CLKREG(0x10240) #define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244) #define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250) -#define EXYNOS5_CLKSRC_PERIC1 EXYNOS_CLKREG(0x10254) -#define EXYNOS5_SCLK_SRC_ISP EXYNOS_CLKREG(0x10270) #define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310) #define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320) #define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C) -#define EXYNOS5_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x10334) #define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340) #define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350) -#define EXYNOS5_CLKSRC_MASK_PERIC1 EXYNOS_CLKREG(0x10354) #define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510) #define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514) #define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520) #define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C) #define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C) -#define EXYNOS5_CLKDIV_MAUDIO EXYNOS_CLKREG(0x10544) #define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548) #define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C) #define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550) #define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554) #define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) -#define EXYNOS5_CLKDIV_PERIC1 EXYNOS_CLKREG(0x1055C) -#define EXYNOS5_CLKDIV_PERIC2 EXYNOS_CLKREG(0x10560) -#define EXYNOS5_CLKDIV_PERIC3 EXYNOS_CLKREG(0x10564) -#define EXYNOS5_CLKDIV_PERIC4 EXYNOS_CLKREG(0x10568) -#define EXYNOS5_CLKDIV_PERIC5 EXYNOS_CLKREG(0x1056C) -#define EXYNOS5_SCLK_DIV_ISP EXYNOS_CLKREG(0x10580) #define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) #define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800) @@ -326,7 +311,6 @@ #define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) #define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) #define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) -#define EXYNOS5_CLKGATE_IP_G3D EXYNOS_CLKREG(0x10930) #define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934) #define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944) #define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C) diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h b/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h index 43a99e6f56ab..4dbb8629b200 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -1,8 +1,9 @@ -/* - * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. +/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS - Power management unit definition + * EXYNOS4 - Power management unit definition * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -228,138 +229,4 @@ #define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034) #define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038) -/* For EXYNOS5 */ - -#define EXYNOS5_USB_CFG S5P_PMUREG(0x0230) - -#define EXYNOS5_ARM_CORE0_SYS_PWR_REG S5P_PMUREG(0x1000) -#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1004) -#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1008) -#define EXYNOS5_ARM_CORE1_SYS_PWR_REG S5P_PMUREG(0x1010) -#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1014) -#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1018) -#define EXYNOS5_FSYS_ARM_SYS_PWR_REG S5P_PMUREG(0x1040) -#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1048) -#define EXYNOS5_ISP_ARM_SYS_PWR_REG S5P_PMUREG(0x1050) -#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1054) -#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1058) -#define EXYNOS5_ARM_COMMON_SYS_PWR_REG S5P_PMUREG(0x1080) -#define EXYNOS5_ARM_L2_SYS_PWR_REG S5P_PMUREG(0x10C0) -#define EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1100) -#define EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1104) -#define EXYNOS5_CMU_RESET_SYS_PWR_REG S5P_PMUREG(0x110C) -#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1120) -#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1124) -#define EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x112C) -#define EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG S5P_PMUREG(0x1130) -#define EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG S5P_PMUREG(0x1134) -#define EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG S5P_PMUREG(0x1138) -#define EXYNOS5_APLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1140) -#define EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1144) -#define EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1148) -#define EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x114C) -#define EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1150) -#define EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1154) -#define EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1164) -#define EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1170) -#define EXYNOS5_TOP_BUS_SYS_PWR_REG S5P_PMUREG(0x1180) -#define EXYNOS5_TOP_RETENTION_SYS_PWR_REG S5P_PMUREG(0x1184) -#define EXYNOS5_TOP_PWR_SYS_PWR_REG S5P_PMUREG(0x1188) -#define EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1190) -#define EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1194) -#define EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1198) -#define EXYNOS5_LOGIC_RESET_SYS_PWR_REG S5P_PMUREG(0x11A0) -#define EXYNOS5_OSCCLK_GATE_SYS_PWR_REG S5P_PMUREG(0x11A4) -#define EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B0) -#define EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B4) -#define EXYNOS5_USBOTG_MEM_SYS_PWR_REG S5P_PMUREG(0x11C0) -#define EXYNOS5_G2D_MEM_SYS_PWR_REG S5P_PMUREG(0x11C8) -#define EXYNOS5_USBDRD_MEM_SYS_PWR_REG S5P_PMUREG(0x11CC) -#define EXYNOS5_SDMMC_MEM_SYS_PWR_REG S5P_PMUREG(0x11D0) -#define EXYNOS5_CSSYS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D4) -#define EXYNOS5_SECSS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D8) -#define EXYNOS5_ROTATOR_MEM_SYS_PWR_REG S5P_PMUREG(0x11DC) -#define EXYNOS5_INTRAM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E0) -#define EXYNOS5_INTROM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E4) -#define EXYNOS5_JPEG_MEM_SYS_PWR_REG S5P_PMUREG(0x11E8) -#define EXYNOS5_HSI_MEM_SYS_PWR_REG S5P_PMUREG(0x11EC) -#define EXYNOS5_MCUIOP_MEM_SYS_PWR_REG S5P_PMUREG(0x11F4) -#define EXYNOS5_SATA_MEM_SYS_PWR_REG S5P_PMUREG(0x11FC) -#define EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG S5P_PMUREG(0x1200) -#define EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG S5P_PMUREG(0x1204) -#define EXYNOS5_PAD_RETENTION_EFNAND_SYS_PWR_REG S5P_PMUREG(0x1208) -#define EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG S5P_PMUREG(0x1220) -#define EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG S5P_PMUREG(0x1224) -#define EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG S5P_PMUREG(0x1228) -#define EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG S5P_PMUREG(0x122C) -#define EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG S5P_PMUREG(0x1230) -#define EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG S5P_PMUREG(0x1234) -#define EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG S5P_PMUREG(0x1238) -#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x123C) -#define EXYNOS5_PAD_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1240) -#define EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1250) -#define EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG S5P_PMUREG(0x1260) -#define EXYNOS5_XUSBXTI_SYS_PWR_REG S5P_PMUREG(0x1280) -#define EXYNOS5_XXTI_SYS_PWR_REG S5P_PMUREG(0x1284) -#define EXYNOS5_EXT_REGULATOR_SYS_PWR_REG S5P_PMUREG(0x12C0) -#define EXYNOS5_GPIO_MODE_SYS_PWR_REG S5P_PMUREG(0x1300) -#define EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1320) -#define EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG S5P_PMUREG(0x1340) -#define EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG S5P_PMUREG(0x1344) -#define EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1348) -#define EXYNOS5_GSCL_SYS_PWR_REG S5P_PMUREG(0x1400) -#define EXYNOS5_ISP_SYS_PWR_REG S5P_PMUREG(0x1404) -#define EXYNOS5_MFC_SYS_PWR_REG S5P_PMUREG(0x1408) -#define EXYNOS5_G3D_SYS_PWR_REG S5P_PMUREG(0x140C) -#define EXYNOS5_DISP1_SYS_PWR_REG S5P_PMUREG(0x1414) -#define EXYNOS5_MAU_SYS_PWR_REG S5P_PMUREG(0x1418) -#define EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG S5P_PMUREG(0x1480) -#define EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG S5P_PMUREG(0x1484) -#define EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG S5P_PMUREG(0x1488) -#define EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG S5P_PMUREG(0x148C) -#define EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG S5P_PMUREG(0x1494) -#define EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG S5P_PMUREG(0x1498) -#define EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG S5P_PMUREG(0x14C0) -#define EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG S5P_PMUREG(0x14C4) -#define EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG S5P_PMUREG(0x14C8) -#define EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG S5P_PMUREG(0x14CC) -#define EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG S5P_PMUREG(0x14D4) -#define EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG S5P_PMUREG(0x14D8) -#define EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG S5P_PMUREG(0x1580) -#define EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG S5P_PMUREG(0x1584) -#define EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG S5P_PMUREG(0x1588) -#define EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG S5P_PMUREG(0x158C) -#define EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG S5P_PMUREG(0x1594) -#define EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG S5P_PMUREG(0x1598) - -#define EXYNOS5_ARM_CORE0_OPTION S5P_PMUREG(0x2008) -#define EXYNOS5_ARM_CORE1_OPTION S5P_PMUREG(0x2088) -#define EXYNOS5_FSYS_ARM_OPTION S5P_PMUREG(0x2208) -#define EXYNOS5_ISP_ARM_OPTION S5P_PMUREG(0x2288) -#define EXYNOS5_ARM_COMMON_OPTION S5P_PMUREG(0x2408) -#define EXYNOS5_TOP_PWR_OPTION S5P_PMUREG(0x2C48) -#define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8) -#define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48) -#define EXYNOS5_GSCL_STATUS S5P_PMUREG(0x4004) -#define EXYNOS5_ISP_STATUS S5P_PMUREG(0x4024) -#define EXYNOS5_GSCL_OPTION S5P_PMUREG(0x4008) -#define EXYNOS5_ISP_OPTION S5P_PMUREG(0x4028) -#define EXYNOS5_MFC_OPTION S5P_PMUREG(0x4048) -#define EXYNOS5_G3D_CONFIGURATION S5P_PMUREG(0x4060) -#define EXYNOS5_G3D_STATUS S5P_PMUREG(0x4064) -#define EXYNOS5_G3D_OPTION S5P_PMUREG(0x4068) -#define EXYNOS5_DISP1_OPTION S5P_PMUREG(0x40A8) -#define EXYNOS5_MAU_OPTION S5P_PMUREG(0x40C8) - -#define EXYNOS5_USE_SC_FEEDBACK (1 << 1) -#define EXYNOS5_USE_SC_COUNTER (1 << 0) - -#define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL (1 << 2) -#define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7) - -#define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24) -#define EXYNOS5_OPTION_USE_STANDBYWFI (1 << 16) - -#define EXYNOS5_OPTION_USE_RETENTION (1 << 4) - #endif /* __ASM_ARCH_REGS_PMU_H */ diff --git a/trunk/arch/arm/mach-exynos/pm.c b/trunk/arch/arm/mach-exynos/pm.c index c06c992943a1..563dea9a6dbb 100644 --- a/trunk/arch/arm/mach-exynos/pm.c +++ b/trunk/arch/arm/mach-exynos/pm.c @@ -1,8 +1,9 @@ -/* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. +/* linux/arch/arm/mach-exynos4/pm.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS - Power Management support + * EXYNOS4210 - Power Management support * * Based on arch/arm/mach-s3c2410/pm.c * Copyright (c) 2006 Simtec Electronics @@ -62,7 +63,90 @@ static struct sleep_save exynos4_vpll_save[] = { SAVE_ITEM(EXYNOS4_VPLL_CON1), }; -static struct sleep_save exynos_core_save[] = { +static struct sleep_save exynos4_core_save[] = { + /* GIC side */ + SAVE_ITEM(S5P_VA_GIC_CPU + 0x000), + SAVE_ITEM(S5P_VA_GIC_CPU + 0x004), + SAVE_ITEM(S5P_VA_GIC_CPU + 0x008), + SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C), + SAVE_ITEM(S5P_VA_GIC_CPU + 0x014), + SAVE_ITEM(S5P_VA_GIC_CPU + 0x018), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x000), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x004), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x100), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x104), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x108), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x300), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x304), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x308), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x400), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x404), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x408), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x410), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x414), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x418), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x420), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x424), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x428), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x430), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x434), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x438), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x440), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x444), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x448), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x450), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x454), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x458), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C), + + SAVE_ITEM(S5P_VA_GIC_DIST + 0x800), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x804), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x808), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x810), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x814), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x818), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x820), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x824), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x828), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x830), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x834), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x838), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x840), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x844), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x848), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x850), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x854), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x858), + SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C), + + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00), + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04), + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08), + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C), + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10), + SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14), + + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080), + SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090), + /* SROM side */ SAVE_ITEM(S5P_SROM_BW), SAVE_ITEM(S5P_SROM_BC0), @@ -75,11 +159,9 @@ static struct sleep_save exynos_core_save[] = { /* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2]; -static int exynos_cpu_suspend(unsigned long arg) +static int exynos4_cpu_suspend(unsigned long arg) { -#ifdef CONFIG_CACHE_L2X0 outer_flush_all(); -#endif /* issue the standby signal into the pm unit. */ cpu_do_idle(); @@ -88,25 +170,19 @@ static int exynos_cpu_suspend(unsigned long arg) panic("sleep resumed to originator?"); } -static void exynos_pm_prepare(void) +static void exynos4_pm_prepare(void) { - unsigned int tmp; + u32 tmp; - s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); + s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); + s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); + s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); - if (!soc_is_exynos5250()) { - s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); - s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); - } else { - /* Disable USE_RETENTION of JPEG_MEM_OPTION */ - tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); - tmp &= ~EXYNOS5_OPTION_USE_RETENTION; - __raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); - } + tmp = __raw_readl(S5P_INFORM1); /* Set value of power down register for sleep mode */ - exynos_sys_powerdown_conf(SYS_SLEEP); + exynos4_sys_powerdown_conf(SYS_SLEEP); __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); /* ensure at least INFORM0 has the resume address */ @@ -115,18 +191,17 @@ static void exynos_pm_prepare(void) /* Before enter central sequence mode, clock src register have to set */ - if (!soc_is_exynos5250()) - s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); + s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); if (soc_is_exynos4210()) s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc)); } -static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) +static int exynos4_pm_add(struct device *dev, struct subsys_interface *sif) { - pm_cpu_prep = exynos_pm_prepare; - pm_cpu_sleep = exynos_cpu_suspend; + pm_cpu_prep = exynos4_pm_prepare; + pm_cpu_sleep = exynos4_cpu_suspend; return 0; } @@ -198,13 +273,13 @@ static void exynos4_restore_pll(void) } while (epll_wait || vpll_wait); } -static struct subsys_interface exynos_pm_interface = { - .name = "exynos_pm", +static struct subsys_interface exynos4_pm_interface = { + .name = "exynos4_pm", .subsys = &exynos_subsys, - .add_dev = exynos_pm_add, + .add_dev = exynos4_pm_add, }; -static __init int exynos_pm_drvinit(void) +static __init int exynos4_pm_drvinit(void) { struct clk *pll_base; unsigned int tmp; @@ -217,20 +292,18 @@ static __init int exynos_pm_drvinit(void) tmp |= ((0xFF << 8) | (0x1F << 1)); __raw_writel(tmp, S5P_WAKEUP_MASK); - if (!soc_is_exynos5250()) { - pll_base = clk_get(NULL, "xtal"); + pll_base = clk_get(NULL, "xtal"); - if (!IS_ERR(pll_base)) { - pll_base_rate = clk_get_rate(pll_base); - clk_put(pll_base); - } + if (!IS_ERR(pll_base)) { + pll_base_rate = clk_get_rate(pll_base); + clk_put(pll_base); } - return subsys_interface_register(&exynos_pm_interface); + return subsys_interface_register(&exynos4_pm_interface); } -arch_initcall(exynos_pm_drvinit); +arch_initcall(exynos4_pm_drvinit); -static int exynos_pm_suspend(void) +static int exynos4_pm_suspend(void) { unsigned long tmp; @@ -240,27 +313,27 @@ static int exynos_pm_suspend(void) tmp &= ~S5P_CENTRAL_LOWPWR_CFG; __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); - /* Setting SEQ_OPTION register */ - - tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); - __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + if (soc_is_exynos4212() || soc_is_exynos4412()) { + tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION); + tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM | + S5P_USE_STANDBYWFE_ISP_ARM); + __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); + } - if (!soc_is_exynos5250()) { - /* Save Power control register */ - asm ("mrc p15, 0, %0, c15, c0, 0" - : "=r" (tmp) : : "cc"); - save_arm_register[0] = tmp; + /* Save Power control register */ + asm ("mrc p15, 0, %0, c15, c0, 0" + : "=r" (tmp) : : "cc"); + save_arm_register[0] = tmp; - /* Save Diagnostic register */ - asm ("mrc p15, 0, %0, c15, c0, 1" - : "=r" (tmp) : : "cc"); - save_arm_register[1] = tmp; - } + /* Save Diagnostic register */ + asm ("mrc p15, 0, %0, c15, c0, 1" + : "=r" (tmp) : : "cc"); + save_arm_register[1] = tmp; return 0; } -static void exynos_pm_resume(void) +static void exynos4_pm_resume(void) { unsigned long tmp; @@ -277,19 +350,17 @@ static void exynos_pm_resume(void) /* No need to perform below restore code */ goto early_wakeup; } - if (!soc_is_exynos5250()) { - /* Restore Power control register */ - tmp = save_arm_register[0]; - asm volatile ("mcr p15, 0, %0, c15, c0, 0" - : : "r" (tmp) - : "cc"); - - /* Restore Diagnostic register */ - tmp = save_arm_register[1]; - asm volatile ("mcr p15, 0, %0, c15, c0, 1" - : : "r" (tmp) - : "cc"); - } + /* Restore Power control register */ + tmp = save_arm_register[0]; + asm volatile ("mcr p15, 0, %0, c15, c0, 0" + : : "r" (tmp) + : "cc"); + + /* Restore Diagnostic register */ + tmp = save_arm_register[1]; + asm volatile ("mcr p15, 0, %0, c15, c0, 1" + : : "r" (tmp) + : "cc"); /* For release retention */ @@ -301,28 +372,26 @@ static void exynos_pm_resume(void) __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); - s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); + s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); - if (!soc_is_exynos5250()) { - exynos4_restore_pll(); + exynos4_restore_pll(); #ifdef CONFIG_SMP - scu_enable(S5P_VA_SCU); + scu_enable(S5P_VA_SCU); #endif - } early_wakeup: return; } -static struct syscore_ops exynos_pm_syscore_ops = { - .suspend = exynos_pm_suspend, - .resume = exynos_pm_resume, +static struct syscore_ops exynos4_pm_syscore_ops = { + .suspend = exynos4_pm_suspend, + .resume = exynos4_pm_resume, }; -static __init int exynos_pm_syscore_init(void) +static __init int exynos4_pm_syscore_init(void) { - register_syscore_ops(&exynos_pm_syscore_ops); + register_syscore_ops(&exynos4_pm_syscore_ops); return 0; } -arch_initcall(exynos_pm_syscore_init); +arch_initcall(exynos4_pm_syscore_init); diff --git a/trunk/arch/arm/mach-exynos/pmu.c b/trunk/arch/arm/mach-exynos/pmu.c index 4aacb66f7161..77c6815eebee 100644 --- a/trunk/arch/arm/mach-exynos/pmu.c +++ b/trunk/arch/arm/mach-exynos/pmu.c @@ -1,8 +1,9 @@ -/* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. +/* linux/arch/arm/mach-exynos4/pmu.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * - * EXYNOS - CPU PMU(Power Management Unit) support + * EXYNOS4210 - CPU PMU(Power Management Unit) support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,14 +12,13 @@ #include #include -#include #include #include -static struct exynos_pmu_conf *exynos_pmu_config; +static struct exynos4_pmu_conf *exynos4_pmu_config; -static struct exynos_pmu_conf exynos4210_pmu_config[] = { +static struct exynos4_pmu_conf exynos4210_pmu_config[] = { /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, @@ -94,7 +94,7 @@ static struct exynos_pmu_conf exynos4210_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos4x12_pmu_config[] = { +static struct exynos4_pmu_conf exynos4x12_pmu_config[] = { { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -202,7 +202,7 @@ static struct exynos_pmu_conf exynos4x12_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos4412_pmu_config[] = { +static struct exynos4_pmu_conf exynos4412_pmu_config[] = { { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } }, @@ -212,174 +212,13 @@ static struct exynos_pmu_conf exynos4412_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ - { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { PMU_TABLE_END,}, -}; - -void __iomem *exynos5_list_both_cnt_feed[] = { - EXYNOS5_ARM_CORE0_OPTION, - EXYNOS5_ARM_CORE1_OPTION, - EXYNOS5_ARM_COMMON_OPTION, - EXYNOS5_GSCL_OPTION, - EXYNOS5_ISP_OPTION, - EXYNOS5_MFC_OPTION, - EXYNOS5_G3D_OPTION, - EXYNOS5_DISP1_OPTION, - EXYNOS5_MAU_OPTION, - EXYNOS5_TOP_PWR_OPTION, - EXYNOS5_TOP_PWR_SYSMEM_OPTION, -}; - -void __iomem *exynos5_list_diable_wfi_wfe[] = { - EXYNOS5_ARM_CORE1_OPTION, - EXYNOS5_FSYS_ARM_OPTION, - EXYNOS5_ISP_ARM_OPTION, -}; - -static void exynos5_init_pmu(void) +void exynos4_sys_powerdown_conf(enum sys_powerdown mode) { unsigned int i; - unsigned int tmp; - - /* - * Enable both SC_FEEDBACK and SC_COUNTER - */ - for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { - tmp = __raw_readl(exynos5_list_both_cnt_feed[i]); - tmp |= (EXYNOS5_USE_SC_FEEDBACK | - EXYNOS5_USE_SC_COUNTER); - __raw_writel(tmp, exynos5_list_both_cnt_feed[i]); - } - - /* - * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable - * MANUAL_L2RSTDISABLE_CONTROL_BITFIELD Enable - */ - tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION); - tmp |= (EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL | - EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN); - __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); - - /* - * Disable WFI/WFE on XXX_OPTION - */ - for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { - tmp = __raw_readl(exynos5_list_diable_wfi_wfe[i]); - tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | - EXYNOS5_OPTION_USE_STANDBYWFI); - __raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]); - } -} - -void exynos_sys_powerdown_conf(enum sys_powerdown mode) -{ - unsigned int i; - - if (soc_is_exynos5250()) - exynos5_init_pmu(); - for (i = 0; (exynos_pmu_config[i].reg != PMU_TABLE_END) ; i++) - __raw_writel(exynos_pmu_config[i].val[mode], - exynos_pmu_config[i].reg); + for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++) + __raw_writel(exynos4_pmu_config[i].val[mode], + exynos4_pmu_config[i].reg); if (soc_is_exynos4412()) { for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++) @@ -388,23 +227,20 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) } } -static int __init exynos_pmu_init(void) +static int __init exynos4_pmu_init(void) { - exynos_pmu_config = exynos4210_pmu_config; + exynos4_pmu_config = exynos4210_pmu_config; if (soc_is_exynos4210()) { - exynos_pmu_config = exynos4210_pmu_config; + exynos4_pmu_config = exynos4210_pmu_config; pr_info("EXYNOS4210 PMU Initialize\n"); } else if (soc_is_exynos4212() || soc_is_exynos4412()) { - exynos_pmu_config = exynos4x12_pmu_config; + exynos4_pmu_config = exynos4x12_pmu_config; pr_info("EXYNOS4x12 PMU Initialize\n"); - } else if (soc_is_exynos5250()) { - exynos_pmu_config = exynos5250_pmu_config; - pr_info("EXYNOS5250 PMU Initialize\n"); } else { - pr_info("EXYNOS: PMU not supported\n"); + pr_info("EXYNOS4: PMU not supported\n"); } return 0; } -arch_initcall(exynos_pmu_init); +arch_initcall(exynos4_pmu_init); diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index a9f80943d01f..ebbd7fc90eb4 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -108,7 +107,7 @@ static signed char irq2gpio[32] = { 7, 8, 9, 10, 11, 12, -1, -1, }; -static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +int gpio_to_irq(int gpio) { int irq; @@ -118,6 +117,7 @@ static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) } return -EINVAL; } +EXPORT_SYMBOL(gpio_to_irq); int irq_to_gpio(unsigned int irq) { @@ -383,56 +383,12 @@ static struct platform_device *ixp46x_devices[] __initdata = { unsigned long ixp4xx_exp_bus_size; EXPORT_SYMBOL(ixp4xx_exp_bus_size); -static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) -{ - gpio_line_config(gpio, IXP4XX_GPIO_IN); - - return 0; -} - -static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, - int level) -{ - gpio_line_set(gpio, level); - gpio_line_config(gpio, IXP4XX_GPIO_OUT); - - return 0; -} - -static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) -{ - int value; - - gpio_line_get(gpio, &value); - - return value; -} - -static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, - int value) -{ - gpio_line_set(gpio, value); -} - -static struct gpio_chip ixp4xx_gpio_chip = { - .label = "IXP4XX_GPIO_CHIP", - .direction_input = ixp4xx_gpio_direction_input, - .direction_output = ixp4xx_gpio_direction_output, - .get = ixp4xx_gpio_get_value, - .set = ixp4xx_gpio_set_value, - .to_irq = ixp4xx_gpio_to_irq, - .base = 0, - .ngpio = 16, -}; - void __init ixp4xx_sys_init(void) { ixp4xx_exp_bus_size = SZ_16M; platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); - gpiochip_add(&ixp4xx_gpio_chip); - if (cpu_is_ixp46x()) { int region; diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h b/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h index ef37f2635b0e..83d6b4ed60bb 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h @@ -1,2 +1,79 @@ -/* empty */ +/* + * arch/arm/mach-ixp4xx/include/mach/gpio.h + * + * IXP4XX GPIO wrappers for arch-neutral GPIO calls + * + * Written by Milan Svoboda + * Based on PXA implementation by Philipp Zabel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_IXP4XX_GPIO_H +#define __ASM_ARCH_IXP4XX_GPIO_H + +#include +#include + +#define __ARM_GPIOLIB_COMPLEX + +static inline int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +static inline void gpio_free(unsigned gpio) +{ + might_sleep(); + + return; +} + +static inline int gpio_direction_input(unsigned gpio) +{ + gpio_line_config(gpio, IXP4XX_GPIO_IN); + return 0; +} + +static inline int gpio_direction_output(unsigned gpio, int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, IXP4XX_GPIO_OUT); + return 0; +} + +static inline int gpio_get_value(unsigned gpio) +{ + int value; + + gpio_line_get(gpio, &value); + + return value; +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + gpio_line_set(gpio, value); +} + +#include /* cansleep wrappers */ + +extern int gpio_to_irq(int gpio); +#define gpio_to_irq gpio_to_irq +extern int irq_to_gpio(unsigned int irq); + +#endif diff --git a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h index b7a9f4d469e8..e53b2177319e 100644 --- a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -134,17 +134,6 @@ #define IRQ_S32416_WDT S3C2410_IRQSUB(27) #define IRQ_S32416_AC97 S3C2410_IRQSUB(28) -/* second interrupt-register of s3c2416/s3c2450 */ - -#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 54 + 29) -#define IRQ_S3C2416_2D S3C2416_IRQ(0) -#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1) -#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2) -#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3) -#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4) -#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5) -#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6) -#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7) /* extra irqs for s3c2440 */ @@ -186,9 +175,7 @@ #define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) -#if defined(CONFIG_CPU_S3C2416) -#define NR_IRQS (IRQ_S3C2416_I2S1 + 1) -#elif defined(CONFIG_CPU_S3C2443) +#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) #define NR_IRQS (IRQ_S3C2443_AC97+1) #else #define NR_IRQS (IRQ_S3C2440_AC97+1) diff --git a/trunk/arch/arm/mach-s3c24xx/irq-s3c2416.c b/trunk/arch/arm/mach-s3c24xx/irq-s3c2416.c index 23ec97370f32..fd49f35e448e 100644 --- a/trunk/arch/arm/mach-s3c24xx/irq-s3c2416.c +++ b/trunk/arch/arm/mach-s3c24xx/irq-s3c2416.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -193,43 +192,6 @@ static struct irq_chip s3c2416_irq_uart3 = { .irq_ack = s3c2416_irq_uart3_ack, }; -/* second interrupt register */ - -static inline void s3c2416_irq_ack_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - - __raw_writel(bitval, S3C2416_SRCPND2); - __raw_writel(bitval, S3C2416_INTPND2); -} - -static void s3c2416_irq_mask_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - unsigned long mask; - - mask = __raw_readl(S3C2416_INTMSK2); - mask |= bitval; - __raw_writel(mask, S3C2416_INTMSK2); -} - -static void s3c2416_irq_unmask_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - unsigned long mask; - - mask = __raw_readl(S3C2416_INTMSK2); - mask &= ~bitval; - __raw_writel(mask, S3C2416_INTMSK2); -} - -struct irq_chip s3c2416_irq_second = { - .irq_ack = s3c2416_irq_ack_second, - .irq_mask = s3c2416_irq_mask_second, - .irq_unmask = s3c2416_irq_unmask_second, -}; - - /* IRQ initialisation code */ static int __init s3c2416_add_sub(unsigned int base, @@ -251,42 +213,6 @@ static int __init s3c2416_add_sub(unsigned int base, return 0; } -static void __init s3c2416_irq_add_second(void) -{ - unsigned long pend; - unsigned long last; - int irqno; - int i; - - /* first, clear all interrupts pending... */ - last = 0; - for (i = 0; i < 4; i++) { - pend = __raw_readl(S3C2416_INTPND2); - - if (pend == 0 || pend == last) - break; - - __raw_writel(pend, S3C2416_SRCPND2); - __raw_writel(pend, S3C2416_INTPND2); - printk(KERN_INFO "irq: clearing pending status %08x\n", - (int)pend); - last = pend; - } - - for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) { - switch (irqno) { - case IRQ_S3C2416_RESERVED2: - case IRQ_S3C2416_RESERVED3: - /* no IRQ here */ - break; - default: - irq_set_chip_and_handler(irqno, &s3c2416_irq_second, - handle_edge_irq); - set_irq_flags(irqno, IRQF_VALID); - } - } -} - static int __init s3c2416_irq_add(struct device *dev, struct subsys_interface *sif) { @@ -306,8 +232,6 @@ static int __init s3c2416_irq_add(struct device *dev, &s3c2416_irq_wdtac97, IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); - s3c2416_irq_add_second(); - return 0; } @@ -324,25 +248,3 @@ static int __init s3c2416_irq_init(void) arch_initcall(s3c2416_irq_init); -#ifdef CONFIG_PM -static struct sleep_save irq_save[] = { - SAVE_ITEM(S3C2416_INTMSK2), -}; - -int s3c2416_irq_suspend(void) -{ - s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); - - return 0; -} - -void s3c2416_irq_resume(void) -{ - s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); -} - -struct syscore_ops s3c2416_irq_syscore_ops = { - .suspend = s3c2416_irq_suspend, - .resume = s3c2416_irq_resume, -}; -#endif diff --git a/trunk/arch/arm/mach-s3c24xx/s3c2416.c b/trunk/arch/arm/mach-s3c24xx/s3c2416.c index ed5a95ece9eb..7743fade50df 100644 --- a/trunk/arch/arm/mach-s3c24xx/s3c2416.c +++ b/trunk/arch/arm/mach-s3c24xx/s3c2416.c @@ -106,7 +106,6 @@ int __init s3c2416_init(void) register_syscore_ops(&s3c2416_pm_syscore_ops); #endif register_syscore_ops(&s3c24xx_irq_syscore_ops); - register_syscore_ops(&s3c2416_irq_syscore_ops); return device_register(&s3c2416_dev); } diff --git a/trunk/arch/arm/mach-s3c64xx/cpuidle.c b/trunk/arch/arm/mach-s3c64xx/cpuidle.c index acb197ccf3f7..179460f38db7 100644 --- a/trunk/arch/arm/mach-s3c64xx/cpuidle.c +++ b/trunk/arch/arm/mach-s3c64xx/cpuidle.c @@ -27,7 +27,12 @@ static int s3c64xx_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { + struct timeval before, after; unsigned long tmp; + int idle_time; + + local_irq_disable(); + do_gettimeofday(&before); /* Setup PWRCFG to enter idle mode */ tmp = __raw_readl(S3C64XX_PWR_CFG); @@ -37,32 +42,42 @@ static int s3c64xx_enter_idle(struct cpuidle_device *dev, cpu_do_idle(); + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; return index; } -static DEFINE_PER_CPU(struct cpuidle_device, s3c64xx_cpuidle_device); +static struct cpuidle_state s3c64xx_cpuidle_set[] = { + [0] = { + .enter = s3c64xx_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IDLE", + .desc = "System active, ARM gated", + }, +}; static struct cpuidle_driver s3c64xx_cpuidle_driver = { - .name = "s3c64xx_cpuidle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states = { - { - .enter = s3c64xx_enter_idle, - .exit_latency = 1, - .target_residency = 1, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IDLE", - .desc = "System active, ARM gated", - }, - }, - .state_count = 1, + .name = "s3c64xx_cpuidle", + .owner = THIS_MODULE, + .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), +}; + +static struct cpuidle_device s3c64xx_cpuidle_device = { + .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), }; static int __init s3c64xx_init_cpuidle(void) { int ret; + memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set, + sizeof(s3c64xx_cpuidle_set)); cpuidle_register_driver(&s3c64xx_cpuidle_driver); ret = cpuidle_register_device(&s3c64xx_cpuidle_device); diff --git a/trunk/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/trunk/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 7a27f5603c74..0ace108c3e3d 100644 --- a/trunk/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/trunk/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -182,11 +182,6 @@ static const struct i2c_board_info wm1277_devs[] = { }, }; -static const struct i2c_board_info wm6230_i2c_devs[] = { - { I2C_BOARD_INFO("wm9081", 0x6c), - .platform_data = &wm9081_pdata, }, -}; - static __devinitdata const struct { u8 id; const char *name; @@ -200,9 +195,7 @@ static __devinitdata const struct { { .id = 0x03, .name = "1252-EV1 Glenlivet" }, { .id = 0x11, .name = "6249-EV2 Glenfarclas", }, { .id = 0x14, .name = "6271-EV1 Lochnagar" }, - { .id = 0x15, .name = "6320-EV1 Bells", - .i2c_devs = wm6230_i2c_devs, - .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) }, + { .id = 0x15, .name = "XXXX-EV1 Bells" }, { .id = 0x21, .name = "1275-EV1 Mortlach" }, { .id = 0x25, .name = "1274-EV1 Glencadam" }, { .id = 0x31, .name = "1253-EV1 Tomatin", diff --git a/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c b/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c index 6b20a71d7dbf..eda5e027b109 100644 --- a/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -671,7 +671,6 @@ static struct i2c_board_info i2c_devs1[] __initdata = { .irq = S3C_EINT(0), .platform_data = &glenfarclas_pmic_pdata }, - { I2C_BOARD_INFO("wlf-gf-module", 0x22) }, { I2C_BOARD_INFO("wlf-gf-module", 0x24) }, { I2C_BOARD_INFO("wlf-gf-module", 0x25) }, { I2C_BOARD_INFO("wlf-gf-module", 0x26) }, diff --git a/trunk/arch/arm/mach-vexpress/v2m.c b/trunk/arch/arm/mach-vexpress/v2m.c index fde26adaef32..04dd092211b8 100644 --- a/trunk/arch/arm/mach-vexpress/v2m.c +++ b/trunk/arch/arm/mach-vexpress/v2m.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/plat-samsung/include/plat/s3c2416.h b/trunk/arch/arm/plat-samsung/include/plat/s3c2416.h index 7178e338e25e..de2b5bdc5ebd 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/s3c2416.h +++ b/trunk/arch/arm/plat-samsung/include/plat/s3c2416.h @@ -24,9 +24,6 @@ extern void s3c2416_init_clocks(int xtal); extern int s3c2416_baseclk_add(void); extern void s3c2416_restart(char mode, const char *cmd); - -extern struct syscore_ops s3c2416_irq_syscore_ops; - #else #define s3c2416_init_clocks NULL #define s3c2416_init_uarts NULL diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 3ff21b536f28..ddb8b24b823d 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -18,7 +18,6 @@ config PARISC select IRQ_PER_CPU select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD - select GENERIC_STRNCPY_FROM_USER help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/trunk/arch/parisc/include/asm/smp.h b/trunk/arch/parisc/include/asm/smp.h index a5dc9066c6d8..e8f8037d872b 100644 --- a/trunk/arch/parisc/include/asm/smp.h +++ b/trunk/arch/parisc/include/asm/smp.h @@ -25,6 +25,7 @@ typedef unsigned long address_t; #define cpu_number_map(cpu) (cpu) #define cpu_logical_map(cpu) (cpu) +extern void smp_send_reschedule(int cpu); extern void smp_send_all_nop(void); extern void arch_send_call_function_single_ipi(int cpu); @@ -49,5 +50,6 @@ static inline void __cpu_die (unsigned int cpu) { while(1) ; } +extern int __cpu_up (unsigned int cpu); #endif /* __ASM_SMP_H */ diff --git a/trunk/arch/parisc/include/asm/uaccess.h b/trunk/arch/parisc/include/asm/uaccess.h index 4ba2c93770f1..9ac066086f03 100644 --- a/trunk/arch/parisc/include/asm/uaccess.h +++ b/trunk/arch/parisc/include/asm/uaccess.h @@ -218,14 +218,15 @@ struct exception_data { extern unsigned long lcopy_to_user(void __user *, const void *, unsigned long); extern unsigned long lcopy_from_user(void *, const void __user *, unsigned long); extern unsigned long lcopy_in_user(void __user *, const void __user *, unsigned long); -extern long strncpy_from_user(char *, const char __user *, long); +extern long lstrncpy_from_user(char *, const char __user *, long); extern unsigned lclear_user(void __user *,unsigned long); extern long lstrnlen_user(const char __user *,long); + /* * Complex access routines -- macros */ -#define user_addr_max() (~0UL) +#define strncpy_from_user lstrncpy_from_user #define strnlen_user lstrnlen_user #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL) #define clear_user lclear_user diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 07ef351edd57..535034217021 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -552,7 +552,7 @@ * entry (identifying the physical page) and %r23 up with * the from tlb entry (or nothing if only a to entry---for * clear_user_page_asm) */ - .macro do_alias spc,tmp,tmp1,va,pte,prot,fault,patype + .macro do_alias spc,tmp,tmp1,va,pte,prot,fault cmpib,COND(<>),n 0,\spc,\fault ldil L%(TMPALIAS_MAP_START),\tmp #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) @@ -581,15 +581,11 @@ */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot -.ifc \patype,20 +#ifdef CONFIG_64BIT depd,z \prot,8,7,\prot -.else -.ifc \patype,11 +#else depw,z \prot,8,7,\prot -.else - .error "undefined PA type to do_alias" -.endif -.endif +#endif /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. @@ -1193,7 +1189,7 @@ dtlb_miss_20w: nop dtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot @@ -1217,7 +1213,7 @@ nadtlb_miss_20w: nop nadtlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot @@ -1249,7 +1245,7 @@ dtlb_miss_11: nop dtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,11 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlba pte,(va) idtlbp prot,(va) @@ -1281,7 +1277,7 @@ nadtlb_miss_11: nop nadtlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,11 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlba pte,(va) idtlbp prot,(va) @@ -1308,7 +1304,7 @@ dtlb_miss_20: nop dtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,dtlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlbt pte,prot @@ -1334,7 +1330,7 @@ nadtlb_miss_20: nop nadtlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate,20 + do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot @@ -1461,7 +1457,7 @@ naitlb_miss_20w: nop naitlb_check_alias_20w: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot @@ -1515,7 +1511,7 @@ naitlb_miss_11: nop naitlb_check_alias_11: - do_alias spc,t0,t1,va,pte,prot,itlb_fault,11 + do_alias spc,t0,t1,va,pte,prot,itlb_fault iitlba pte,(%sr0, va) iitlbp prot,(%sr0, va) @@ -1561,7 +1557,7 @@ naitlb_miss_20: nop naitlb_check_alias_20: - do_alias spc,t0,t1,va,pte,prot,naitlb_fault,20 + do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index ceec85de6290..a7bb757a5497 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -44,6 +44,7 @@ EXPORT_SYMBOL(__cmpxchg_u64); #endif #include +EXPORT_SYMBOL(lstrncpy_from_user); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); diff --git a/trunk/arch/parisc/kernel/vmlinux.lds.S b/trunk/arch/parisc/kernel/vmlinux.lds.S index 64a999882e4f..fa6f2b8163e0 100644 --- a/trunk/arch/parisc/kernel/vmlinux.lds.S +++ b/trunk/arch/parisc/kernel/vmlinux.lds.S @@ -50,10 +50,8 @@ SECTIONS . = KERNEL_BINARY_TEXT_START; _text = .; /* Text and read-only data */ - .head ALIGN(16) : { - HEAD_TEXT - } = 0 .text ALIGN(16) : { + HEAD_TEXT TEXT_TEXT SCHED_TEXT LOCK_TEXT @@ -67,7 +65,7 @@ SECTIONS *(.fixup) *(.lock.text) /* out-of-line lock text */ *(.gnu.warning) - } + } = 0 /* End of text section */ _etext = .; diff --git a/trunk/arch/parisc/lib/lusercopy.S b/trunk/arch/parisc/lib/lusercopy.S index 6f2d9355efe2..1bd23ccec17b 100644 --- a/trunk/arch/parisc/lib/lusercopy.S +++ b/trunk/arch/parisc/lib/lusercopy.S @@ -60,6 +60,47 @@ bv %r0(%r1) .endm + /* + * long lstrncpy_from_user(char *dst, const char *src, long n) + * + * Returns -EFAULT if exception before terminator, + * N if the entire buffer filled, + * otherwise strlen (i.e. excludes zero byte) + */ + +ENTRY(lstrncpy_from_user) + .proc + .callinfo NO_CALLS + .entry + comib,= 0,%r24,$lsfu_done + copy %r24,%r23 + get_sr +1: ldbs,ma 1(%sr1,%r25),%r1 +$lsfu_loop: + stbs,ma %r1,1(%r26) + comib,=,n 0,%r1,$lsfu_done + addib,<>,n -1,%r24,$lsfu_loop +2: ldbs,ma 1(%sr1,%r25),%r1 +$lsfu_done: + sub %r23,%r24,%r28 +$lsfu_exit: + bv %r0(%r2) + nop + .exit +ENDPROC(lstrncpy_from_user) + + .section .fixup,"ax" +3: fixup_branch $lsfu_exit + ldi -EFAULT,%r28 + .previous + + .section __ex_table,"aw" + ASM_ULONG_INSN 1b,3b + ASM_ULONG_INSN 2b,3b + .previous + + .procend + /* * unsigned long lclear_user(void *to, unsigned long n) * diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index a39b4690c171..b403c533432c 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -87,7 +87,6 @@ config S390 select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP - select HAVE_CMPXCHG_LOCAL select ARCH_DISCARD_MEMBLOCK select ARCH_INLINE_SPIN_TRYLOCK select ARCH_INLINE_SPIN_TRYLOCK_BH diff --git a/trunk/arch/s390/include/asm/bitops.h b/trunk/arch/s390/include/asm/bitops.h index a6ff5a83e227..e5beb490959b 100644 --- a/trunk/arch/s390/include/asm/bitops.h +++ b/trunk/arch/s390/include/asm/bitops.h @@ -13,6 +13,8 @@ * */ +#ifdef __KERNEL__ + #ifndef _LINUX_BITOPS_H #error only can be included directly #endif @@ -61,7 +63,7 @@ extern const char _ni_bitmap[]; extern const char _zb_findmap[]; extern const char _sb_findmap[]; -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define __BITOPS_ALIGN 3 #define __BITOPS_WORDSIZE 32 @@ -81,7 +83,7 @@ extern const char _sb_findmap[]; : "d" (__val), "Q" (*(unsigned long *) __addr) \ : "cc"); -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define __BITOPS_ALIGN 7 #define __BITOPS_WORDSIZE 64 @@ -101,7 +103,7 @@ extern const char _sb_findmap[]; : "d" (__val), "Q" (*(unsigned long *) __addr) \ : "cc"); -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) #define __BITOPS_BARRIER() asm volatile("" : : : "memory") @@ -410,7 +412,7 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr, unsigned long bytes = 0; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " ahi %1,-1\n" " sra %1,5\n" " jz 1f\n" @@ -447,7 +449,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, unsigned long bytes = 0; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " ahi %1,-1\n" " sra %1,5\n" " jz 1f\n" @@ -479,7 +481,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, */ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if ((word & 0xffffffff) == 0xffffffff) { word >>= 32; nr += 32; @@ -503,7 +505,7 @@ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) */ static inline unsigned long __ffs_word(unsigned long nr, unsigned long word) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if ((word & 0xffffffff) == 0) { word >>= 32; nr += 32; @@ -544,7 +546,7 @@ static inline unsigned long __load_ulong_le(const unsigned long *p, unsigned long word; p = (unsigned long *)((unsigned long) p + offset); -#ifndef CONFIG_64BIT +#ifndef __s390x__ asm volatile( " ic %0,%O1(%R1)\n" " icm %0,2,%O1+1(%R1)\n" @@ -832,4 +834,7 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, #include + +#endif /* __KERNEL__ */ + #endif /* _S390_BITOPS_H */ diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index 4c8d4d5b8bd2..fc50a3342da3 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -10,6 +10,8 @@ #include #include +#ifdef __KERNEL__ + #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 @@ -289,3 +291,5 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl); int chsc_sstpi(void *page, void *result, size_t size); #endif + +#endif diff --git a/trunk/arch/s390/include/asm/cmpxchg.h b/trunk/arch/s390/include/asm/cmpxchg.h index 8d798e962b63..81d7908416cf 100644 --- a/trunk/arch/s390/include/asm/cmpxchg.h +++ b/trunk/arch/s390/include/asm/cmpxchg.h @@ -29,7 +29,7 @@ static inline unsigned long __xchg(unsigned long x, void *ptr, int size) " cs %0,0,%4\n" " jl 0b\n" : "=&d" (old), "=Q" (*(int *) addr) - : "d" ((x & 0xff) << shift), "d" (~(0xff << shift)), + : "d" (x << shift), "d" (~(255 << shift)), "Q" (*(int *) addr) : "memory", "cc", "0"); return old >> shift; case 2: @@ -44,7 +44,7 @@ static inline unsigned long __xchg(unsigned long x, void *ptr, int size) " cs %0,0,%4\n" " jl 0b\n" : "=&d" (old), "=Q" (*(int *) addr) - : "d" ((x & 0xffff) << shift), "d" (~(0xffff << shift)), + : "d" (x << shift), "d" (~(65535 << shift)), "Q" (*(int *) addr) : "memory", "cc", "0"); return old >> shift; case 4: @@ -113,10 +113,9 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) - : "d" ((old & 0xff) << shift), - "d" ((new & 0xff) << shift), - "d" (~(0xff << shift)) + : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) + : "d" (old << shift), "d" (new << shift), + "d" (~(255 << shift)), "Q" (*(int *) ptr) : "memory", "cc"); return prev >> shift; case 2: @@ -135,10 +134,9 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, " nr %1,%5\n" " jnz 0b\n" "1:" - : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr) - : "d" ((old & 0xffff) << shift), - "d" ((new & 0xffff) << shift), - "d" (~(0xffff << shift)) + : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) + : "d" (old << shift), "d" (new << shift), + "d" (~(65535 << shift)), "Q" (*(int *) ptr) : "memory", "cc"); return prev >> shift; case 4: @@ -162,14 +160,9 @@ static inline unsigned long __cmpxchg(void *ptr, unsigned long old, return old; } -#define cmpxchg(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \ - sizeof(*(ptr))); \ - __ret; \ -}) +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) #ifdef CONFIG_64BIT #define cmpxchg64(ptr, o, n) \ @@ -188,19 +181,13 @@ static inline unsigned long long __cmpxchg64(void *ptr, " cds %0,%2,%1" : "+&d" (rp_old), "=Q" (ptr) : "d" (rp_new), "Q" (ptr) - : "memory", "cc"); + : "cc"); return rp_old.pair; } - -#define cmpxchg64(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg64((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n)); \ - __ret; \ -}) +#define cmpxchg64(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) #endif /* CONFIG_64BIT */ #include @@ -229,13 +216,8 @@ static inline unsigned long __cmpxchg_local(void *ptr, * them available. */ #define cmpxchg_local(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg_local((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr))); \ - __ret; \ -}) + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) #define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n)) diff --git a/trunk/arch/s390/include/asm/cputime.h b/trunk/arch/s390/include/asm/cputime.h index 718374de9c7f..24ef186a1c4f 100644 --- a/trunk/arch/s390/include/asm/cputime.h +++ b/trunk/arch/s390/include/asm/cputime.h @@ -21,15 +21,15 @@ typedef unsigned long long __nocast cputime64_t; static inline unsigned long __div(unsigned long long n, unsigned long base) { -#ifndef CONFIG_64BIT +#ifndef __s390x__ register_pair rp; rp.pair = n >> 1; asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1)); return rp.subreg.odd; -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ return n / base; -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ } #define cputime_one_jiffy jiffies_to_cputime(1) @@ -100,7 +100,7 @@ static inline void cputime_to_timespec(const cputime_t cputime, struct timespec *value) { unsigned long long __cputime = (__force unsigned long long) cputime; -#ifndef CONFIG_64BIT +#ifndef __s390x__ register_pair rp; rp.pair = __cputime >> 1; @@ -128,7 +128,7 @@ static inline void cputime_to_timeval(const cputime_t cputime, struct timeval *value) { unsigned long long __cputime = (__force unsigned long long) cputime; -#ifndef CONFIG_64BIT +#ifndef __s390x__ register_pair rp; rp.pair = __cputime >> 1; diff --git a/trunk/arch/s390/include/asm/ctl_reg.h b/trunk/arch/s390/include/asm/ctl_reg.h index debfda33d1f8..ecde9417d669 100644 --- a/trunk/arch/s390/include/asm/ctl_reg.h +++ b/trunk/arch/s390/include/asm/ctl_reg.h @@ -7,7 +7,7 @@ #ifndef __ASM_CTL_REG_H #define __ASM_CTL_REG_H -#ifdef CONFIG_64BIT +#ifdef __s390x__ #define __ctl_load(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ @@ -25,7 +25,7 @@ : "i" (low), "i" (high)); \ }) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define __ctl_load(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ @@ -43,7 +43,7 @@ : "i" (low), "i" (high)); \ }) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define __ctl_set_bit(cr, bit) ({ \ unsigned long __dummy; \ diff --git a/trunk/arch/s390/include/asm/current.h b/trunk/arch/s390/include/asm/current.h index 7a68084ec2f0..83cf36cde2da 100644 --- a/trunk/arch/s390/include/asm/current.h +++ b/trunk/arch/s390/include/asm/current.h @@ -11,10 +11,13 @@ #ifndef _S390_CURRENT_H #define _S390_CURRENT_H +#ifdef __KERNEL__ #include struct task_struct; #define current ((struct task_struct *const)S390_lowcore.current_task) +#endif + #endif /* !(_S390_CURRENT_H) */ diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h index 06151e6a3098..c4ee39f7a4d6 100644 --- a/trunk/arch/s390/include/asm/elf.h +++ b/trunk/arch/s390/include/asm/elf.h @@ -107,11 +107,11 @@ /* * These are used to set parameters in the core dumps. */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define ELF_CLASS ELFCLASS32 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define ELF_CLASS ELFCLASS64 -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define ELF_DATA ELFDATA2MSB #define ELF_ARCH EM_S390 @@ -181,9 +181,9 @@ extern unsigned long elf_hwcap; extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define SET_PERSONALITY(ex) set_personality(PER_LINUX) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define SET_PERSONALITY(ex) \ do { \ if (personality(current->personality) != PER_LINUX32) \ @@ -194,7 +194,7 @@ do { \ else \ clear_thread_flag(TIF_31BIT); \ } while (0) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define STACK_RND_MASK 0x7ffUL diff --git a/trunk/arch/s390/include/asm/futex.h b/trunk/arch/s390/include/asm/futex.h index 96bc83ea5c90..81cf36b691f1 100644 --- a/trunk/arch/s390/include/asm/futex.h +++ b/trunk/arch/s390/include/asm/futex.h @@ -1,6 +1,8 @@ #ifndef _ASM_S390_FUTEX_H #define _ASM_S390_FUTEX_H +#ifdef __KERNEL__ + #include #include #include @@ -46,4 +48,5 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval); } +#endif /* __KERNEL__ */ #endif /* _ASM_S390_FUTEX_H */ diff --git a/trunk/arch/s390/include/asm/idals.h b/trunk/arch/s390/include/asm/idals.h index aef0dde340d1..aae276d00383 100644 --- a/trunk/arch/s390/include/asm/idals.h +++ b/trunk/arch/s390/include/asm/idals.h @@ -20,7 +20,7 @@ #include #include -#ifdef CONFIG_64BIT +#ifdef __s390x__ #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */ #else #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */ @@ -33,7 +33,7 @@ static inline int idal_is_needed(void *vaddr, unsigned int length) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ return ((__pa(vaddr) + length - 1) >> 31) != 0; #else return 0; @@ -78,7 +78,7 @@ static inline unsigned long *idal_create_words(unsigned long *idaws, static inline int set_normalized_cda(struct ccw1 * ccw, void *vaddr) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ unsigned int nridaws; unsigned long *idal; @@ -105,7 +105,7 @@ set_normalized_cda(struct ccw1 * ccw, void *vaddr) static inline void clear_normalized_cda(struct ccw1 * ccw) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if (ccw->flags & CCW_FLAG_IDA) { kfree((void *)(unsigned long) ccw->cda); ccw->flags &= ~CCW_FLAG_IDA; @@ -182,7 +182,7 @@ idal_buffer_free(struct idal_buffer *ib) static inline int __idal_buffer_is_needed(struct idal_buffer *ib) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ return ib->size > (4096ul << ib->page_order) || idal_is_needed(ib->data[0], ib->size); #else diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index f81a0975cbea..27216d317991 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -11,6 +11,8 @@ #ifndef _S390_IO_H #define _S390_IO_H +#ifdef __KERNEL__ + #include #define IO_SPACE_LIMIT 0xffffffff @@ -44,4 +46,6 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr); */ #define xlate_dev_kmem_ptr(p) p +#endif /* __KERNEL__ */ + #endif diff --git a/trunk/arch/s390/include/asm/irq.h b/trunk/arch/s390/include/asm/irq.h index 2b9d41899d21..5289cacd4861 100644 --- a/trunk/arch/s390/include/asm/irq.h +++ b/trunk/arch/s390/include/asm/irq.h @@ -17,8 +17,7 @@ enum interruption_class { EXTINT_VRT, EXTINT_SCP, EXTINT_IUC, - EXTINT_CMS, - EXTINT_CMC, + EXTINT_CPM, IOINT_CIO, IOINT_QAI, IOINT_DAS, diff --git a/trunk/arch/s390/include/asm/kexec.h b/trunk/arch/s390/include/asm/kexec.h index f4f38826eebb..3f30dac804ea 100644 --- a/trunk/arch/s390/include/asm/kexec.h +++ b/trunk/arch/s390/include/asm/kexec.h @@ -10,8 +10,10 @@ #ifndef _S390_KEXEC_H #define _S390_KEXEC_H -#include +#ifdef __KERNEL__ #include +#endif +#include /* * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. * I.e. Maximum page that is mapped directly into kernel memory, diff --git a/trunk/arch/s390/include/asm/kmap_types.h b/trunk/arch/s390/include/asm/kmap_types.h index 0a88622339ee..94ec3ee07983 100644 --- a/trunk/arch/s390/include/asm/kmap_types.h +++ b/trunk/arch/s390/include/asm/kmap_types.h @@ -1,6 +1,8 @@ +#ifdef __KERNEL__ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H #include #endif +#endif /* __KERNEL__ */ diff --git a/trunk/arch/s390/include/asm/mmu_context.h b/trunk/arch/s390/include/asm/mmu_context.h index 69bdf72e95ec..5d09e405c54d 100644 --- a/trunk/arch/s390/include/asm/mmu_context.h +++ b/trunk/arch/s390/include/asm/mmu_context.h @@ -49,7 +49,7 @@ static inline int init_new_context(struct task_struct *tsk, #define destroy_context(mm) do { } while (0) -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define LCTL_OPCODE "lctl" #else #define LCTL_OPCODE "lctlg" diff --git a/trunk/arch/s390/include/asm/module.h b/trunk/arch/s390/include/asm/module.h index f0b6b26b6e59..1cc1c5af705a 100644 --- a/trunk/arch/s390/include/asm/module.h +++ b/trunk/arch/s390/include/asm/module.h @@ -28,7 +28,7 @@ struct mod_arch_specific struct mod_arch_syminfo *syminfo; }; -#ifdef CONFIG_64BIT +#ifdef __s390x__ #define ElfW(x) Elf64_ ## x #define ELFW(x) ELF64_ ## x #else diff --git a/trunk/arch/s390/include/asm/os_info.h b/trunk/arch/s390/include/asm/os_info.h index 295f2c4f1c96..d07518af09ea 100644 --- a/trunk/arch/s390/include/asm/os_info.h +++ b/trunk/arch/s390/include/asm/os_info.h @@ -13,6 +13,7 @@ #define OS_INFO_VMCOREINFO 0 #define OS_INFO_REIPL_BLOCK 1 +#define OS_INFO_INIT_FN 2 struct os_info_entry { u64 addr; @@ -27,8 +28,8 @@ struct os_info { u16 version_minor; u64 crashkernel_addr; u64 crashkernel_size; - struct os_info_entry entry[2]; - u8 reserved[4024]; + struct os_info_entry entry[3]; + u8 reserved[4004]; } __packed; void os_info_init(void); diff --git a/trunk/arch/s390/include/asm/percpu.h b/trunk/arch/s390/include/asm/percpu.h index 6537e72e0853..0fbd1899c7b0 100644 --- a/trunk/arch/s390/include/asm/percpu.h +++ b/trunk/arch/s390/include/asm/percpu.h @@ -15,7 +15,7 @@ * per cpu area, use weak definitions to force the compiler to * generate external references. */ -#if defined(CONFIG_SMP) && defined(CONFIG_64BIT) && defined(MODULE) +#if defined(CONFIG_SMP) && defined(__s390x__) && defined(MODULE) #define ARCH_NEEDS_WEAK_PER_CPU #endif diff --git a/trunk/arch/s390/include/asm/pgalloc.h b/trunk/arch/s390/include/asm/pgalloc.h index 43078c194394..78e3041919de 100644 --- a/trunk/arch/s390/include/asm/pgalloc.h +++ b/trunk/arch/s390/include/asm/pgalloc.h @@ -48,7 +48,7 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry) clear_table(crst, entry, sizeof(unsigned long)*2048); } -#ifndef CONFIG_64BIT +#ifndef __s390x__ static inline unsigned long pgd_entry_type(struct mm_struct *mm) { @@ -64,7 +64,7 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) #define pgd_populate(mm, pgd, pud) BUG() #define pud_populate(mm, pud, pmd) BUG() -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ static inline unsigned long pgd_entry_type(struct mm_struct *mm) { @@ -106,7 +106,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) pud_val(*pud) = _REGION3_ENTRY | __pa(pmd); } -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ static inline pgd_t *pgd_alloc(struct mm_struct *mm) { diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index b3227415abda..011358c1b18e 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -74,15 +74,15 @@ static inline int is_zero_pfn(unsigned long pfn) * table can map * PGDIR_SHIFT determines what a third-level page table entry can map */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ # define PMD_SHIFT 20 # define PUD_SHIFT 20 # define PGDIR_SHIFT 20 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ # define PMD_SHIFT 20 # define PUD_SHIFT 31 # define PGDIR_SHIFT 42 -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) @@ -98,13 +98,13 @@ static inline int is_zero_pfn(unsigned long pfn) * that leads to 1024 pte per pgd */ #define PTRS_PER_PTE 256 -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define PTRS_PER_PMD 1 #define PTRS_PER_PUD 1 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define PTRS_PER_PMD 2048 #define PTRS_PER_PUD 2048 -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0 @@ -276,7 +276,7 @@ extern struct page *vmemmap; * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ /* Bits in the segment table address-space-control-element */ #define _ASCE_SPACE_SWITCH 0x80000000UL /* space switch event */ @@ -308,7 +308,7 @@ extern struct page *vmemmap; #define KVM_UR_BIT 0x00008000UL #define KVM_UC_BIT 0x00004000UL -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ /* Bits in the segment/region table address-space-control-element */ #define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ @@ -363,7 +363,7 @@ extern struct page *vmemmap; #define KVM_UR_BIT 0x0000800000000000UL #define KVM_UC_BIT 0x0000400000000000UL -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ /* * A user page table pointer has the space-switch-event bit, the @@ -424,7 +424,7 @@ static inline int mm_has_pgste(struct mm_struct *mm) /* * pgd/pmd/pte query functions */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ static inline int pgd_present(pgd_t pgd) { return 1; } static inline int pgd_none(pgd_t pgd) { return 0; } @@ -434,7 +434,7 @@ static inline int pud_present(pud_t pud) { return 1; } static inline int pud_none(pud_t pud) { return 0; } static inline int pud_bad(pud_t pud) { return 0; } -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ static inline int pgd_present(pgd_t pgd) { @@ -490,7 +490,7 @@ static inline int pud_bad(pud_t pud) return (pud_val(pud) & mask) != 0; } -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ static inline int pmd_present(pmd_t pmd) { @@ -741,7 +741,7 @@ static inline int pte_young(pte_t pte) static inline void pgd_clear(pgd_t *pgd) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; #endif @@ -749,7 +749,7 @@ static inline void pgd_clear(pgd_t *pgd) static inline void pud_clear(pud_t *pud) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) pud_val(*pud) = _REGION3_ENTRY_EMPTY; #endif @@ -921,7 +921,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, static inline void __ptep_ipte(unsigned long address, pte_t *ptep) { if (!(pte_val(*ptep) & _PAGE_INVALID)) { -#ifndef CONFIG_64BIT +#ifndef __s390x__ /* pto must point to the start of the segment table */ pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); #else @@ -1116,7 +1116,7 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) #define pgd_offset_k(address) pgd_offset(&init_mm, address) -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pmd) ({ BUG(); 0UL; }) @@ -1125,7 +1125,7 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pud_offset(pgd, address) ((pud_t *) pgd) #define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address)) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) @@ -1147,7 +1147,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) return pmd + pmd_index(address); } -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot)) #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) @@ -1196,7 +1196,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define __SWP_OFFSET_MASK (~0UL >> 12) #else #define __SWP_OFFSET_MASK (~0UL >> 11) @@ -1217,11 +1217,11 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#ifndef CONFIG_64BIT +#ifndef __s390x__ # define PTE_FILE_MAX_BITS 26 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ # define PTE_FILE_MAX_BITS 59 -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define pte_to_pgoff(__pte) \ ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index 20d0585cf905..6cbf31311673 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -20,6 +20,7 @@ #include #include +#ifdef __KERNEL__ /* * Default implementation of macro that returns current * instruction pointer ("program counter"). @@ -32,33 +33,39 @@ static inline void get_cpu_id(struct cpuid *ptr) } extern void s390_adjust_jiffies(void); +extern int get_cpu_capability(unsigned int *); extern const struct seq_operations cpuinfo_op; extern int sysctl_ieee_emulation_warnings; /* * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define TASK_SIZE (1UL << 31) #define TASK_UNMAPPED_BASE (1UL << 30) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #define TASK_SIZE TASK_SIZE_OF(current) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ -#ifndef CONFIG_64BIT +#ifdef __KERNEL__ + +#ifndef __s390x__ #define STACK_TOP (1UL << 31) #define STACK_TOP_MAX (1UL << 31) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define STACK_TOP (1UL << (test_thread_flag(TIF_31BIT) ? 31:42)) #define STACK_TOP_MAX (1UL << 42) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ + + +#endif #define HAVE_ARCH_PICK_MMAP_LAYOUT @@ -175,7 +182,7 @@ static inline void psw_set_key(unsigned int key) */ static inline void __load_psw(psw_t psw) { -#ifndef CONFIG_64BIT +#ifndef __s390x__ asm volatile("lpsw %0" : : "Q" (psw) : "cc"); #else asm volatile("lpswe %0" : : "Q" (psw) : "cc"); @@ -193,7 +200,7 @@ static inline void __load_psw_mask (unsigned long mask) psw.mask = mask; -#ifndef CONFIG_64BIT +#ifndef __s390x__ asm volatile( " basr %0,0\n" "0: ahi %0,1f-0b\n" @@ -201,14 +208,14 @@ static inline void __load_psw_mask (unsigned long mask) " lpsw %1\n" "1:" : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc"); -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ asm volatile( " larl %0,1f\n" " stg %0,%O1+8(%R1)\n" " lpswe %1\n" "1:" : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc"); -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ } /* @@ -216,7 +223,7 @@ static inline void __load_psw_mask (unsigned long mask) */ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc) { -#ifndef CONFIG_64BIT +#ifndef __s390x__ if (psw.addr & PSW_ADDR_AMODE) /* 31 bit mode */ return (psw.addr - ilc) | PSW_ADDR_AMODE; @@ -246,7 +253,7 @@ static inline void __noreturn disabled_wait(unsigned long code) * Store status and then load disabled wait psw, * the processor is dead afterwards */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ asm volatile( " stctl 0,0,0(%2)\n" " ni 0(%2),0xef\n" /* switch off protection */ @@ -265,7 +272,7 @@ static inline void __noreturn disabled_wait(unsigned long code) " lpsw 0(%1)" : "=m" (ctl_buf) : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc"); -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ asm volatile( " stctg 0,0,0(%2)\n" " ni 4(%2),0xef\n" /* switch off protection */ @@ -298,7 +305,7 @@ static inline void __noreturn disabled_wait(unsigned long code) " lpswe 0(%1)" : "=m" (ctl_buf) : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0", "1"); -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ while (1); } @@ -331,10 +338,12 @@ extern void (*s390_base_ext_handler_fn)(void); #define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL +#endif + /* * Helper macro for exception table entries */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define EX_TABLE(_fault,_target) \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ diff --git a/trunk/arch/s390/include/asm/rwsem.h b/trunk/arch/s390/include/asm/rwsem.h index 1ceee10264c3..d0eb4653cebd 100644 --- a/trunk/arch/s390/include/asm/rwsem.h +++ b/trunk/arch/s390/include/asm/rwsem.h @@ -41,17 +41,19 @@ #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" #endif -#ifndef CONFIG_64BIT +#ifdef __KERNEL__ + +#ifndef __s390x__ #define RWSEM_UNLOCKED_VALUE 0x00000000 #define RWSEM_ACTIVE_BIAS 0x00000001 #define RWSEM_ACTIVE_MASK 0x0000ffff #define RWSEM_WAITING_BIAS (-0x00010000) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define RWSEM_UNLOCKED_VALUE 0x0000000000000000L #define RWSEM_ACTIVE_BIAS 0x0000000000000001L #define RWSEM_ACTIVE_MASK 0x00000000ffffffffL #define RWSEM_WAITING_BIAS (-0x0000000100000000L) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) @@ -63,19 +65,19 @@ static inline void __down_read(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " ahi %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " aghi %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -91,7 +93,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: ltr %1,%0\n" " jm 1f\n" @@ -99,7 +101,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) " cs %0,%1,%2\n" " jl 0b\n" "1:" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: ltgr %1,%0\n" " jm 1f\n" @@ -107,7 +109,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) " csg %0,%1,%2\n" " jl 0b\n" "1:" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -123,19 +125,19 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) tmp = RWSEM_ACTIVE_WRITE_BIAS; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -156,19 +158,19 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) signed long old; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%1\n" "0: ltr %0,%0\n" " jnz 1f\n" " cs %0,%3,%1\n" " jl 0b\n" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%1\n" "0: ltgr %0,%0\n" " jnz 1f\n" " csg %0,%3,%1\n" " jl 0b\n" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ "1:" : "=&d" (old), "=Q" (sem->count) : "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS) @@ -184,19 +186,19 @@ static inline void __up_read(struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " ahi %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " aghi %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); @@ -214,19 +216,19 @@ static inline void __up_write(struct rw_semaphore *sem) tmp = -RWSEM_ACTIVE_WRITE_BIAS; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -244,19 +246,19 @@ static inline void __downgrade_write(struct rw_semaphore *sem) tmp = -RWSEM_WAITING_BIAS; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " a %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " ag %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "m" (tmp) : "cc", "memory"); @@ -272,19 +274,19 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " ar %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " agr %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "d" (delta) : "cc", "memory"); @@ -298,23 +300,24 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) signed long old, new; asm volatile( -#ifndef CONFIG_64BIT +#ifndef __s390x__ " l %0,%2\n" "0: lr %1,%0\n" " ar %1,%4\n" " cs %0,%1,%2\n" " jl 0b" -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ " lg %0,%2\n" "0: lgr %1,%0\n" " agr %1,%4\n" " csg %0,%1,%2\n" " jl 0b" -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ : "=&d" (old), "=&d" (new), "=Q" (sem->count) : "Q" (sem->count), "d" (delta) : "cc", "memory"); return new; } +#endif /* __KERNEL__ */ #endif /* _S390_RWSEM_H */ diff --git a/trunk/arch/s390/include/asm/setup.h b/trunk/arch/s390/include/asm/setup.h index 40eb2ff88e9e..7244e1f64126 100644 --- a/trunk/arch/s390/include/asm/setup.h +++ b/trunk/arch/s390/include/asm/setup.h @@ -22,19 +22,19 @@ #include #include -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define IPL_DEVICE (*(unsigned long *) (0x10404)) #define INITRD_START (*(unsigned long *) (0x1040C)) #define INITRD_SIZE (*(unsigned long *) (0x10414)) #define OLDMEM_BASE (*(unsigned long *) (0x1041C)) #define OLDMEM_SIZE (*(unsigned long *) (0x10424)) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define IPL_DEVICE (*(unsigned long *) (0x10400)) #define INITRD_START (*(unsigned long *) (0x10408)) #define INITRD_SIZE (*(unsigned long *) (0x10410)) #define OLDMEM_BASE (*(unsigned long *) (0x10418)) #define OLDMEM_SIZE (*(unsigned long *) (0x10420)) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define COMMAND_LINE ((char *) (0x10480)) #define CHUNK_READ_WRITE 0 @@ -89,7 +89,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C) -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define MACHINE_HAS_IEEE (S390_lowcore.machine_flags & MACHINE_FLAG_IEEE) #define MACHINE_HAS_CSP (S390_lowcore.machine_flags & MACHINE_FLAG_CSP) #define MACHINE_HAS_IDTE (0) @@ -100,7 +100,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (0) #define MACHINE_HAS_SPP (0) #define MACHINE_HAS_TOPOLOGY (0) -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define MACHINE_HAS_IEEE (1) #define MACHINE_HAS_CSP (1) #define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE) @@ -111,7 +111,7 @@ extern unsigned int user_mode; #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) #define MACHINE_HAS_TOPOLOGY (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY) -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define ZFCPDUMP_HSA_SIZE (32UL<<20) #define ZFCPDUMP_HSA_SIZE_MAX (64UL<<20) @@ -153,19 +153,19 @@ extern void (*_machine_power_off)(void); #else /* __ASSEMBLY__ */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define IPL_DEVICE 0x10404 #define INITRD_START 0x1040C #define INITRD_SIZE 0x10414 #define OLDMEM_BASE 0x1041C #define OLDMEM_SIZE 0x10424 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #define IPL_DEVICE 0x10400 #define INITRD_START 0x10408 #define INITRD_SIZE 0x10410 #define OLDMEM_BASE 0x10418 #define OLDMEM_SIZE 0x10420 -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define COMMAND_LINE 0x10480 #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/s390/include/asm/sfp-util.h b/trunk/arch/s390/include/asm/sfp-util.h index 5959bfb3b693..ca3f8814e361 100644 --- a/trunk/arch/s390/include/asm/sfp-util.h +++ b/trunk/arch/s390/include/asm/sfp-util.h @@ -51,7 +51,7 @@ wl = __wl; \ }) -#ifdef CONFIG_64BIT +#ifdef __s390x__ #define udiv_qrnnd(q, r, n1, n0, d) \ do { unsigned long __n; \ unsigned int __r, __d; \ diff --git a/trunk/arch/s390/include/asm/string.h b/trunk/arch/s390/include/asm/string.h index 8cc160c9e1cb..cd0241db5a46 100644 --- a/trunk/arch/s390/include/asm/string.h +++ b/trunk/arch/s390/include/asm/string.h @@ -9,6 +9,8 @@ #ifndef _S390_STRING_H_ #define _S390_STRING_H_ +#ifdef __KERNEL__ + #ifndef _LINUX_TYPES_H #include #endif @@ -150,4 +152,6 @@ size_t strlen(const char *s); size_t strnlen(const char * s, size_t n); #endif /* !IN_ARCH_STRING_C */ +#endif /* __KERNEL__ */ + #endif /* __S390_STRING_H_ */ diff --git a/trunk/arch/s390/include/asm/thread_info.h b/trunk/arch/s390/include/asm/thread_info.h index 4e40b25cd060..003b04edcff6 100644 --- a/trunk/arch/s390/include/asm/thread_info.h +++ b/trunk/arch/s390/include/asm/thread_info.h @@ -9,13 +9,15 @@ #ifndef _ASM_THREAD_INFO_H #define _ASM_THREAD_INFO_H +#ifdef __KERNEL__ + /* * Size of kernel stack for each process */ -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define THREAD_ORDER 1 #define ASYNC_ORDER 1 -#else /* CONFIG_64BIT */ +#else /* __s390x__ */ #ifndef __SMALL_STACK #define THREAD_ORDER 2 #define ASYNC_ORDER 2 @@ -23,7 +25,7 @@ #define THREAD_ORDER 1 #define ASYNC_ORDER 1 #endif -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define ASYNC_SIZE (PAGE_SIZE << ASYNC_ORDER) @@ -121,6 +123,8 @@ static inline struct thread_info *current_thread_info(void) #define is_32bit_task() (1) #endif +#endif /* __KERNEL__ */ + #define PREEMPT_ACTIVE 0x4000000 #endif /* _ASM_THREAD_INFO_H */ diff --git a/trunk/arch/s390/include/asm/timer.h b/trunk/arch/s390/include/asm/timer.h index 15d647901e5c..e63069ba39e3 100644 --- a/trunk/arch/s390/include/asm/timer.h +++ b/trunk/arch/s390/include/asm/timer.h @@ -10,6 +10,8 @@ #ifndef _ASM_S390_TIMER_H #define _ASM_S390_TIMER_H +#ifdef __KERNEL__ + #include #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) @@ -48,4 +50,6 @@ extern void vtime_init(void); extern void vtime_stop_cpu(void); extern void vtime_start_leave(void); +#endif /* __KERNEL__ */ + #endif /* _ASM_S390_TIMER_H */ diff --git a/trunk/arch/s390/include/asm/tlb.h b/trunk/arch/s390/include/asm/tlb.h index 06e5acbc84bd..775a5eea8f9e 100644 --- a/trunk/arch/s390/include/asm/tlb.h +++ b/trunk/arch/s390/include/asm/tlb.h @@ -106,7 +106,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, unsigned long address) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; if (!tlb->fullmm) @@ -125,7 +125,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, unsigned long address) { -#ifdef CONFIG_64BIT +#ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; if (!tlb->fullmm) diff --git a/trunk/arch/s390/include/asm/tlbflush.h b/trunk/arch/s390/include/asm/tlbflush.h index 9fde315f3a7c..1d8648cf2fea 100644 --- a/trunk/arch/s390/include/asm/tlbflush.h +++ b/trunk/arch/s390/include/asm/tlbflush.h @@ -27,12 +27,12 @@ static inline void __tlb_flush_global(void) register unsigned long reg4 asm("4"); long dummy; -#ifndef CONFIG_64BIT +#ifndef __s390x__ if (!MACHINE_HAS_CSP) { smp_ptlb_all(); return; } -#endif /* CONFIG_64BIT */ +#endif /* __s390x__ */ dummy = 0; reg2 = reg3 = 0; diff --git a/trunk/arch/s390/include/asm/types.h b/trunk/arch/s390/include/asm/types.h index 6c8c35f8df14..05ebbcdbbf6b 100644 --- a/trunk/arch/s390/include/asm/types.h +++ b/trunk/arch/s390/include/asm/types.h @@ -28,7 +28,7 @@ typedef __signed__ long saddr_t; #ifndef __ASSEMBLY__ -#ifndef CONFIG_64BIT +#ifndef __s390x__ typedef union { unsigned long long pair; struct { @@ -37,7 +37,7 @@ typedef union { } subreg; } register_pair; -#endif /* ! CONFIG_64BIT */ +#endif /* ! __s390x__ */ #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _S390_TYPES_H */ diff --git a/trunk/arch/s390/include/asm/uaccess.h b/trunk/arch/s390/include/asm/uaccess.h index 1f3a79bcd262..8f2cada4f7c9 100644 --- a/trunk/arch/s390/include/asm/uaccess.h +++ b/trunk/arch/s390/include/asm/uaccess.h @@ -50,15 +50,10 @@ #define segment_eq(a,b) ((a).ar4 == (b).ar4) -static inline int __range_ok(unsigned long addr, unsigned long size) -{ - return 1; -} - -#define __access_ok(addr, size) \ -({ \ - __chk_user_ptr(addr); \ - __range_ok((unsigned long)(addr), (size)); \ +#define __access_ok(addr, size) \ +({ \ + __chk_user_ptr(addr); \ + 1; \ }) #define access_ok(type, addr, size) __access_ok(addr, size) @@ -382,7 +377,7 @@ clear_user(void __user *to, unsigned long n) } extern int memcpy_real(void *, void *, size_t); -extern void memcpy_absolute(void *, void *, size_t); +extern void copy_to_absolute_zero(void *dest, void *src, size_t count); extern int copy_to_user_real(void __user *dest, void *src, size_t count); extern int copy_from_user_real(void *dest, void __user *src, size_t count); diff --git a/trunk/arch/s390/include/asm/vdso.h b/trunk/arch/s390/include/asm/vdso.h index a73eb2e1e918..c4a11cfad3c8 100644 --- a/trunk/arch/s390/include/asm/vdso.h +++ b/trunk/arch/s390/include/asm/vdso.h @@ -1,6 +1,8 @@ #ifndef __S390_VDSO_H__ #define __S390_VDSO_H__ +#ifdef __KERNEL__ + /* Default link addresses for the vDSOs */ #define VDSO32_LBASE 0 #define VDSO64_LBASE 0 @@ -43,4 +45,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore); #endif #endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + #endif /* __S390_VDSO_H__ */ diff --git a/trunk/arch/s390/kernel/base.S b/trunk/arch/s390/kernel/base.S index c880ff72db44..3aa4d00aaf50 100644 --- a/trunk/arch/s390/kernel/base.S +++ b/trunk/arch/s390/kernel/base.S @@ -88,9 +88,6 @@ ENTRY(diag308_reset) stctg %c0,%c15,0(%r4) larl %r4,.Lfpctl # Floating point control register stfpc 0(%r4) - larl %r4,.Lcontinue_psw # Save PSW flags - epsw %r2,%r3 - stm %r2,%r3,0(%r4) larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 lghi %r3,0 lg %r4,0(%r4) # Save PSW @@ -106,20 +103,11 @@ ENTRY(diag308_reset) lctlg %c0,%c15,0(%r4) larl %r4,.Lfpctl # Restore floating point ctl register lfpc 0(%r4) - larl %r4,.Lcontinue_psw # Restore PSW flags - lpswe 0(%r4) -.Lcontinue: br %r14 .align 16 .Lrestart_psw: .long 0x00080000,0x80000000 + .Lrestart_part2 - .section .data..nosave,"aw",@progbits -.align 8 -.Lcontinue_psw: - .quad 0,.Lcontinue - .previous - .section .bss .align 8 .Lctlregs: diff --git a/trunk/arch/s390/kernel/early.c b/trunk/arch/s390/kernel/early.c index 6684fff17558..d84181f1f5e8 100644 --- a/trunk/arch/s390/kernel/early.c +++ b/trunk/arch/s390/kernel/early.c @@ -237,7 +237,7 @@ static noinline __init void detect_machine_type(void) S390_lowcore.machine_flags |= MACHINE_FLAG_VM; } -static void early_pgm_check_handler(void) +static __init void early_pgm_check_handler(void) { unsigned long addr; const struct exception_table_entry *fixup; diff --git a/trunk/arch/s390/kernel/head_kdump.S b/trunk/arch/s390/kernel/head_kdump.S index 796c976b5fdc..e1ac3893e972 100644 --- a/trunk/arch/s390/kernel/head_kdump.S +++ b/trunk/arch/s390/kernel/head_kdump.S @@ -85,6 +85,11 @@ startup_kdump_relocated: basr %r13,0 0: mvc 0(8,%r0),.Lrestart_psw-0b(%r13) # Setup restart PSW + mvc 464(16,%r0),.Lpgm_psw-0b(%r13) # Setup pgm check PSW + lhi %r1,1 # Start new kernel + diag %r1,%r1,0x308 # with diag 308 + +.Lno_diag308: # No diag 308 sam31 # Switch to 31 bit addr mode sr %r1,%r1 # Erase register r1 sr %r2,%r2 # Erase register r2 @@ -93,6 +98,8 @@ startup_kdump_relocated: .align 8 .Lrestart_psw: .long 0x00080000,0x80000000 + startup +.Lpgm_psw: + .quad 0x0000000180000000,0x0000000000000000 + .Lno_diag308 #else .align 2 .Lep_startup_kdump: diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 2f6cfd460cb6..8342e65a140d 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -1528,15 +1528,12 @@ static struct shutdown_action __refdata dump_action = { static void dump_reipl_run(struct shutdown_trigger *trigger) { - struct { - void *addr; - __u32 csum; - } __packed ipib; - - ipib.csum = csum_partial(reipl_block_actual, - reipl_block_actual->hdr.len, 0); - ipib.addr = reipl_block_actual; - memcpy_absolute(&S390_lowcore.ipib, &ipib, sizeof(ipib)); + u32 csum; + + csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); + copy_to_absolute_zero(&S390_lowcore.ipib_checksum, &csum, sizeof(csum)); + copy_to_absolute_zero(&S390_lowcore.ipib, &reipl_block_actual, + sizeof(reipl_block_actual)); dump_run(trigger); } @@ -1753,7 +1750,6 @@ static struct kobj_attribute on_restart_attr = static void __do_restart(void *ignore) { - __arch_local_irq_stosm(0x04); /* enable DAT */ smp_send_stop(); #ifdef CONFIG_CRASH_DUMP crash_kexec(NULL); diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index b4f4a7133fa1..8a22c27219dd 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -42,8 +42,7 @@ static const struct irq_class intrclass_names[] = { {.name = "VRT", .desc = "[EXT] Virtio" }, {.name = "SCP", .desc = "[EXT] Service Call" }, {.name = "IUC", .desc = "[EXT] IUCV" }, - {.name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling" }, - {.name = "CMC", .desc = "[EXT] CPU-Measurement: Counter" }, + {.name = "CPM", .desc = "[EXT] CPU Measurement" }, {.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt" }, {.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" }, {.name = "DAS", .desc = "[I/O] DASD" }, diff --git a/trunk/arch/s390/kernel/machine_kexec.c b/trunk/arch/s390/kernel/machine_kexec.c index cdacf8f91b2d..bdad47d54478 100644 --- a/trunk/arch/s390/kernel/machine_kexec.c +++ b/trunk/arch/s390/kernel/machine_kexec.c @@ -24,7 +24,6 @@ #include #include #include -#include typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); @@ -80,8 +79,8 @@ static void __do_machine_kdump(void *image) #ifdef CONFIG_CRASH_DUMP int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; - setup_regs(); __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); + setup_regs(); start_kdump(1); #endif } @@ -115,13 +114,8 @@ static void crash_map_pages(int enable) size % KEXEC_CRASH_MEM_ALIGN); if (enable) vmem_add_mapping(crashk_res.start, size); - else { + else vmem_remove_mapping(crashk_res.start, size); - if (size) - os_info_crashkernel_add(crashk_res.start, size); - else - os_info_crashkernel_add(0, 0); - } } /* @@ -214,7 +208,6 @@ static void __machine_kexec(void *data) { struct kimage *image = data; - __arch_local_irq_stosm(0x04); /* enable DAT */ pfault_fini(); tracing_off(); debug_locks_off(); diff --git a/trunk/arch/s390/kernel/os_info.c b/trunk/arch/s390/kernel/os_info.c index 95fa5ac6c4ce..e8d6c214d498 100644 --- a/trunk/arch/s390/kernel/os_info.c +++ b/trunk/arch/s390/kernel/os_info.c @@ -60,7 +60,7 @@ void __init os_info_init(void) os_info.version_minor = OS_INFO_VERSION_MINOR; os_info.magic = OS_INFO_MAGIC; os_info.csum = os_info_csum(&os_info); - memcpy_absolute(&S390_lowcore.os_info, &ptr, sizeof(ptr)); + copy_to_absolute_zero(&S390_lowcore.os_info, &ptr, sizeof(ptr)); } #ifdef CONFIG_CRASH_DUMP @@ -138,6 +138,7 @@ static void os_info_old_init(void) goto fail_free; os_info_old_alloc(OS_INFO_VMCOREINFO, 1); os_info_old_alloc(OS_INFO_REIPL_BLOCK, 1); + os_info_old_alloc(OS_INFO_INIT_FN, PAGE_SIZE); pr_info("crashkernel: addr=0x%lx size=%lu\n", (unsigned long) os_info_old->crashkernel_addr, (unsigned long) os_info_old->crashkernel_size); diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index 9871b1971ed7..cb019f429e88 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -225,7 +225,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, if (!(alert & CPU_MF_INT_CF_MASK)) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_CMC]++; + kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; cpuhw = &__get_cpu_var(cpu_hw_events); /* Measurement alerts are shared and might happen when the PMU diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 489d1d8d96b0..06264ae8ccd9 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -428,12 +428,10 @@ static void __init setup_lowcore(void) lc->restart_fn = (unsigned long) do_restart; lc->restart_data = 0; lc->restart_source = -1UL; - - /* Setup absolute zero lowcore */ - memcpy_absolute(&S390_lowcore.restart_stack, &lc->restart_stack, - 4 * sizeof(unsigned long)); - memcpy_absolute(&S390_lowcore.restart_psw, &lc->restart_psw, - sizeof(lc->restart_psw)); + memcpy(&S390_lowcore.restart_stack, &lc->restart_stack, + 4*sizeof(unsigned long)); + copy_to_absolute_zero(&S390_lowcore.restart_psw, + &lc->restart_psw, sizeof(psw_t)); set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; @@ -600,7 +598,7 @@ static void __init setup_vmcoreinfo(void) #ifdef CONFIG_KEXEC unsigned long ptr = paddr_vmcoreinfo_note(); - memcpy_absolute(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); + copy_to_absolute_zero(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); #endif } diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 15cca26ccb6c..647ba9425893 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -297,27 +297,26 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), void *data, unsigned long stack) { - struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; - struct { - unsigned long stack; - void *func; - void *data; - unsigned long source; - } restart = { stack, func, data, stap() }; + struct _lowcore *lc = pcpu->lowcore; + unsigned short this_cpu; __load_psw_mask(psw_kernel_bits); - if (pcpu->address == restart.source) + this_cpu = stap(); + if (pcpu->address == this_cpu) func(data); /* should not return */ /* Stop target cpu (if func returns this stops the current cpu). */ pcpu_sigp_retry(pcpu, sigp_stop, 0); /* Restart func on the target cpu and stop the current cpu. */ - memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); + lc->restart_stack = stack; + lc->restart_fn = (unsigned long) func; + lc->restart_data = (unsigned long) data; + lc->restart_source = (unsigned long) this_cpu; asm volatile( "0: sigp 0,%0,6 # sigp restart to target cpu\n" " brc 2,0b # busy, try again\n" "1: sigp 0,%1,5 # sigp stop to current cpu\n" " brc 2,1b # busy, try again\n" - : : "d" (pcpu->address), "d" (restart.source) : "0", "1", "cc"); + : : "d" (pcpu->address), "d" (this_cpu) : "0", "1", "cc"); for (;;) ; } @@ -801,6 +800,17 @@ void __noreturn cpu_die(void) #endif /* CONFIG_HOTPLUG_CPU */ +static void smp_call_os_info_init_fn(void) +{ + int (*init_fn)(void); + unsigned long size; + + init_fn = os_info_old_entry(OS_INFO_INIT_FN, &size); + if (!init_fn) + return; + init_fn(); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { /* request the 0x1201 emergency signal external interrupt */ @@ -809,6 +819,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* request the 0x1202 external call external interrupt */ if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0) panic("Couldn't request external interrupt 0x1202"); + smp_call_os_info_init_fn(); smp_detect_cpus(); } @@ -932,6 +943,19 @@ static struct attribute_group cpu_common_attr_group = { .attrs = cpu_common_attrs, }; +static ssize_t show_capability(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int capability; + int rc; + + rc = get_cpu_capability(&capability); + if (rc) + return rc; + return sprintf(buf, "%u\n", capability); +} +static DEVICE_ATTR(capability, 0444, show_capability, NULL); + static ssize_t show_idle_count(struct device *dev, struct device_attribute *attr, char *buf) { @@ -969,6 +993,7 @@ static ssize_t show_idle_time(struct device *dev, static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); static struct attribute *cpu_online_attrs[] = { + &dev_attr_capability.attr, &dev_attr_idle_count.attr, &dev_attr_idle_time_us.attr, NULL, diff --git a/trunk/arch/s390/kernel/sysinfo.c b/trunk/arch/s390/kernel/sysinfo.c index fa0eb238dac7..2a94b774695c 100644 --- a/trunk/arch/s390/kernel/sysinfo.c +++ b/trunk/arch/s390/kernel/sysinfo.c @@ -392,6 +392,27 @@ static __init int create_proc_service_level(void) } subsys_initcall(create_proc_service_level); +/* + * Bogomips calculation based on cpu capability. + */ +int get_cpu_capability(unsigned int *capability) +{ + struct sysinfo_1_2_2 *info; + int rc; + + info = (void *) get_zeroed_page(GFP_KERNEL); + if (!info) + return -ENOMEM; + rc = stsi(info, 1, 2, 2); + if (rc == -ENOSYS) + goto out; + rc = 0; + *capability = info->capability; +out: + free_page((unsigned long) info); + return rc; +} + /* * CPU capability might have changed. Therefore recalculate loops_per_jiffy. */ diff --git a/trunk/arch/s390/lib/uaccess_mvcos.c b/trunk/arch/s390/lib/uaccess_mvcos.c index 58a75a8ae90c..60455f104ea3 100644 --- a/trunk/arch/s390/lib/uaccess_mvcos.c +++ b/trunk/arch/s390/lib/uaccess_mvcos.c @@ -14,7 +14,7 @@ #include #include "uaccess.h" -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define AHI "ahi" #define ALR "alr" #define CLR "clr" diff --git a/trunk/arch/s390/lib/uaccess_std.c b/trunk/arch/s390/lib/uaccess_std.c index 57e94298539b..bb1a7eed42ce 100644 --- a/trunk/arch/s390/lib/uaccess_std.c +++ b/trunk/arch/s390/lib/uaccess_std.c @@ -15,7 +15,7 @@ #include #include "uaccess.h" -#ifndef CONFIG_64BIT +#ifndef __s390x__ #define AHI "ahi" #define ALR "alr" #define CLR "clr" diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index 921fa541dc04..795a0a9bb2eb 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -101,27 +101,19 @@ int memcpy_real(void *dest, void *src, size_t count) } /* - * Copy memory in absolute mode (kernel to kernel) + * Copy memory to absolute zero */ -void memcpy_absolute(void *dest, void *src, size_t count) +void copy_to_absolute_zero(void *dest, void *src, size_t count) { - unsigned long cr0, flags, prefix; + unsigned long cr0; - flags = arch_local_irq_save(); + BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore)); + preempt_disable(); __ctl_store(cr0, 0, 0); __ctl_clear_bit(0, 28); /* disable lowcore protection */ - prefix = store_prefix(); - if (prefix) { - local_mcck_disable(); - set_prefix(0); - memcpy(dest, src, count); - set_prefix(prefix); - local_mcck_enable(); - } else { - memcpy(dest, src, count); - } + memcpy_real(dest + store_prefix(), src, count); __ctl_load(cr0, 0, 0); - arch_local_irq_restore(flags); + preempt_enable(); } /* @@ -195,6 +187,20 @@ static int is_swapped(unsigned long addr) return 0; } +/* + * Return swapped prefix or zero page address + */ +static unsigned long get_swapped(unsigned long addr) +{ + unsigned long prefix = store_prefix(); + + if (addr < sizeof(struct _lowcore)) + return addr + prefix; + if (addr >= prefix && addr < prefix + sizeof(struct _lowcore)) + return addr - prefix; + return addr; +} + /* * Convert a physical pointer for /dev/mem access * @@ -212,7 +218,7 @@ void *xlate_dev_mem_ptr(unsigned long addr) size = PAGE_SIZE - (addr & ~PAGE_MASK); bounce = (void *) __get_free_page(GFP_ATOMIC); if (bounce) - memcpy_absolute(bounce, (void *) addr, size); + memcpy_real(bounce, (void *) get_swapped(addr), size); } preempt_enable(); put_online_cpus(); diff --git a/trunk/arch/s390/mm/vmem.c b/trunk/arch/s390/mm/vmem.c index 71ae20df674e..4799383e2df9 100644 --- a/trunk/arch/s390/mm/vmem.c +++ b/trunk/arch/s390/mm/vmem.c @@ -109,7 +109,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pm_dir = pmd_offset(pu_dir, address); -#ifdef CONFIG_64BIT +#ifdef __s390x__ if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && (address + HPAGE_SIZE <= start + size) && (address >= HPAGE_SIZE)) { diff --git a/trunk/arch/s390/oprofile/hwsampler.c b/trunk/arch/s390/oprofile/hwsampler.c index a4a89fa980d6..c6646de07bf4 100644 --- a/trunk/arch/s390/oprofile/hwsampler.c +++ b/trunk/arch/s390/oprofile/hwsampler.c @@ -235,7 +235,7 @@ static void hws_ext_handler(struct ext_code ext_code, if (!(param32 & CPU_MF_INT_SF_MASK)) return; - kstat_cpu(smp_processor_id()).irqs[EXTINT_CMS]++; + kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++; atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); if (hws_wq) diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index e74ff1377626..83bd051754e1 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -41,6 +41,7 @@ config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 select CLZ_TAB + select ARCH_USES_GETTIMEOFFSET config SPARC64 def_bool 64BIT diff --git a/trunk/arch/sparc/include/asm/asi.h b/trunk/arch/sparc/include/asm/asi.h index 61ebe7411ceb..cbb93e5141de 100644 --- a/trunk/arch/sparc/include/asm/asi.h +++ b/trunk/arch/sparc/include/asm/asi.h @@ -40,7 +40,11 @@ #define ASI_M_UNA01 0x01 /* Same here... */ #define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ #define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ +#ifndef CONFIG_SPARC_LEON #define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ +#else +#define ASI_M_MMUREGS 0x19 +#endif /* CONFIG_SPARC_LEON */ #define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ #define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ #define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ diff --git a/trunk/arch/sparc/include/asm/asmmacro.h b/trunk/arch/sparc/include/asm/asmmacro.h index a0e28ef02558..02a172fb193a 100644 --- a/trunk/arch/sparc/include/asm/asmmacro.h +++ b/trunk/arch/sparc/include/asm/asmmacro.h @@ -20,26 +20,4 @@ /* All traps low-level code here must end with this macro. */ #define RESTORE_ALL b ret_trap_entry; clr %l6; -/* Support for run-time patching of single instructions. - * This is used to handle the differences in the ASI for - * MMUREGS for LEON and SUN. - * - * Sample: - * LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0 - * SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0 - * PI == Patch Instruction - * - * For LEON we will use the first variant, - * and for all other we will use the SUN variant. - * The order is important. - */ -#define LEON_PI(...) \ -662: __VA_ARGS__ - -#define SUN_PI_(...) \ - .section .leon_1insn_patch, "ax"; \ - .word 662b; \ - __VA_ARGS__; \ - .previous - #endif /* !(_SPARC_ASMMACRO_H) */ diff --git a/trunk/arch/sparc/include/asm/dma-mapping.h b/trunk/arch/sparc/include/asm/dma-mapping.h index 8493fd3c7ba5..48a7c65731d2 100644 --- a/trunk/arch/sparc/include/asm/dma-mapping.h +++ b/trunk/arch/sparc/include/asm/dma-mapping.h @@ -12,18 +12,13 @@ extern int dma_supported(struct device *dev, u64 mask); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -extern struct dma_map_ops *dma_ops; -extern struct dma_map_ops *leon_dma_ops; -extern struct dma_map_ops pci32_dma_ops; - +extern struct dma_map_ops *dma_ops, pci32_dma_ops; extern struct bus_type pci_bus_type; static inline struct dma_map_ops *get_dma_ops(struct device *dev) { #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI) - if (sparc_cpu_model == sparc_leon) - return leon_dma_ops; - else if (dev->bus == &pci_bus_type) + if (dev->bus == &pci_bus_type) return &pci32_dma_ops; #endif return dma_ops; diff --git a/trunk/arch/sparc/include/asm/leon.h b/trunk/arch/sparc/include/asm/leon.h index 3375c6293893..07659124c140 100644 --- a/trunk/arch/sparc/include/asm/leon.h +++ b/trunk/arch/sparc/include/asm/leon.h @@ -8,6 +8,8 @@ #ifndef LEON_H_INCLUDE #define LEON_H_INCLUDE +#ifdef CONFIG_SPARC_LEON + /* mmu register access, ASI_LEON_MMUREGS */ #define LEON_CNR_CTRL 0x000 #define LEON_CNR_CTXP 0x100 @@ -60,6 +62,15 @@ #ifndef __ASSEMBLY__ +/* do a virtual address read without cache */ +static inline unsigned long leon_readnobuffer_reg(unsigned long paddr) +{ + unsigned long retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE)); + return retval; +} + /* do a physical address bypass write, i.e. for 0x80000000 */ static inline void leon_store_reg(unsigned long paddr, unsigned long value) { @@ -76,16 +87,47 @@ static inline unsigned long leon_load_reg(unsigned long paddr) return retval; } +static inline void leon_srmmu_disabletlb(void) +{ + unsigned int retval; + __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), + "i"(ASI_LEON_MMUREGS)); + retval |= LEON_CNR_CTRL_TLBDIS; + __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), + "i"(ASI_LEON_MMUREGS) : "memory"); +} + +static inline void leon_srmmu_enabletlb(void) +{ + unsigned int retval; + __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), + "i"(ASI_LEON_MMUREGS)); + retval = retval & ~LEON_CNR_CTRL_TLBDIS; + __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), + "i"(ASI_LEON_MMUREGS) : "memory"); +} + /* macro access for leon_load_reg() and leon_store_reg() */ #define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x))) #define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v))) +#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v) +#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v) #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) +#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS) +#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v)) +#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v)) +#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v)) + +/* macro access for leon_readnobuffer_reg() */ +#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x)) extern void leon_init(void); extern void leon_switch_mm(void); extern void leon_init_IRQ(void); +extern unsigned long last_valid_pfn; + static inline unsigned long sparc_leon3_get_dcachecfg(void) { unsigned int retval; @@ -188,6 +230,9 @@ static inline int sparc_leon3_cpuid(void) #error cannot determine LEON_PAGE_SIZE_LEON #endif +#define PAGE_MIN_SHIFT (12) +#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT) + #define LEON3_XCCR_SETS_MASK 0x07000000UL #define LEON3_XCCR_SSIZE_MASK 0x00f00000UL @@ -197,7 +242,7 @@ static inline int sparc_leon3_cpuid(void) #ifndef __ASSEMBLY__ struct vm_area_struct; -extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr); +extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); extern void leon_flush_icache_all(void); extern void leon_flush_dcache_all(void); extern void leon_flush_cache_all(void); @@ -213,7 +258,15 @@ struct leon3_cacheregs { unsigned long dccr; /* 0x0c - Data Cache Configuration Register */ }; -#include +/* struct that hold LEON2 cache configuration register + * & configuration register + */ +struct leon2_cacheregs { + unsigned long ccr, cfg; +}; + +#ifdef __KERNEL__ + #include struct device_node; @@ -239,15 +292,24 @@ extern void leon_smp_done(void); extern void leon_boot_cpus(void); extern int leon_boot_one_cpu(int i, struct task_struct *); void leon_init_smp(void); +extern void cpu_idle(void); +extern void init_IRQ(void); +extern void cpu_panic(void); +extern int __leon_processor_id(void); void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu); extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused); +extern unsigned int real_irq_entry[]; extern unsigned int smpleon_ipi[]; -extern unsigned int linux_trap_ipi15_leon[]; +extern unsigned int patchme_maybe_smp_msg[]; +extern unsigned int t_nmi[], linux_trap_ipi15_leon[]; +extern unsigned int linux_trap_ipi15_sun4m[]; extern int leon_ipi_irq; #endif /* CONFIG_SMP */ +#endif /* __KERNEL__ */ + #endif /* __ASSEMBLY__ */ /* macros used in leon_mm.c */ @@ -255,4 +317,18 @@ extern int leon_ipi_irq; #define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base))) #define _SRMMU_PTE_PMASK_LEON 0xffffffff +#else /* defined(CONFIG_SPARC_LEON) */ + +/* nop definitions for !LEON case */ +#define leon_init() do {} while (0) +#define leon_switch_mm() do {} while (0) +#define leon_init_IRQ() do {} while (0) +#define init_leon() do {} while (0) +#define leon_smp_done() do {} while (0) +#define leon_boot_cpus() do {} while (0) +#define leon_boot_one_cpu(i, t) 1 +#define leon_init_smp() do {} while (0) + +#endif /* !defined(CONFIG_SPARC_LEON) */ + #endif diff --git a/trunk/arch/sparc/include/asm/leon_amba.h b/trunk/arch/sparc/include/asm/leon_amba.h index f3034eddf468..e50f326e71bd 100644 --- a/trunk/arch/sparc/include/asm/leon_amba.h +++ b/trunk/arch/sparc/include/asm/leon_amba.h @@ -87,6 +87,8 @@ struct amba_prom_registers { #define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7) #define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0) +#ifdef CONFIG_SPARC_LEON + #ifndef __ASSEMBLY__ struct leon3_irqctrl_regs_map { @@ -262,4 +264,6 @@ extern unsigned int sparc_leon_eirq; #define amba_device(x) (((x) >> 12) & 0xfff) +#endif /* !defined(CONFIG_SPARC_LEON) */ + #endif diff --git a/trunk/arch/sparc/include/asm/pgtsrmmu.h b/trunk/arch/sparc/include/asm/pgtsrmmu.h index 79da17866fa8..cb828703a63a 100644 --- a/trunk/arch/sparc/include/asm/pgtsrmmu.h +++ b/trunk/arch/sparc/include/asm/pgtsrmmu.h @@ -139,7 +139,6 @@ restore %g0, %g0, %g0; #ifndef __ASSEMBLY__ -extern unsigned long last_valid_pfn; /* This makes sense. Honest it does - Anton */ /* XXX Yes but it's ugly as sin. FIXME. -KMW */ @@ -149,13 +148,67 @@ extern void *srmmu_nocache_pool; #define __nocache_fix(VADDR) __va(__nocache_pa(VADDR)) /* Accessing the MMU control register. */ -unsigned int srmmu_get_mmureg(void); -void srmmu_set_mmureg(unsigned long regval); -void srmmu_set_ctable_ptr(unsigned long paddr); -void srmmu_set_context(int context); -int srmmu_get_context(void); -unsigned int srmmu_get_fstatus(void); -unsigned int srmmu_get_faddr(void); +static inline unsigned int srmmu_get_mmureg(void) +{ + unsigned int retval; + __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : + "=r" (retval) : + "i" (ASI_M_MMUREGS)); + return retval; +} + +static inline void srmmu_set_mmureg(unsigned long regval) +{ + __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : + "r" (regval), "i" (ASI_M_MMUREGS) : "memory"); + +} + +static inline void srmmu_set_ctable_ptr(unsigned long paddr) +{ + paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (paddr), "r" (SRMMU_CTXTBL_PTR), + "i" (ASI_M_MMUREGS) : + "memory"); +} + +static inline void srmmu_set_context(int context) +{ + __asm__ __volatile__("sta %0, [%1] %2\n\t" : : + "r" (context), "r" (SRMMU_CTX_REG), + "i" (ASI_M_MMUREGS) : "memory"); +} + +static inline int srmmu_get_context(void) +{ + register int retval; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_CTX_REG), + "i" (ASI_M_MMUREGS)); + return retval; +} + +static inline unsigned int srmmu_get_fstatus(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS)); + return retval; +} + +static inline unsigned int srmmu_get_faddr(void) +{ + unsigned int retval; + + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS)); + return retval; +} /* This is guaranteed on all SRMMU's. */ static inline void srmmu_flush_whole_tlb(void) @@ -166,6 +219,23 @@ static inline void srmmu_flush_whole_tlb(void) } +/* These flush types are not available on all chips... */ +#ifndef CONFIG_SPARC_LEON +static inline unsigned long srmmu_hwprobe(unsigned long vaddr) +{ + unsigned long retval; + + vaddr &= PAGE_MASK; + __asm__ __volatile__("lda [%1] %2, %0\n\t" : + "=r" (retval) : + "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); + + return retval; +} +#else +#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0) +#endif + static inline int srmmu_get_pte (unsigned long addr) { diff --git a/trunk/arch/sparc/include/asm/psr.h b/trunk/arch/sparc/include/asm/psr.h index cee7ed9c927d..b8c0e5f0a66b 100644 --- a/trunk/arch/sparc/include/asm/psr.h +++ b/trunk/arch/sparc/include/asm/psr.h @@ -35,14 +35,6 @@ #define PSR_VERS 0x0f000000 /* cpu-version field */ #define PSR_IMPL 0xf0000000 /* cpu-implementation field */ -#define PSR_VERS_SHIFT 24 -#define PSR_IMPL_SHIFT 28 -#define PSR_VERS_SHIFTED_MASK 0xf -#define PSR_IMPL_SHIFTED_MASK 0xf - -#define PSR_IMPL_TI 0x4 -#define PSR_IMPL_LEON 0xf - #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/trunk/arch/sparc/include/asm/sections.h b/trunk/arch/sparc/include/asm/sections.h index f300d1a9b2b6..0b0553bbd8a0 100644 --- a/trunk/arch/sparc/include/asm/sections.h +++ b/trunk/arch/sparc/include/asm/sections.h @@ -7,7 +7,4 @@ /* sparc entry point */ extern char _start[]; -extern char __leon_1insn_patch[]; -extern char __leon_1insn_patch_end[]; - #endif diff --git a/trunk/arch/sparc/kernel/Makefile b/trunk/arch/sparc/kernel/Makefile index 6cf591b7e1c6..72308f9b0096 100644 --- a/trunk/arch/sparc/kernel/Makefile +++ b/trunk/arch/sparc/kernel/Makefile @@ -51,8 +51,8 @@ obj-y += of_device_common.o obj-y += of_device_$(BITS).o obj-$(CONFIG_SPARC64) += prom_irqtrans.o -obj-$(CONFIG_SPARC32) += leon_kernel.o -obj-$(CONFIG_SPARC32) += leon_pmc.o +obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o +obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o obj-$(CONFIG_SPARC64) += reboot.o obj-$(CONFIG_SPARC64) += sysfs.o diff --git a/trunk/arch/sparc/kernel/cpu.c b/trunk/arch/sparc/kernel/cpu.c index a6c94a2bf9d4..2d1819641769 100644 --- a/trunk/arch/sparc/kernel/cpu.c +++ b/trunk/arch/sparc/kernel/cpu.c @@ -121,7 +121,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { FPU(-1, NULL) } },{ - PSR_IMPL_TI, + 4, .cpu_info = { CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), /* SparcClassic -- borned STP1010TAB-50*/ @@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { FPU(-1, NULL) } },{ - PSR_IMPL_LEON, /* Aeroflex Gaisler */ + 0xF, /* Aeroflex Gaisler */ .cpu_info = { CPU(3, "LEON"), CPU(-1, NULL) @@ -440,16 +440,16 @@ static int __init cpu_type_probe(void) int psr_impl, psr_vers, fpu_vers; int psr; - psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK); - psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK); + psr_impl = ((get_psr() >> 28) & 0xf); + psr_vers = ((get_psr() >> 24) & 0xf); psr = get_psr(); put_psr(psr | PSR_EF); - - if (psr_impl == PSR_IMPL_LEON) - fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; - else - fpu_vers = ((get_fsr() >> 17) & 0x7); +#ifdef CONFIG_SPARC_LEON + fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; +#else + fpu_vers = ((get_fsr() >> 17) & 0x7); +#endif put_psr(psr); diff --git a/trunk/arch/sparc/kernel/entry.S b/trunk/arch/sparc/kernel/entry.S index dcaa1cf0de40..2dbe1806e530 100644 --- a/trunk/arch/sparc/kernel/entry.S +++ b/trunk/arch/sparc/kernel/entry.S @@ -393,6 +393,7 @@ linux_trap_ipi15_sun4d: /* FIXME */ 1: b,a 1b +#ifdef CONFIG_SPARC_LEON .globl smpleon_ipi .extern leon_ipi_interrupt /* SMP per-cpu IPI interrupts are handled specially. */ @@ -423,6 +424,8 @@ linux_trap_ipi15_leon: b ret_trap_lockless_ipi clr %l6 +#endif /* CONFIG_SPARC_LEON */ + #endif /* CONFIG_SMP */ /* This routine handles illegal instructions and privileged @@ -767,11 +770,8 @@ srmmu_fault: mov 0x400, %l5 mov 0x300, %l4 -LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first -SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first - -LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last -SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last + lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first + lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last andn %l6, 0xfff, %l6 srl %l5, 6, %l5 ! and encode all info into l7 diff --git a/trunk/arch/sparc/kernel/etrap_32.S b/trunk/arch/sparc/kernel/etrap_32.S index e3e80d65e39a..84b5f0d2afde 100644 --- a/trunk/arch/sparc/kernel/etrap_32.S +++ b/trunk/arch/sparc/kernel/etrap_32.S @@ -234,8 +234,7 @@ tsetup_srmmu_stackchk: cmp %glob_tmp, %sp bleu,a 1f -LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control -SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control + lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control trap_setup_user_stack_is_bolixed: /* From user/kernel into invalid window w/bad user @@ -250,25 +249,18 @@ trap_setup_user_stack_is_bolixed: 1: /* Clear the fault status and turn on the no_fault bit. */ or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit -LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it -SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it + sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp -LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) -SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) - + sta %glob_tmp, [%g0] ASI_M_MMUREGS mov AC_M_SFAR, %glob_tmp -LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) -SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) - + lda [%glob_tmp] ASI_M_MMUREGS, %g0 mov AC_M_SFSR, %glob_tmp -LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore -SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore - + lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore andcc %glob_tmp, 0x2, %g0 ! did we fault? bne trap_setup_user_stack_is_bolixed ! failure nop diff --git a/trunk/arch/sparc/kernel/head_32.S b/trunk/arch/sparc/kernel/head_32.S index afeb1d770303..a0f5c20e4b9c 100644 --- a/trunk/arch/sparc/kernel/head_32.S +++ b/trunk/arch/sparc/kernel/head_32.S @@ -30,6 +30,10 @@ * the cpu-type */ .align 4 +cputyp: + .word 1 + + .align 4 .globl cputypval cputypval: .asciz "sun4m" @@ -42,8 +46,8 @@ cputypvar: .align 4 -notsup: - .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n" +sun4c_notsup: + .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" .align 4 sun4e_notsup: @@ -119,7 +123,7 @@ current_pc: tst %o0 be no_sun4u_here mov %g4, %o7 /* Previous %o7. */ - + mov %o0, %l0 ! stash away romvec mov %o0, %g7 ! put it here too mov %o1, %l1 ! stash away debug_vec too @@ -128,7 +132,7 @@ current_pc: set current_pc, %g5 cmp %g3, %g5 be already_mapped - nop + nop /* %l6 will hold the offset we have to subtract * from absolute symbols in order to access areas @@ -188,9 +192,9 @@ copy_prom_done: bne not_a_sun4 nop -halt_notsup: +halt_sun4_or_sun4c: ld [%g7 + 0x68], %o1 - set notsup, %o0 + set sun4c_notsup, %o0 sub %o0, %l6, %o0 call %o1 nop @@ -198,31 +202,18 @@ halt_notsup: nop not_a_sun4: - /* It looks like this is a machine we support. - * Now find out what MMU we are dealing with - * LEON - identified by the psr.impl field - * Viking - identified by the psr.impl field - * In all other cases a sun4m srmmu. - * We check that the MMU is enabled in all cases. - */ - - /* Check if this is a LEON CPU */ - rd %psr, %g3 - srl %g3, PSR_IMPL_SHIFT, %g3 - and %g3, PSR_IMPL_SHIFTED_MASK, %g3 - cmp %g3, PSR_IMPL_LEON - be leon_remap /* It is a LEON - jump */ - nop - - /* Sanity-check, is MMU enabled */ lda [%g0] ASI_M_MMUREGS, %g1 andcc %g1, 1, %g0 - be halt_notsup + be halt_sun4_or_sun4c nop - /* Check for a viking (TI) module. */ - cmp %g3, PSR_IMPL_TI - bne srmmu_not_viking +srmmu_remap: + /* First, check for a viking (TI) module. */ + set 0x40000000, %g2 + rd %psr, %g3 + and %g2, %g3, %g3 + subcc %g3, 0x0, %g0 + bz srmmu_nviking nop /* Figure out what kind of viking we are on. @@ -237,14 +228,14 @@ not_a_sun4: lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg and %g2, %g3, %g3 subcc %g3, 0x0, %g0 - bnz srmmu_not_viking ! is in mbus mode + bnz srmmu_nviking ! is in mbus mode nop - + rd %psr, %g3 ! DO NOT TOUCH %g3 andn %g3, PSR_ET, %g2 wr %g2, 0x0, %psr WRITE_PAUSE - + /* Get context table pointer, then convert to * a physical address, which is 36 bits. */ @@ -267,12 +258,12 @@ not_a_sun4: lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr srl %o1, 0x4, %o1 ! Clear low 4 bits sll %o1, 0x8, %o1 ! Make physical - + /* Ok, pull in the PTD. */ lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd /* Calculate to KERNBASE entry. */ - add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 + add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 /* Poke the entry into the calculated address. */ sta %o2, [%o3] ASI_M_BYPASS @@ -302,12 +293,12 @@ not_a_sun4: b go_to_highmem nop -srmmu_not_viking: /* This works on viking's in Mbus mode and all * other MBUS modules. It is virtually the same as * the above madness sans turning traps off and flipping * the AC bit. */ +srmmu_nviking: set AC_M_CTPR, %g1 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr sll %g1, 0x4, %g1 ! make physical addr @@ -322,29 +313,6 @@ srmmu_not_viking: nop ! wheee.... -leon_remap: - /* Sanity-check, is MMU enabled */ - lda [%g0] ASI_LEON_MMUREGS, %g1 - andcc %g1, 1, %g0 - be halt_notsup - nop - - /* Same code as in the srmmu_not_viking case, - * with the LEON ASI for mmuregs - */ - set AC_M_CTPR, %g1 - lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr - sll %g1, 0x4, %g1 ! make physical addr - lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table - srl %g1, 0x4, %g1 - sll %g1, 0x8, %g1 ! make phys addr for l1 tbl - - lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0 - add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3 - sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry - b go_to_highmem - nop ! wheee.... - /* Now do a non-relative jump so that PC is in high-memory */ go_to_highmem: set execute_in_high_mem, %g1 @@ -368,9 +336,8 @@ execute_in_high_mem: sethi %hi(linux_dbvec), %g1 st %o1, [%g1 + %lo(linux_dbvec)] - /* Get the machine type via the romvec - * getprops node operation - */ +/* Get the machine type via the mysterious romvec node operations. */ + add %g7, 0x1c, %l1 ld [%l1], %l0 ld [%l0], %l0 @@ -389,42 +356,9 @@ execute_in_high_mem: ! to a buf where above string ! will get stored by the prom. +#ifdef CONFIG_SPARC_LEON + /* no cpu-type check is needed, it is a SPARC-LEON */ - /* Check value of "compatible" property. - * "value" => "model" - * leon => sparc_leon - * sun4m => sun4m - * sun4s => sun4m - * sun4d => sun4d - * sun4e => "no_sun4e_here" - * '*' => "no_sun4u_here" - * Check single letters only - */ - - set cputypval, %o2 - /* If cputypval[0] == 'l' (lower case letter L) this is leon */ - ldub [%o2], %l1 - cmp %l1, 'l' - be leon_init - nop - - /* Check cputypval[4] to find the sun model */ - ldub [%o2 + 0x4], %l1 - - cmp %l1, 'm' - be sun4m_init - cmp %l1, 's' - be sun4m_init - cmp %l1, 'd' - be sun4d_init - cmp %l1, 'e' - be no_sun4e_here ! Could be a sun4e. - nop - b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) - nop - -leon_init: - /* LEON CPU - set boot_cpu_id */ sethi %hi(boot_cpu_id), %g2 ! boot-cpu index #ifdef CONFIG_SMP @@ -442,6 +376,26 @@ leon_init: ba continue_boot nop +#endif + +/* Check to cputype. We may be booted on a sun4u (64 bit box), + * and sun4d needs special treatment. + */ + + set cputypval, %o2 + ldub [%o2 + 0x4], %l1 + + cmp %l1, 'm' + be sun4m_init + cmp %l1, 's' + be sun4m_init + cmp %l1, 'd' + be sun4d_init + cmp %l1, 'e' + be no_sun4e_here ! Could be a sun4e. + nop + b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) + nop /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 @@ -477,9 +431,9 @@ sun4m_init: /* This sucks, apparently this makes Vikings call prom panic, will fix later */ 2: rd %psr, %o1 - srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU + srl %o1, 28, %o1 ! Get a type of the CPU - subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC + subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC be continue_boot nop @@ -505,6 +459,10 @@ continue_boot: /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! */ + + sethi %hi(cputyp), %o0 + st %g4, [%o0 + %lo(cputyp)] + /* Turn on Supervisor, EnableFloating, and all the PIL bits. * Also puts us in register window zero with traps off. */ @@ -522,7 +480,7 @@ continue_boot: set __bss_start , %o0 ! First address of BSS set _end , %o1 ! Last address of BSS add %o0, 0x1, %o0 -1: +1: stb %g0, [%o0] subcc %o0, %o1, %g0 bl 1b @@ -588,7 +546,7 @@ continue_boot: set dest, %g2; \ ld [%g5], %g4; \ st %g4, [%g2]; - + /* Patch for window spills... */ PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) @@ -639,7 +597,7 @@ continue_boot: st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] -2: +2: sethi %hi(nwindows), %g4 st %g3, [%g4 + %lo(nwindows)] ! store final value sub %g3, 0x1, %g3 @@ -659,12 +617,18 @@ continue_boot: wr %g3, PSR_ET, %psr WRITE_PAUSE - /* Call sparc32_start_kernel(struct linux_romvec *rp) */ + /* First we call prom_init() to set up PROMLIB, then + * off to start_kernel(). + */ + sethi %hi(prom_vector_p), %g5 ld [%g5 + %lo(prom_vector_p)], %o0 - call sparc32_start_kernel + call prom_init nop + call start_kernel + nop + /* We should not get here. */ call halt_me nop @@ -695,7 +659,7 @@ sun4u_5: .asciz "write" .align 4 sun4u_6: - .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r" + .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" sun4u_6e: .align 4 sun4u_7: diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c index 0f094db918c7..a2846f5e32d8 100644 --- a/trunk/arch/sparc/kernel/ioport.c +++ b/trunk/arch/sparc/kernel/ioport.c @@ -55,13 +55,17 @@ const struct sparc32_dma_ops *sparc32_dma_ops; /* This function must make sure that caches and memory are coherent after DMA * On LEON systems without cache snooping it flushes the entire D-CACHE. */ +#ifndef CONFIG_SPARC_LEON static inline void dma_make_coherent(unsigned long pa, unsigned long len) { - if (sparc_cpu_model == sparc_leon) { - if (!sparc_leon3_snooping_enabled()) - leon_flush_dcache_all(); - } } +#else +static inline void dma_make_coherent(unsigned long pa, unsigned long len) +{ + if (!sparc_leon3_snooping_enabled()) + leon_flush_dcache_all(); +} +#endif static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, @@ -423,6 +427,9 @@ arch_initcall(sparc_register_ioport); #endif /* CONFIG_SBUS */ +/* LEON reuses PCI DMA ops */ +#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON) + /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. */ @@ -650,11 +657,14 @@ struct dma_map_ops pci32_dma_ops = { }; EXPORT_SYMBOL(pci32_dma_ops); -/* leon re-uses pci32_dma_ops */ -struct dma_map_ops *leon_dma_ops = &pci32_dma_ops; -EXPORT_SYMBOL(leon_dma_ops); +#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ +#ifdef CONFIG_SPARC_LEON +struct dma_map_ops *dma_ops = &pci32_dma_ops; +#elif defined(CONFIG_SBUS) struct dma_map_ops *dma_ops = &sbus_dma_ops; +#endif + EXPORT_SYMBOL(dma_ops); diff --git a/trunk/arch/sparc/kernel/irq_32.c b/trunk/arch/sparc/kernel/irq_32.c index c145f6fd123b..ae04914f7774 100644 --- a/trunk/arch/sparc/kernel/irq_32.c +++ b/trunk/arch/sparc/kernel/irq_32.c @@ -241,6 +241,9 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler) unsigned int cpu_irq; int err; +#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON + struct tt_entry *trap_table; +#endif err = request_irq(irq, irq_handler, 0, "floppy", NULL); if (err) @@ -261,18 +264,13 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler) table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; INSTANTIATE(sparc_ttable) - -#if defined CONFIG_SMP - if (sparc_cpu_model != sparc_leon) { - struct tt_entry *trap_table; - - trap_table = &trapbase_cpu1; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu2; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu3; - INSTANTIATE(trap_table) - } +#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON + trap_table = &trapbase_cpu1; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu2; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu3; + INSTANTIATE(trap_table) #endif #undef INSTANTIATE /* diff --git a/trunk/arch/sparc/kernel/kernel.h b/trunk/arch/sparc/kernel/kernel.h index 291bb5de9ce0..a86372d34587 100644 --- a/trunk/arch/sparc/kernel/kernel.h +++ b/trunk/arch/sparc/kernel/kernel.h @@ -26,9 +26,6 @@ static inline unsigned long kimage_addr_to_ra(const char *p) #endif #ifdef CONFIG_SPARC32 -/* setup_32.c */ -void sparc32_start_kernel(struct linux_romvec *rp); - /* cpu.c */ extern void cpu_probe(void); diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index e34e2c40c060..77c1b916e4dd 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -23,7 +23,6 @@ #include #include -#include "kernel.h" #include "prom.h" #include "irq.h" diff --git a/trunk/arch/sparc/kernel/leon_pmc.c b/trunk/arch/sparc/kernel/leon_pmc.c index 4e174321097d..519ca923f59f 100644 --- a/trunk/arch/sparc/kernel/leon_pmc.c +++ b/trunk/arch/sparc/kernel/leon_pmc.c @@ -7,7 +7,6 @@ #include #include -#include #include /* List of Systems that need fixup instructions around power-down instruction */ @@ -66,15 +65,13 @@ void pmc_leon_idle(void) /* Install LEON Power Down function */ static int __init leon_pmc_install(void) { - if (sparc_cpu_model == sparc_leon) { - /* Assign power management IDLE handler */ - if (pmc_leon_need_fixup()) - pm_idle = pmc_leon_idle_fixup; - else - pm_idle = pmc_leon_idle; + /* Assign power management IDLE handler */ + if (pmc_leon_need_fixup()) + pm_idle = pmc_leon_idle_fixup; + else + pm_idle = pmc_leon_idle; - printk(KERN_INFO "leon: power management initialized\n"); - } + printk(KERN_INFO "leon: power management initialized\n"); return 0; } diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index 0f3fb6d9c8ef..a469090faf9f 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -48,13 +48,15 @@ #include "kernel.h" +#ifdef CONFIG_SPARC_LEON + #include "irq.h" extern ctxd_t *srmmu_ctx_table_phys; static int smp_processors_ready; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpumask_t smp_commenced_mask; -void __cpuinit leon_configure_cache_smp(void); +void __init leon_configure_cache_smp(void); static void leon_ipi_init(void); /* IRQ number of LEON IPIs */ @@ -121,7 +123,7 @@ void __cpuinit leon_callin(void) extern struct linux_prom_registers smp_penguin_ctable; -void __cpuinit leon_configure_cache_smp(void) +void __init leon_configure_cache_smp(void) { unsigned long cfg = sparc_leon3_get_dcachecfg(); int me = smp_processor_id(); @@ -505,3 +507,5 @@ void __init leon_init_smp(void) sparc32_ipi_ops = &leon_ipi_ops; } + +#endif /* CONFIG_SPARC_LEON */ diff --git a/trunk/arch/sparc/kernel/process_32.c b/trunk/arch/sparc/kernel/process_32.c index cb36e82dcd5d..fe6787cc62fc 100644 --- a/trunk/arch/sparc/kernel/process_32.c +++ b/trunk/arch/sparc/kernel/process_32.c @@ -65,25 +65,50 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); struct task_struct *last_task_used_math = NULL; struct thread_info *current_set[NR_CPUS]; +#ifndef CONFIG_SMP + /* * the idle loop on a Sparc... ;) */ void cpu_idle(void) { - set_thread_flag(TIF_POLLING_NRFLAG); - /* endless idle loop with no priority at all */ for (;;) { - while (!need_resched()) { - if (pm_idle) + if (pm_idle) { + while (!need_resched()) + (*pm_idle)(); + } else { + while (!need_resched()) + cpu_relax(); + } + schedule_preempt_disabled(); + } +} + +#else + +/* This is being executed in task 0 'user space'. */ +void cpu_idle(void) +{ + set_thread_flag(TIF_POLLING_NRFLAG); + /* endless idle loop with no priority at all */ + while(1) { +#ifdef CONFIG_SPARC_LEON + if (pm_idle) { + while (!need_resched()) (*pm_idle)(); - else + } else +#endif + { + while (!need_resched()) cpu_relax(); } schedule_preempt_disabled(); } } +#endif + /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { diff --git a/trunk/arch/sparc/kernel/prom_common.c b/trunk/arch/sparc/kernel/prom_common.c index 1303021748c8..741df916c124 100644 --- a/trunk/arch/sparc/kernel/prom_common.c +++ b/trunk/arch/sparc/kernel/prom_common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "prom.h" diff --git a/trunk/arch/sparc/kernel/rtrap_32.S b/trunk/arch/sparc/kernel/rtrap_32.S index 6c34de0c2abd..7abc24e2bf1a 100644 --- a/trunk/arch/sparc/kernel/rtrap_32.S +++ b/trunk/arch/sparc/kernel/rtrap_32.S @@ -231,14 +231,11 @@ srmmu_rett_stackchk: cmp %g1, %fp bleu ret_trap_user_stack_is_bolixed mov AC_M_SFSR, %g1 -LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0) -SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0) + lda [%g1] ASI_M_MMUREGS, %g0 -LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1) -SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1) + lda [%g0] ASI_M_MMUREGS, %g1 or %g1, 0x2, %g1 -LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) -SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) + sta %g1, [%g0] ASI_M_MMUREGS restore %g0, %g0, %g0 @@ -247,16 +244,13 @@ SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) save %g0, %g0, %g0 andn %g1, 0x2, %g1 -LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) -SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) + sta %g1, [%g0] ASI_M_MMUREGS mov AC_M_SFAR, %g2 -LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2) -SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2) + lda [%g2] ASI_M_MMUREGS, %g2 mov AC_M_SFSR, %g1 -LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1) -SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1) + lda [%g1] ASI_M_MMUREGS, %g1 andcc %g1, 0x2, %g0 be ret_trap_userwins_ok nop diff --git a/trunk/arch/sparc/kernel/setup_32.c b/trunk/arch/sparc/kernel/setup_32.c index efe3e64bba38..c052313f4dc5 100644 --- a/trunk/arch/sparc/kernel/setup_32.c +++ b/trunk/arch/sparc/kernel/setup_32.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -46,7 +45,6 @@ #include #include #include -#include #include "kernel.h" @@ -239,42 +237,28 @@ static void __init per_cpu_patch(void) } } -struct leon_1insn_patch_entry { - unsigned int addr; - unsigned int insn; -}; - enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); -static __init void leon_patch(void) -{ - struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch; - struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end; +struct tt_entry *sparc_ttable; - /* Default instruction is leon - no patching */ - if (sparc_cpu_model == sparc_leon) - return; +struct pt_regs fake_swapper_regs; - while (start < end) { - unsigned long addr = start->addr; +void __init setup_arch(char **cmdline_p) +{ + int i; + unsigned long highest_paddr; - *(unsigned int *)(addr) = start->insn; - flushi(addr); + sparc_ttable = (struct tt_entry *) &trapbase; - start++; - } -} + /* Initialize PROM console and command line. */ + *cmdline_p = prom_getbootargs(); + strcpy(boot_command_line, *cmdline_p); + parse_early_param(); -struct tt_entry *sparc_ttable; -struct pt_regs fake_swapper_regs; + boot_flags_init(*cmdline_p); -/* Called from head_32.S - before we have setup anything - * in the kernel. Be very careful with what you do here. - */ -void __init sparc32_start_kernel(struct linux_romvec *rp) -{ - prom_init(rp); + register_console(&prom_early_console); /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; @@ -291,26 +275,6 @@ void __init sparc32_start_kernel(struct linux_romvec *rp) if (!strncmp(&cputypval[0], "leon" , 4)) sparc_cpu_model = sparc_leon; - leon_patch(); - start_kernel(); -} - -void __init setup_arch(char **cmdline_p) -{ - int i; - unsigned long highest_paddr; - - sparc_ttable = (struct tt_entry *) &trapbase; - - /* Initialize PROM console and command line. */ - *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); - parse_early_param(); - - boot_flags_init(*cmdline_p); - - register_console(&prom_early_console); - printk("ARCH: "); switch(sparc_cpu_model) { case sun4m: diff --git a/trunk/arch/sparc/kernel/trampoline_32.S b/trunk/arch/sparc/kernel/trampoline_32.S index af27acab4486..7364ddc9e5aa 100644 --- a/trunk/arch/sparc/kernel/trampoline_32.S +++ b/trunk/arch/sparc/kernel/trampoline_32.S @@ -149,6 +149,8 @@ sun4d_cpu_startup: b,a smp_do_cpu_idle +#ifdef CONFIG_SPARC_LEON + __CPUINIT .align 4 .global leon_smp_cpu_startup, smp_penguin_ctable @@ -159,7 +161,7 @@ leon_smp_cpu_startup: ld [%g1+4],%g1 srl %g1,4,%g1 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ - sta %g1, [%g5] ASI_LEON_MMUREGS + sta %g1, [%g5] ASI_M_MMUREGS /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ set (PSR_PIL | PSR_S | PSR_PS), %g1 @@ -205,3 +207,5 @@ leon_smp_cpu_startup: nop b,a smp_do_cpu_idle + +#endif diff --git a/trunk/arch/sparc/kernel/traps_64.c b/trunk/arch/sparc/kernel/traps_64.c index 3b05e6697710..c72fdf55e1c1 100644 --- a/trunk/arch/sparc/kernel/traps_64.c +++ b/trunk/arch/sparc/kernel/traps_64.c @@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs) do_fpe_common(regs); } -extern int do_mathemu(struct pt_regs *, struct fpustate *, bool); +extern int do_mathemu(struct pt_regs *, struct fpustate *); void do_fpother(struct pt_regs *regs) { @@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs) switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ case (3 << 14): /* unimplemented_FPop */ - ret = do_mathemu(regs, f, false); + ret = do_mathemu(regs, f); break; } if (ret) @@ -2308,12 +2308,10 @@ void do_illegal_instruction(struct pt_regs *regs) } else { struct fpustate *f = FPUSTATE; - /* On UltraSPARC T2 and later, FPU insns which - * are not implemented in HW signal an illegal - * instruction trap and do not set the FP Trap - * Trap in the %fsr to unimplemented_FPop. + /* XXX maybe verify XFSR bits like + * XXX do_fpother() does? */ - if (do_mathemu(regs, f, true)) + if (do_mathemu(regs, f)) return; } } diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 89c2c29f154b..0e1605697b49 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -107,11 +107,6 @@ SECTIONS *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } - .leon_1insn_patch : { - __leon_1insn_patch = .; - *(.leon_1insn_patch) - __leon_1insn_patch_end = .; - } .swapper_tsb_phys_patch : { __swapper_tsb_phys_patch = .; *(.swapper_tsb_phys_patch) diff --git a/trunk/arch/sparc/kernel/wof.S b/trunk/arch/sparc/kernel/wof.S index 28a7bc69f82b..4c2de3cf309b 100644 --- a/trunk/arch/sparc/kernel/wof.S +++ b/trunk/arch/sparc/kernel/wof.S @@ -332,30 +332,24 @@ spwin_srmmu_stackchk: mov AC_M_SFSR, %glob_tmp /* Clear the fault status and turn on the no_fault bit. */ -LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR -SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR + lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR -LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control -SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control + lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit -LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it -SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it + sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp -LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) -SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) + sta %glob_tmp, [%g0] ASI_M_MMUREGS mov AC_M_SFAR, %glob_tmp -LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) -SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) + lda [%glob_tmp] ASI_M_MMUREGS, %g0 mov AC_M_SFSR, %glob_tmp -LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp) -SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) + lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp andcc %glob_tmp, 0x2, %g0 ! did we fault? be,a spwin_finish_up + 0x4 ! cool beans, success restore %g0, %g0, %g0 diff --git a/trunk/arch/sparc/kernel/wuf.S b/trunk/arch/sparc/kernel/wuf.S index 2c21cc59683e..9fde91a249e0 100644 --- a/trunk/arch/sparc/kernel/wuf.S +++ b/trunk/arch/sparc/kernel/wuf.S @@ -254,19 +254,16 @@ srmmu_fwin_stackchk: mov AC_M_SFSR, %l4 cmp %l5, %sp bleu fwin_user_stack_is_bolixed -LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status -SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status + lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status /* The technique is, turn off faults on this processor, * just let the load rip, then check the sfsr to see if * a fault did occur. Then we turn on fault traps again * and branch conditionally based upon what happened. */ -LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg -SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg + lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg or %l5, 0x2, %l5 ! turn on no-fault bit -LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it -SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it + sta %l5, [%g0] ASI_M_MMUREGS ! store it /* Cross fingers and go for it. */ LOAD_WINDOW(sp) @@ -278,22 +275,18 @@ SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it /* LOCATION: Window 'T' */ -LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again -SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again - andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit -LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it -SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it + lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again + andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit + sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it mov AC_M_SFAR, %twin_tmp2 -LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address -SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address + lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address mov AC_M_SFSR, %twin_tmp2 -LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status -SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status - andcc %twin_tmp2, 0x2, %g0 ! did fault occur? + lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status + andcc %twin_tmp2, 0x2, %g0 ! did fault occur? - bne 1f ! yep, cleanup + bne 1f ! yep, cleanup nop wr %t_psr, 0x0, %psr diff --git a/trunk/arch/sparc/math-emu/math_64.c b/trunk/arch/sparc/math-emu/math_64.c index 1704068da928..2bbe2f28ad23 100644 --- a/trunk/arch/sparc/math-emu/math_64.c +++ b/trunk/arch/sparc/math-emu/math_64.c @@ -163,7 +163,7 @@ typedef union { u64 q[2]; } *argp; -int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) +int do_mathemu(struct pt_regs *regs, struct fpustate *f) { unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; @@ -218,7 +218,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) case FSQRTS: { unsigned long x = current_thread_info()->xfsr[0]; - x = (x >> 14) & 0x7; + x = (x >> 14) & 0xf; TYPE(x,1,1,1,1,0,0); break; } @@ -226,7 +226,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) case FSQRTD: { unsigned long x = current_thread_info()->xfsr[0]; - x = (x >> 14) & 0x7; + x = (x >> 14) & 0xf; TYPE(x,2,1,2,1,0,0); break; } @@ -357,17 +357,9 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) if (type) { argp rs1 = NULL, rs2 = NULL, rd = NULL; - /* Starting with UltraSPARC-T2, the cpu does not set the FP Trap - * Type field in the %fsr to unimplemented_FPop. Nor does it - * use the fp_exception_other trap. Instead it signals an - * illegal instruction and leaves the FP trap type field of - * the %fsr unchanged. - */ - if (!illegal_insn_trap) { - int ftt = (current_thread_info()->xfsr[0] >> 14) & 0x7; - if (ftt != (type >> 9)) - goto err; - } + freg = (current_thread_info()->xfsr[0] >> 14) & 0xf; + if (freg != (type >> 9)) + goto err; current_thread_info()->xfsr[0] &= ~0x1c000; freg = ((insn >> 14) & 0x1f); switch (type & 0x3) { diff --git a/trunk/arch/sparc/mm/Makefile b/trunk/arch/sparc/mm/Makefile index 30c3eccfdf5a..69ffd3112fed 100644 --- a/trunk/arch/sparc/mm/Makefile +++ b/trunk/arch/sparc/mm/Makefile @@ -8,9 +8,8 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o obj-y += fault_$(BITS).o obj-y += init_$(BITS).o obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o -obj-$(CONFIG_SPARC32) += srmmu_access.o obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o -obj-$(CONFIG_SPARC32) += leon_mm.o +obj-$(CONFIG_SPARC_LEON)+= leon_mm.o # Only used by sparc64 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/trunk/arch/sparc/mm/leon_mm.c b/trunk/arch/sparc/mm/leon_mm.c index 5bed085a2c17..4c67ae6e5023 100644 --- a/trunk/arch/sparc/mm/leon_mm.c +++ b/trunk/arch/sparc/mm/leon_mm.c @@ -32,7 +32,7 @@ static inline unsigned long leon_get_ctable_ptr(void) } -unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr) +unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) { unsigned int ctxtbl; diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 62e3f5773303..256db6b22c54 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -646,23 +646,6 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start, } } -/* These flush types are not available on all chips... */ -static inline unsigned long srmmu_probe(unsigned long vaddr) -{ - unsigned long retval; - - if (sparc_cpu_model != sparc_leon) { - - vaddr &= PAGE_MASK; - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); - } else { - retval = leon_swprobe(vaddr, 0); - } - return retval; -} - /* * This is much cleaner than poking around physical address space * looking at the prom's page table directly which is what most @@ -682,7 +665,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, break; /* probably wrap around */ if(start == 0xfef00000) start = KADB_DEBUGGER_BEGVM; - if(!(prompte = srmmu_probe(start))) { + if(!(prompte = srmmu_hwprobe(start))) { start += PAGE_SIZE; continue; } @@ -691,12 +674,12 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, what = 0; if(!(start & ~(SRMMU_REAL_PMD_MASK))) { - if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) + if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) what = 1; } if(!(start & ~(SRMMU_PGDIR_MASK))) { - if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == + if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == prompte) what = 2; } @@ -1173,7 +1156,7 @@ static void turbosparc_flush_page_to_ram(unsigned long page) #ifdef TURBOSPARC_WRITEBACK volatile unsigned long clear; - if (srmmu_probe(page)) + if (srmmu_hwprobe(page)) turbosparc_flush_page_cache(page); clear = srmmu_get_fstatus(); #endif diff --git a/trunk/arch/sparc/mm/srmmu_access.S b/trunk/arch/sparc/mm/srmmu_access.S deleted file mode 100644 index d0a67b2c2383..000000000000 --- a/trunk/arch/sparc/mm/srmmu_access.S +++ /dev/null @@ -1,82 +0,0 @@ -/* Assembler variants of srmmu access functions. - * Implemented in assembler to allow run-time patching. - * LEON uses a different ASI for MMUREGS than SUN. - * - * The leon_1insn_patch infrastructure is used - * for the run-time patching. - */ - -#include - -#include -#include -#include - -/* unsigned int srmmu_get_mmureg(void) */ -ENTRY(srmmu_get_mmureg) -LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0) -SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0) - retl - nop -ENDPROC(srmmu_get_mmureg) - -/* void srmmu_set_mmureg(unsigned long regval) */ -ENTRY(srmmu_set_mmureg) -LEON_PI(sta %o0, [%g0] ASI_LEON_MMUREGS) -SUN_PI_(sta %o0, [%g0] ASI_M_MMUREGS) - retl - nop -ENDPROC(srmmu_set_mmureg) - -/* void srmmu_set_ctable_ptr(unsigned long paddr) */ -ENTRY(srmmu_set_ctable_ptr) - /* paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); */ - srl %o0, 4, %g1 - and %g1, SRMMU_CTX_PMASK, %g1 - - mov SRMMU_CTXTBL_PTR, %g2 -LEON_PI(sta %g1, [%g2] ASI_LEON_MMUREGS) -SUN_PI_(sta %g1, [%g2] ASI_M_MMUREGS) - retl - nop -ENDPROC(srmmu_set_ctable_ptr) - - -/* void srmmu_set_context(int context) */ -ENTRY(srmmu_set_context) - mov SRMMU_CTX_REG, %g1 -LEON_PI(sta %o0, [%g1] ASI_LEON_MMUREGS) -SUN_PI_(sta %o0, [%g1] ASI_M_MMUREGS) - retl - nop -ENDPROC(srmmu_set_context) - - -/* int srmmu_get_context(void) */ -ENTRY(srmmu_get_context) - mov SRMMU_CTX_REG, %o0 -LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) -SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) - retl - nop -ENDPROC(srmmu_get_context) - - -/* unsigned int srmmu_get_fstatus(void) */ -ENTRY(srmmu_get_fstatus) - mov SRMMU_FAULT_STATUS, %o0 -LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) -SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) - retl - nop -ENDPROC(srmmu_get_fstatus) - - -/* unsigned int srmmu_get_faddr(void) */ -ENTRY(srmmu_get_faddr) - mov SRMMU_FAULT_ADDR, %o0 -LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) -SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) - retl - nop -ENDPROC(srmmu_get_faddr) diff --git a/trunk/arch/x86/include/asm/acpi.h b/trunk/arch/x86/include/asm/acpi.h index 0c44630d1789..724aa441de7d 100644 --- a/trunk/arch/x86/include/asm/acpi.h +++ b/trunk/arch/x86/include/asm/acpi.h @@ -29,7 +29,6 @@ #include #include #include -#include #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -117,8 +116,10 @@ static inline void acpi_disable_pci(void) /* Low-level suspend routine. */ extern int acpi_suspend_lowlevel(void); -/* Physical address to resume after wakeup */ -#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start)) +extern const unsigned char acpi_wakeup_code[]; + +/* early initialization routine */ +extern void acpi_reserve_wakeup_memory(void); /* * Check if the CPU can handle C2 and deeper diff --git a/trunk/arch/x86/include/asm/bitops.h b/trunk/arch/x86/include/asm/bitops.h index a6983b277220..b97596e2b68c 100644 --- a/trunk/arch/x86/include/asm/bitops.h +++ b/trunk/arch/x86/include/asm/bitops.h @@ -15,8 +15,6 @@ #include #include -#define BIT_64(n) (U64_C(1) << (n)) - /* * These have to be done with inline assembly: that way the bit-setting * is guaranteed to be atomic. All bit operations return 0 if the bit diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index 0a687fd185e6..b772dd6ad450 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -1251,15 +1251,15 @@ void mce_log_therm_throt_event(__u64 status) * poller finds an MCE, poll 2x faster. When the poller finds no more * errors, poll 2x slower (up to check_interval seconds). */ -static unsigned long check_interval = 5 * 60; /* 5 minutes */ +static int check_interval = 5 * 60; /* 5 minutes */ -static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ +static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */ static DEFINE_PER_CPU(struct timer_list, mce_timer); -static void mce_timer_fn(unsigned long data) +static void mce_start_timer(unsigned long data) { - struct timer_list *t = &__get_cpu_var(mce_timer); - unsigned long iv; + struct timer_list *t = &per_cpu(mce_timer, data); + int *n; WARN_ON(smp_processor_id() != data); @@ -1272,14 +1272,13 @@ static void mce_timer_fn(unsigned long data) * Alert userspace if needed. If we logged an MCE, reduce the * polling interval, otherwise increase the polling interval. */ - iv = __this_cpu_read(mce_next_interval); + n = &__get_cpu_var(mce_next_interval); if (mce_notify_irq()) - iv = max(iv, (unsigned long) HZ/100); + *n = max(*n/2, HZ/100); else - iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); - __this_cpu_write(mce_next_interval, iv); + *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); - t->expires = jiffies + iv; + t->expires = jiffies + *n; add_timer_on(t, smp_processor_id()); } @@ -1473,9 +1472,9 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) rdmsrl(msrs[i], val); /* CntP bit set? */ - if (val & BIT_64(62)) { - val &= ~BIT_64(62); - wrmsrl(msrs[i], val); + if (val & BIT(62)) { + val &= ~BIT(62); + wrmsrl(msrs[i], val); } } @@ -1557,17 +1556,17 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) static void __mcheck_cpu_init_timer(void) { struct timer_list *t = &__get_cpu_var(mce_timer); - unsigned long iv = __this_cpu_read(mce_next_interval); + int *n = &__get_cpu_var(mce_next_interval); - setup_timer(t, mce_timer_fn, smp_processor_id()); + setup_timer(t, mce_start_timer, smp_processor_id()); if (mce_ignore_ce) return; - __this_cpu_write(mce_next_interval, iv); - if (!iv) + *n = check_interval * HZ; + if (!*n) return; - t->expires = round_jiffies(jiffies + iv); + t->expires = round_jiffies(jiffies + *n); add_timer_on(t, smp_processor_id()); } @@ -2277,7 +2276,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) case CPU_DOWN_FAILED_FROZEN: if (!mce_ignore_ce && check_interval) { t->expires = round_jiffies(jiffies + - per_cpu(mce_next_interval, cpu)); + __get_cpu_var(mce_next_interval)); add_timer_on(t, cpu); } smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); diff --git a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c index bdda2e6c673b..ac140c7be396 100644 --- a/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/trunk/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -266,7 +266,7 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, if (align > max_align) align = max_align; - sizek = 1UL << align; + sizek = 1 << align; if (debug_print) { char start_factor = 'K', size_factor = 'K'; unsigned long start_base, size_base; diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c index 1460a5df92f7..9cc7b4392f7c 100644 --- a/trunk/arch/x86/kernel/hpet.c +++ b/trunk/arch/x86/kernel/hpet.c @@ -870,7 +870,7 @@ int __init hpet_enable(void) else pr_warn("HPET initial state will not be saved\n"); cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY); - hpet_writel(cfg, HPET_CFG); + hpet_writel(cfg, HPET_Tn_CFG(i)); if (cfg) pr_warn("HPET: Unrecognized bits %#x set in global cfg\n", cfg); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index be3cea4407ff..72102e0ab7cb 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -2595,7 +2595,8 @@ static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, *gfnp = gfn; kvm_release_pfn_clean(pfn); pfn &= ~mask; - kvm_get_pfn(pfn); + if (!get_page_unless_zero(pfn_to_page(pfn))) + BUG(); *pfnp = pfn; } } diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c index 3d68ef6d2266..f11729fd019c 100644 --- a/trunk/arch/x86/mm/pat.c +++ b/trunk/arch/x86/mm/pat.c @@ -158,47 +158,31 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type) return req_type; } -struct pagerange_state { - unsigned long cur_pfn; - int ram; - int not_ram; -}; - -static int -pagerange_is_ram_callback(unsigned long initial_pfn, unsigned long total_nr_pages, void *arg) -{ - struct pagerange_state *state = arg; - - state->not_ram |= initial_pfn > state->cur_pfn; - state->ram |= total_nr_pages > 0; - state->cur_pfn = initial_pfn + total_nr_pages; - - return state->ram && state->not_ram; -} - static int pat_pagerange_is_ram(resource_size_t start, resource_size_t end) { - int ret = 0; - unsigned long start_pfn = start >> PAGE_SHIFT; - unsigned long end_pfn = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - struct pagerange_state state = {start_pfn, 0, 0}; - - /* - * For legacy reasons, physical address range in the legacy ISA - * region is tracked as non-RAM. This will allow users of - * /dev/mem to map portions of legacy ISA region, even when - * some of those portions are listed(or not even listed) with - * different e820 types(RAM/reserved/..) - */ - if (start_pfn < ISA_END_ADDRESS >> PAGE_SHIFT) - start_pfn = ISA_END_ADDRESS >> PAGE_SHIFT; + int ram_page = 0, not_rampage = 0; + unsigned long page_nr; - if (start_pfn < end_pfn) { - ret = walk_system_ram_range(start_pfn, end_pfn - start_pfn, - &state, pagerange_is_ram_callback); + for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); + ++page_nr) { + /* + * For legacy reasons, physical address range in the legacy ISA + * region is tracked as non-RAM. This will allow users of + * /dev/mem to map portions of legacy ISA region, even when + * some of those portions are listed(or not even listed) with + * different e820 types(RAM/reserved/..) + */ + if (page_nr >= (ISA_END_ADDRESS >> PAGE_SHIFT) && + page_is_ram(page_nr)) + ram_page = 1; + else + not_rampage = 1; + + if (ram_page == not_rampage) + return -1; } - return (ret > 0) ? -1 : (state.ram ? 1 : 0); + return ram_page; } /* diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index e74df9548a02..75f33b2a5933 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -1116,10 +1116,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, - .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = xen_write_msr_safe, - .wrmsr_regs = native_wrmsr_safe_regs, - .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, diff --git a/trunk/block/blk-ioc.c b/trunk/block/blk-ioc.c index 893b8007c657..1e2d53b04858 100644 --- a/trunk/block/blk-ioc.c +++ b/trunk/block/blk-ioc.c @@ -235,7 +235,6 @@ void ioc_clear_queue(struct request_queue *q) int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node) { struct io_context *ioc; - int ret; ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO, node); @@ -263,12 +262,9 @@ int create_task_io_context(struct task_struct *task, gfp_t gfp_flags, int node) task->io_context = ioc; else kmem_cache_free(iocontext_cachep, ioc); - - ret = task->io_context ? 0 : -EBUSY; - task_unlock(task); - return ret; + return 0; } /** diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 74ee4ab577b6..ebaa04593236 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -25,6 +25,8 @@ #include #include +#include + #include "internal.h" #include "sleep.h" @@ -91,11 +93,13 @@ static struct notifier_block tts_notifier = { static int acpi_sleep_prepare(u32 acpi_state) { #ifdef CONFIG_ACPI_SLEEP + unsigned long wakeup_pa = real_mode_header->wakeup_start; /* do we have a wakeup address for S2 and S3? */ if (acpi_state == ACPI_STATE_S3) { - if (!acpi_wakeup_address) + if (!wakeup_pa) return -EFAULT; - acpi_set_firmware_waking_vector(acpi_wakeup_address); + acpi_set_firmware_waking_vector( + (acpi_physical_address)wakeup_pa); } ACPI_FLUSH_CPU_CACHE(); diff --git a/trunk/drivers/atm/solos-pci.c b/trunk/drivers/atm/solos-pci.c index 98510931c815..e8cd652d2017 100644 --- a/trunk/drivers/atm/solos-pci.c +++ b/trunk/drivers/atm/solos-pci.c @@ -984,7 +984,6 @@ static uint32_t fpga_tx(struct solos_card *card) } else if (skb && card->using_dma) { SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data, skb->len, PCI_DMA_TODEVICE); - card->tx_skb[port] = skb; iowrite32(SKB_CB(skb)->dma_addr, card->config_regs + TX_DMA_ADDR(port)); } @@ -1153,8 +1152,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) db_fpga_upgrade = db_firmware_upgrade = 0; } - if (card->fpga_version >= DMA_SUPPORTED) { - pci_set_master(dev); + if (card->fpga_version >= DMA_SUPPORTED){ card->using_dma = 1; } else { card->using_dma = 0; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 264bc77dcb91..304000c3d433 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -294,16 +294,18 @@ static int hba_reset_nosleep(struct driver_data *dd) */ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) { + unsigned long flags = 0; + atomic_set(&port->commands[tag].active, 1); - spin_lock(&port->cmd_issue_lock); + spin_lock_irqsave(&port->cmd_issue_lock, flags); writel((1 << MTIP_TAG_BIT(tag)), port->s_active[MTIP_TAG_INDEX(tag)]); writel((1 << MTIP_TAG_BIT(tag)), port->cmd_issue[MTIP_TAG_INDEX(tag)]); - spin_unlock(&port->cmd_issue_lock); + spin_unlock_irqrestore(&port->cmd_issue_lock, flags); /* Set the command's timeout value.*/ port->commands[tag].comp_time = jiffies + msecs_to_jiffies( @@ -434,7 +436,8 @@ static void mtip_init_port(struct mtip_port *port) writel(0xFFFFFFFF, port->completed[i]); /* Clear any pending interrupts for this port */ - writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); + writel(readl(port->dd->mmio + PORT_IRQ_STAT), + port->dd->mmio + PORT_IRQ_STAT); /* Clear any pending interrupts on the HBA. */ writel(readl(port->dd->mmio + HOST_IRQ_STAT), @@ -779,24 +782,13 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Stop the timer to prevent command timeouts. */ del_timer(&port->cmd_timer); - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); - - if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && - test_bit(MTIP_TAG_INTERNAL, port->allocated)) { - cmd = &port->commands[MTIP_TAG_INTERNAL]; - dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); - - atomic_inc(&cmd->active); /* active > 1 indicates error */ - if (cmd->comp_data && cmd->comp_func) { - cmd->comp_func(port, MTIP_TAG_INTERNAL, - cmd->comp_data, PORT_IRQ_TF_ERR); - } - goto handle_tfe_exit; - } /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + /* Set eh_active */ + set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + /* Loop through all the groups */ for (group = 0; group < dd->slot_groups; group++) { completed = readl(port->completed[group]); @@ -948,7 +940,6 @@ static void mtip_handle_tfe(struct driver_data *dd) } print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); -handle_tfe_exit: /* clear eh_active */ clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); @@ -970,8 +961,6 @@ static inline void mtip_process_sdbf(struct driver_data *dd) /* walk all bits in all slot groups */ for (group = 0; group < dd->slot_groups; group++) { completed = readl(port->completed[group]); - if (!completed) - continue; /* clear completed status register in the hardware.*/ writel(completed, port->completed[group]); @@ -1340,6 +1329,22 @@ static int mtip_exec_internal_command(struct mtip_port *port, } rv = -EAGAIN; } + + if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) { + dev_warn(&port->dd->pdev->dev, + "Retiring internal command but CI is 1.\n"); + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + hba_reset_nosleep(port->dd); + rv = -ENXIO; + } else { + mtip_restart_port(port); + rv = -EAGAIN; + } + goto exec_ic_exit; + } + } else { /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); @@ -1356,25 +1361,21 @@ static int mtip_exec_internal_command(struct mtip_port *port, rv = -ENXIO; goto exec_ic_exit; } - if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) { - atomic_inc(&int_cmd->active); /* error */ - break; - } } - } - if (atomic_read(&int_cmd->active) > 1) { - dev_err(&port->dd->pdev->dev, - "Internal command [%02X] failed\n", fis->command); - rv = -EIO; - } - if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) + if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { - rv = -ENXIO; - if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - mtip_restart_port(port); + dev_err(&port->dd->pdev->dev, + "Internal command did not complete [atomic]\n"); rv = -EAGAIN; + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + hba_reset_nosleep(port->dd); + rv = -ENXIO; + } else { + mtip_restart_port(port); + rv = -EAGAIN; + } } } exec_ic_exit: @@ -1892,33 +1893,13 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, void __user *user_buffer) { struct host_to_dev_fis fis; - struct host_to_dev_fis *reply; - u8 *buf = NULL; - dma_addr_t dma_addr = 0; - int rv = 0, xfer_sz = command[3]; - - if (xfer_sz) { - if (user_buffer) - return -EFAULT; - - buf = dmam_alloc_coherent(&port->dd->pdev->dev, - ATA_SECT_SIZE * xfer_sz, - &dma_addr, - GFP_KERNEL); - if (!buf) { - dev_err(&port->dd->pdev->dev, - "Memory allocation failed (%d bytes)\n", - ATA_SECT_SIZE * xfer_sz); - return -ENOMEM; - } - memset(buf, 0, ATA_SECT_SIZE * xfer_sz); - } + struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.type = 0x27; - fis.opts = 1 << 7; - fis.command = command[0]; + fis.type = 0x27; + fis.opts = 1 << 7; + fis.command = command[0]; fis.features = command[2]; fis.sect_count = command[3]; if (fis.command == ATA_CMD_SMART) { @@ -1927,11 +1908,6 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, fis.cyl_hi = 0xC2; } - if (xfer_sz) - reply = (port->rxfis + RX_FIS_PIO_SETUP); - else - reply = (port->rxfis + RX_FIS_D2H_REG); - dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, sect %x, " "feat %x, sectcnt %x\n", @@ -1941,46 +1917,43 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, command[2], command[3]); + memset(port->sector_buffer, 0x00, ATA_SECT_SIZE); + /* Execute the command. */ if (mtip_exec_internal_command(port, &fis, 5, - (xfer_sz ? dma_addr : 0), - (xfer_sz ? ATA_SECT_SIZE * xfer_sz : 0), + port->sector_buffer_dma, + (command[3] != 0) ? ATA_SECT_SIZE : 0, 0, GFP_KERNEL, MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { - rv = -EFAULT; - goto exit_drive_command; + return -1; } /* Collect the completion status. */ command[0] = reply->command; /* Status*/ command[1] = reply->features; /* Error*/ - command[2] = reply->sect_count; + command[2] = command[3]; dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, " - "err %x, nsect %x\n", + "err %x, cmd %x\n", __func__, command[0], command[1], command[2]); - if (xfer_sz) { + if (user_buffer && command[3]) { if (copy_to_user(user_buffer, - buf, + port->sector_buffer, ATA_SECT_SIZE * command[3])) { - rv = -EFAULT; - goto exit_drive_command; + return -EFAULT; } } -exit_drive_command: - if (buf) - dmam_free_coherent(&port->dd->pdev->dev, - ATA_SECT_SIZE * xfer_sz, buf, dma_addr); - return rv; + + return 0; } /* @@ -2030,32 +2003,6 @@ static unsigned int implicit_sector(unsigned char command, return rv; } -static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) -{ - switch (fis->command) { - case ATA_CMD_DOWNLOAD_MICRO: - *timeout = 120000; /* 2 minutes */ - break; - case ATA_CMD_SEC_ERASE_UNIT: - case 0xFC: - *timeout = 240000; /* 4 minutes */ - break; - case ATA_CMD_STANDBYNOW1: - *timeout = 10000; /* 10 seconds */ - break; - case 0xF7: - case 0xFA: - *timeout = 60000; /* 60 seconds */ - break; - case ATA_CMD_SMART: - *timeout = 15000; /* 15 seconds */ - break; - default: - *timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; - break; - } -} - /* * Executes a taskfile * See ide_taskfile_ioctl() for derivation @@ -2076,7 +2023,7 @@ static int exec_drive_taskfile(struct driver_data *dd, unsigned int taskin = 0; unsigned int taskout = 0; u8 nsect = 0; - unsigned int timeout; + unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; unsigned int force_single_sector; unsigned int transfer_size; unsigned long task_file_data; @@ -2206,7 +2153,32 @@ static int exec_drive_taskfile(struct driver_data *dd, fis.lba_hi, fis.device); - mtip_set_timeout(&fis, &timeout); + switch (fis.command) { + case ATA_CMD_DOWNLOAD_MICRO: + /* Change timeout for Download Microcode to 2 minutes */ + timeout = 120000; + break; + case ATA_CMD_SEC_ERASE_UNIT: + /* Change timeout for Security Erase Unit to 4 minutes.*/ + timeout = 240000; + break; + case ATA_CMD_STANDBYNOW1: + /* Change timeout for standby immediate to 10 seconds.*/ + timeout = 10000; + break; + case 0xF7: + case 0xFA: + /* Change timeout for vendor unique command to 10 secs */ + timeout = 10000; + break; + case ATA_CMD_SMART: + /* Change timeout for vendor unique command to 15 secs */ + timeout = 15000; + break; + default: + timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; + break; + } /* Determine the correct transfer size.*/ if (force_single_sector) @@ -2323,12 +2295,13 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, { switch (cmd) { case HDIO_GET_IDENTITY: - { - if (copy_to_user((void __user *)arg, dd->port->identify, - sizeof(u16) * ATA_ID_WORDS)) - return -EFAULT; + if (mtip_get_identify(dd->port, (void __user *) arg) < 0) { + dev_warn(&dd->pdev->dev, + "Unable to read identity\n"); + return -EIO; + } + break; - } case HDIO_DRIVE_CMD: { u8 drive_command[4]; @@ -2564,58 +2537,40 @@ static ssize_t mtip_hw_show_registers(struct device *dev, int size = 0; int n; - size += sprintf(&buf[size], "Hardware\n--------\n"); - size += sprintf(&buf[size], "S ACTive : [ 0x"); + size += sprintf(&buf[size], "S ACTive:\n"); - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", readl(dd->port->s_active[n])); - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Command Issue : [ 0x"); + size += sprintf(&buf[size], "Command Issue:\n"); - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", readl(dd->port->cmd_issue[n])); - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Completed : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) - size += sprintf(&buf[size], "%08X ", - readl(dd->port->completed[n])); - - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", - readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", - readl(dd->mmio + HOST_IRQ_STAT)); - size += sprintf(&buf[size], "\n"); + size += sprintf(&buf[size], "Allocated:\n"); - size += sprintf(&buf[size], "Local\n-----\n"); - size += sprintf(&buf[size], "Allocated : [ 0x"); - - for (n = dd->slot_groups-1; n >= 0; n--) { + for (n = 0; n < dd->slot_groups; n++) { if (sizeof(long) > sizeof(u32)) group_allocated = dd->port->allocated[n/2] >> (32*(n&1)); else group_allocated = dd->port->allocated[n]; - size += sprintf(&buf[size], "%08X ", group_allocated); + size += sprintf(&buf[size], "0x%08x\n", + group_allocated); } - size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Commands in Q: [ 0x"); + size += sprintf(&buf[size], "Completed:\n"); - for (n = dd->slot_groups-1; n >= 0; n--) { - if (sizeof(long) > sizeof(u32)) - group_allocated = - dd->port->cmds_to_issue[n/2] >> (32*(n&1)); - else - group_allocated = dd->port->cmds_to_issue[n]; - size += sprintf(&buf[size], "%08X ", group_allocated); - } - size += sprintf(&buf[size], "]\n"); + for (n = 0; n < dd->slot_groups; n++) + size += sprintf(&buf[size], "0x%08x\n", + readl(dd->port->completed[n])); + + size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n", + readl(dd->port->mmio + PORT_IRQ_STAT)); + size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n", + readl(dd->mmio + HOST_IRQ_STAT)); return size; } @@ -2637,24 +2592,8 @@ static ssize_t mtip_hw_show_status(struct device *dev, return size; } -static ssize_t mtip_hw_show_flags(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; - - size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", - dd->port->flags); - size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", - dd->dd_flag); - - return size; -} - static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); -static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); /* * Create the sysfs related attributes. @@ -2677,9 +2616,6 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (sysfs_create_file(kobj, &dev_attr_status.attr)) dev_warn(&dd->pdev->dev, "Error creating 'status' sysfs entry\n"); - if (sysfs_create_file(kobj, &dev_attr_flags.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'flags' sysfs entry\n"); return 0; } @@ -2700,7 +2636,6 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) sysfs_remove_file(kobj, &dev_attr_registers.attr); sysfs_remove_file(kobj, &dev_attr_status.attr); - sysfs_remove_file(kobj, &dev_attr_flags.attr); return 0; } @@ -3699,10 +3634,7 @@ static int mtip_block_initialize(struct driver_data *dd) set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags); blk_queue_max_segments(dd->queue, MTIP_MAX_SG); blk_queue_physical_block_size(dd->queue, 4096); - blk_queue_max_hw_sectors(dd->queue, 0xffff); - blk_queue_max_segment_size(dd->queue, 0x400000); blk_queue_io_min(dd->queue, 4096); - /* * write back cache is not supported in the device. FUA depends on * write back cache support, hence setting flush support to zero. diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index b2c88da26b2a..4ef58336310a 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -113,35 +113,33 @@ #define __force_bit2int (unsigned int __force) -enum { - /* below are bit numbers in 'flags' defined in mtip_port */ - MTIP_PF_IC_ACTIVE_BIT = 0, /* pio/ioctl */ - MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ - MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ - MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ - MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ +/* below are bit numbers in 'flags' defined in mtip_port */ +#define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */ +#define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */ +#define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */ +#define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */ +#define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ (1 << MTIP_PF_EH_ACTIVE_BIT) | \ (1 << MTIP_PF_SE_ACTIVE_BIT) | \ - (1 << MTIP_PF_DM_ACTIVE_BIT)), - - MTIP_PF_SVC_THD_ACTIVE_BIT = 4, - MTIP_PF_ISSUE_CMDS_BIT = 5, - MTIP_PF_REBUILD_BIT = 6, - MTIP_PF_SVC_THD_STOP_BIT = 8, - - /* below are bit numbers in 'dd_flag' defined in driver_data */ - MTIP_DDF_REMOVE_PENDING_BIT = 1, - MTIP_DDF_OVER_TEMP_BIT = 2, - MTIP_DDF_WRITE_PROTECT_BIT = 3, - MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ + (1 << MTIP_PF_DM_ACTIVE_BIT)) + +#define MTIP_PF_SVC_THD_ACTIVE_BIT 4 +#define MTIP_PF_ISSUE_CMDS_BIT 5 +#define MTIP_PF_REBUILD_BIT 6 +#define MTIP_PF_SVC_THD_STOP_BIT 8 + +/* below are bit numbers in 'dd_flag' defined in driver_data */ +#define MTIP_DDF_REMOVE_PENDING_BIT 1 +#define MTIP_DDF_OVER_TEMP_BIT 2 +#define MTIP_DDF_WRITE_PROTECT_BIT 3 +#define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ (1 << MTIP_DDF_OVER_TEMP_BIT) | \ - (1 << MTIP_DDF_WRITE_PROTECT_BIT)), + (1 << MTIP_DDF_WRITE_PROTECT_BIT)) - MTIP_DDF_CLEANUP_BIT = 5, - MTIP_DDF_RESUME_BIT = 6, - MTIP_DDF_INIT_DONE_BIT = 7, - MTIP_DDF_REBUILD_FAILED_BIT = 8, -}; +#define MTIP_DDF_CLEANUP_BIT 5 +#define MTIP_DDF_RESUME_BIT 6 +#define MTIP_DDF_INIT_DONE_BIT 7 +#define MTIP_DDF_REBUILD_FAILED_BIT 8 __packed struct smart_attr{ u8 attr_id; diff --git a/trunk/drivers/edac/mce_amd.h b/trunk/drivers/edac/mce_amd.h index 8c87a5e87057..c6074c5cd1ef 100644 --- a/trunk/drivers/edac/mce_amd.h +++ b/trunk/drivers/edac/mce_amd.h @@ -5,6 +5,8 @@ #include +#define BIT_64(n) (U64_C(1) << (n)) + #define EC(x) ((x) & 0xffff) #define XEC(x, mask) (((x) >> 16) & mask) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 8e269178d6a5..4fba63e896d7 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -93,6 +93,11 @@ static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_n } +static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) +{ + return -EINVAL; +} + static const struct dma_buf_ops i915_dmabuf_ops = { .map_dma_buf = i915_gem_map_dma_buf, .unmap_dma_buf = i915_gem_unmap_dma_buf, @@ -101,6 +106,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = { .kmap_atomic = i915_gem_dmabuf_kmap_atomic, .kunmap = i915_gem_dmabuf_kunmap, .kunmap_atomic = i915_gem_dmabuf_kunmap_atomic, + .mmap = i915_gem_dmabuf_mmap, }; struct dma_buf *i915_gem_prime_export(struct drm_device *dev, diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 444143e5f28c..a5c591ffe395 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -6483,7 +6483,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) printk(MYIOC_s_INFO_FMT "%s: host reset in" " progress mpt_config timed out.!!\n", __func__, ioc->name); - mutex_unlock(&ioc->mptbase_cmds.mutex); return -EFAULT; } spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); diff --git a/trunk/drivers/net/ethernet/rdc/r6040.c b/trunk/drivers/net/ethernet/rdc/r6040.c index d1827e887f4e..4de73643fec6 100644 --- a/trunk/drivers/net/ethernet/rdc/r6040.c +++ b/trunk/drivers/net/ethernet/rdc/r6040.c @@ -1096,20 +1096,20 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out_disable_dev; + goto err_out; } err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { dev_err(&pdev->dev, "32-bit PCI DMA addresses" "not supported by the card\n"); - goto err_out_disable_dev; + goto err_out; } /* IO Size check */ if (pci_resource_len(pdev, bar) < io_size) { dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); err = -EIO; - goto err_out_disable_dev; + goto err_out; } pci_set_master(pdev); @@ -1117,7 +1117,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { err = -ENOMEM; - goto err_out_disable_dev; + goto err_out; } SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); @@ -1233,15 +1233,11 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, err_out_mdio: mdiobus_free(lp->mii_bus); err_out_unmap: - netif_napi_del(&lp->napi); - pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ioaddr); err_out_free_res: pci_release_regions(pdev); err_out_free_dev: free_netdev(dev); -err_out_disable_dev: - pci_disable_device(pdev); err_out: return err; } @@ -1255,9 +1251,6 @@ static void __devexit r6040_remove_one(struct pci_dev *pdev) mdiobus_unregister(lp->mii_bus); kfree(lp->mii_bus->irq); mdiobus_free(lp->mii_bus); - netif_napi_del(&lp->napi); - pci_set_drvdata(pdev, NULL); - pci_iounmap(pdev, lp->base); pci_release_regions(pdev); free_netdev(dev); pci_disable_device(pdev); diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index 667169b82526..be3c22179161 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -1101,12 +1101,8 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { - /* fix the values for the next receiving */ - mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - - sh_eth_read(ndev, RDLAR)) >> 4; + if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) sh_eth_write(ndev, EDRRR_R, EDRRR); - } return 0; } @@ -1203,6 +1199,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ ndev->stats.rx_over_errors++; + if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R) + sh_eth_write(ndev, EDRRR_R, EDRRR); if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } diff --git a/trunk/drivers/net/ethernet/smsc/smsc911x.c b/trunk/drivers/net/ethernet/smsc/smsc911x.c index 1466e5d2af44..dab9c6f671ec 100644 --- a/trunk/drivers/net/ethernet/smsc/smsc911x.c +++ b/trunk/drivers/net/ethernet/smsc/smsc911x.c @@ -2390,11 +2390,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = smsc911x_request_resources(pdev); if (retval) - goto out_request_resources_fail; + goto out_return_resources; retval = smsc911x_enable_resources(pdev); if (retval) - goto out_enable_resources_fail; + goto out_disable_resources; if (pdata->ioaddr == NULL) { SMSC_WARN(pdata, probe, "Error smsc911x base address invalid"); @@ -2501,9 +2501,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) free_irq(dev->irq, dev); out_disable_resources: (void)smsc911x_disable_resources(pdev); -out_enable_resources_fail: +out_return_resources: smsc911x_free_resources(pdev); -out_request_resources_fail: platform_set_drvdata(pdev, NULL); iounmap(pdata->ioaddr); free_netdev(dev); diff --git a/trunk/drivers/net/usb/asix.c b/trunk/drivers/net/usb/asix.c index 3ae80eccd0ef..71e2b0523bc2 100644 --- a/trunk/drivers/net/usb/asix.c +++ b/trunk/drivers/net/usb/asix.c @@ -35,7 +35,6 @@ #include #include #include -#include #define DRIVER_VERSION "22-Dec-2011" #define DRIVER_NAME "asix" @@ -322,7 +321,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; } - if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || + if ((size > dev->net->mtu + ETH_HLEN) || (size + offset > skb->len)) { netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", size); diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..380dbea6109d 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -547,8 +547,6 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ - {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ - {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ { } /* END */ }; MODULE_DEVICE_TABLE(usb, products); diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 5214b1eceb95..9ce6995e8d08 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -1231,6 +1231,11 @@ static int virtnet_freeze(struct virtio_device *vdev) vi->config_enable = false; mutex_unlock(&vi->config_lock); + virtqueue_disable_cb(vi->rvq); + virtqueue_disable_cb(vi->svq); + if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) + virtqueue_disable_cb(vi->cvq); + netif_device_detach(vi->dev); cancel_delayed_work_sync(&vi->refill); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index fbaa30930076..0ba81a66061f 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -2415,22 +2415,6 @@ ath5k_tx_complete_poll_work(struct work_struct *work) * Initialization routines * \*************************/ -static const struct ieee80211_iface_limit if_limits[] = { - { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) }, - { .max = 4, .types = -#ifdef CONFIG_MAC80211_MESH - BIT(NL80211_IFTYPE_MESH_POINT) | -#endif - BIT(NL80211_IFTYPE_AP) }, -}; - -static const struct ieee80211_iface_combination if_comb = { - .limits = if_limits, - .n_limits = ARRAY_SIZE(if_limits), - .max_interfaces = 2048, - .num_different_channels = 1, -}; - int __devinit ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) { @@ -2452,9 +2436,6 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->iface_combinations = &if_comb; - hw->wiphy->n_iface_combinations = 1; - /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index dfb0441f406c..ac53d901801d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3809,7 +3809,7 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) return true; } -void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) +static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 8396d150ce01..2505ac44f0c1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -334,7 +334,4 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, struct ath9k_channel *chan); - -void ar9003_hw_internal_regulator_apply(struct ath_hw *ah); - #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index 1bd3a3d22101..f11d9b2677fd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012 Qualcomm Atheros Inc. + * Copyright (c) 2011 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +18,7 @@ #define INITVALS_9330_1P1_H static const u32 ar9331_1p1_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, @@ -28,10 +27,10 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, - {0x00009e04, 0x00202020, 0x00202020, 0x00202020, 0x00202020}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31365d5e, 0x3136605e, 0x3136605e, 0x31365d5e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, @@ -56,7 +55,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, @@ -64,7 +63,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = { }; static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -156,7 +155,7 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, @@ -246,7 +245,7 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { }; static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -378,14 +377,14 @@ static const u32 ar9331_1p1_radio_core[][2] = { {0x000160b4, 0x92480040}, {0x000160c0, 0x006db6db}, {0x000160c4, 0x0186db60}, - {0x000160c8, 0x6db4db6c}, + {0x000160c8, 0x6db6db6c}, {0x000160cc, 0x6de6c300}, {0x000160d0, 0x14500820}, {0x00016100, 0x04cb0001}, {0x00016104, 0xfff80015}, {0x00016108, 0x00080010}, {0x0001610c, 0x00170000}, - {0x00016140, 0x10800000}, + {0x00016140, 0x10804000}, {0x00016144, 0x01884080}, {0x00016148, 0x000080c0}, {0x00016280, 0x01000015}, @@ -418,7 +417,7 @@ static const u32 ar9331_1p1_radio_core[][2] = { }; static const u32 ar9331_1p1_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, }; @@ -692,7 +691,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = { }; static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, @@ -784,7 +783,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { }; static const u32 ar9331_1p1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, @@ -974,27 +973,26 @@ static const u32 ar9331_1p1_mac_core[][2] = { static const u32 ar9331_common_rx_gain_1p1[][2] = { /* Addr allmodes */ - {0x00009e18, 0x05000000}, - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, - {0x0000a02c, 0x03850384}, - {0x0000a030, 0x03890388}, - {0x0000a034, 0x038b038a}, - {0x0000a038, 0x038d038c}, - {0x0000a03c, 0x03910390}, - {0x0000a040, 0x03930392}, - {0x0000a044, 0x03950394}, - {0x0000a048, 0x00000396}, - {0x0000a04c, 0x00000000}, + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, {0x0000a050, 0x00000000}, {0x0000a054, 0x00000000}, {0x0000a058, 0x00000000}, @@ -1007,15 +1005,15 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x28282828}, - {0x0000a084, 0x28282828}, - {0x0000a088, 0x28282828}, - {0x0000a08c, 0x28282828}, - {0x0000a090, 0x28282828}, - {0x0000a094, 0x24242428}, - {0x0000a098, 0x171e1e1e}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, {0x0000a0a4, 0x00000000}, {0x0000a0a8, 0x00000000}, {0x0000a0ac, 0x00000000}, @@ -1023,27 +1021,27 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x22072208}, - {0x0000a0c4, 0x22052206}, - {0x0000a0c8, 0x22032204}, - {0x0000a0cc, 0x22012202}, - {0x0000a0d0, 0x221f2200}, - {0x0000a0d4, 0x221d221e}, - {0x0000a0d8, 0x33023303}, - {0x0000a0dc, 0x33003301}, - {0x0000a0e0, 0x331e331f}, - {0x0000a0e4, 0x4402331d}, - {0x0000a0e8, 0x44004401}, - {0x0000a0ec, 0x441e441f}, - {0x0000a0f0, 0x55025503}, - {0x0000a0f4, 0x55005501}, - {0x0000a0f8, 0x551e551f}, - {0x0000a0fc, 0x6602551d}, - {0x0000a100, 0x66006601}, - {0x0000a104, 0x661e661f}, - {0x0000a108, 0x7703661d}, - {0x0000a10c, 0x77017702}, - {0x0000a110, 0x00007700}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, {0x0000a114, 0x00000000}, {0x0000a118, 0x00000000}, {0x0000a11c, 0x00000000}, @@ -1056,26 +1054,26 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a138, 0x00000000}, {0x0000a13c, 0x00000000}, {0x0000a140, 0x001f0000}, - {0x0000a144, 0x111f1100}, - {0x0000a148, 0x111d111e}, - {0x0000a14c, 0x111b111c}, - {0x0000a150, 0x22032204}, - {0x0000a154, 0x22012202}, - {0x0000a158, 0x221f2200}, - {0x0000a15c, 0x221d221e}, - {0x0000a160, 0x33013302}, - {0x0000a164, 0x331f3300}, - {0x0000a168, 0x4402331e}, - {0x0000a16c, 0x44004401}, - {0x0000a170, 0x441e441f}, - {0x0000a174, 0x55015502}, - {0x0000a178, 0x551f5500}, - {0x0000a17c, 0x6602551e}, - {0x0000a180, 0x66006601}, - {0x0000a184, 0x661e661f}, - {0x0000a188, 0x7703661d}, - {0x0000a18c, 0x77017702}, - {0x0000a190, 0x00007700}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, {0x0000a194, 0x00000000}, {0x0000a198, 0x00000000}, {0x0000a19c, 0x00000000}, @@ -1102,14 +1100,14 @@ static const u32 ar9331_common_rx_gain_1p1[][2] = { {0x0000a1f0, 0x00000396}, {0x0000a1f4, 0x00000396}, {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000296}, + {0x0000a1fc, 0x00000196}, }; static const u32 ar9331_common_tx_gain_offset1_1[][1] = { - {0x00000000}, - {0x00000003}, - {0x00000000}, - {0x00000000}, + {0}, + {3}, + {0}, + {0}, }; static const u32 ar9331_1p1_chansel_xtal_25M[] = { diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 7db1890448f2..abe05ec85d50 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1468,9 +1468,6 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, return false; ah->chip_fullsleep = false; - - if (AR_SREV_9330(ah)) - ar9003_hw_internal_regulator_apply(ah); ath9k_hw_init_pll(ah, chan); ath9k_hw_set_rfmode(ah, chan); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 4de4473776ac..dfa78e8b6470 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -239,7 +239,7 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - bool ret = true; + bool ret; ieee80211_stop_queues(sc->hw); @@ -250,10 +250,9 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) ath9k_debug_samp_bb_mac(sc); ath9k_hw_disable_interrupts(ah); - if (!ath_stoprecv(sc)) - ret = false; + ret = ath_drain_all_txq(sc, retry_tx); - if (!ath_drain_all_txq(sc, retry_tx)) + if (!ath_stoprecv(sc)) ret = false; if (!flush) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01d6cde..23eaa1b26ebe 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -64,8 +64,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb, - bool dequeue); + struct sk_buff *skb); enum { MCS_HT20, @@ -812,7 +811,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, fi = get_frame_info(skb); bf = fi->bf; if (!fi->bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); + bf = ath_tx_setup_buffer(sc, txq, tid, skb); if (!bf) continue; @@ -1727,7 +1726,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, return; } - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); if (!bf) return; @@ -1754,7 +1753,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, bf = fi->bf; if (!bf) - bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); + bf = ath_tx_setup_buffer(sc, txq, tid, skb); if (!bf) return; @@ -1815,8 +1814,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid, - struct sk_buff *skb, - bool dequeue) + struct sk_buff *skb) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_frame_info *fi = get_frame_info(skb); @@ -1865,8 +1863,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, return bf; error: - if (dequeue) - __skb_unlink(skb, &tid->buf_q); dev_kfree_skb_any(skb); return NULL; } @@ -1897,7 +1893,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, */ ath_tx_send_ampdu(sc, tid, skb, txctl); } else { - bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); + bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); if (!bf) return; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e7..c5a34ffe6459 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -1240,7 +1239,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) return -EINVAL; } - devinfo->image = vmalloc(fw->size); /* plus nvram */ + devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */ if (!devinfo->image) return -ENOMEM; @@ -1604,7 +1603,7 @@ static struct usb_driver brcmf_usbdrvr = { void brcmf_usb_exit(void) { usb_deregister(&brcmf_usbdrvr); - vfree(g_image.data); + kfree(g_image.data); g_image.data = NULL; g_image.len = 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig index 2463c0626438..db6c6e528022 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Kconfig +++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig @@ -137,3 +137,11 @@ config IWLWIFI_EXPERIMENTAL_MFP even if the microcode doesn't advertise it. Say Y only if you want to experiment with MFP. + +config IWLWIFI_UCODE16 + bool "support uCode 16.0" + depends on IWLWIFI + help + This option enables support for uCode version 16.0. + + Say Y if you want to use 16.0 microcode. diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index d615eacbf050..406f297a9a56 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -18,6 +18,7 @@ iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o +iwlwifi-$(CONFIG_IWLWIFI_UCODE16) += iwl-phy-db.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c index 8133105ac645..7f793417c787 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -79,7 +79,7 @@ static const struct iwl_base_params iwl2000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .shadow_reg_enable = true, .hd_v2 = true, }; @@ -97,7 +97,7 @@ static const struct iwl_base_params iwl2030_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .shadow_reg_enable = true, .hd_v2 = true, }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index 19f7ee84ae89..381b02cf339c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -86,7 +86,7 @@ static const struct iwl_base_params iwl6000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .shadow_reg_enable = true, }; static const struct iwl_base_params iwl6050_base_params = { @@ -102,7 +102,7 @@ static const struct iwl_base_params iwl6050_base_params = { .chain_noise_scale = 1500, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .shadow_reg_enable = true, }; static const struct iwl_base_params iwl6000_g2_base_params = { @@ -118,7 +118,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .shadow_reg_enable = true, }; static const struct iwl_ht_params iwl6000_ht_params = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8cebd7c363fc..51e1a69ffdda 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -884,7 +884,6 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; - priv->last_bt_traffic_load = priv->bt_traffic_load; /* Update uCode's rate table. */ tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index aea07aab3c9e..b31584e87bc7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -772,7 +772,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; - continue; + spin_unlock_bh(&priv->sta_lock); } /* * Rate scaling has already been initialized, send diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c index d742900969ea..3c72bad0ae56 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } -static int iwl_alloc_ucode(struct iwl_drv *drv, - struct iwl_firmware_pieces *pieces, - enum iwl_ucode_type type) +static int alloc_pci_desc(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) { int i; for (i = 0; i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); i++) if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), - get_sec(pieces, type, i))) - return -ENOMEM; + get_sec(pieces, type, i))) + return -1; return 0; } @@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) - if (iwl_alloc_ucode(drv, &pieces, i)) - goto out_free_fw; + if (alloc_pci_desc(drv, &pieces, i)) + goto err_pci_alloc; /* Now that we can no longer fail, copy information */ @@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) - goto out_free_fw; + goto out_unbind; return; @@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto out_unbind; return; - out_free_fw: + err_pci_alloc: IWL_ERR(drv, "failed to allocate pci memory\n"); iwl_dealloc_ucode(drv); release_firmware(ucode_raw); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c new file mode 100644 index 000000000000..f166955340fe --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -0,0 +1,288 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include + +#include "iwl-debug.h" +#include "iwl-dev.h" + +#include "iwl-phy-db.h" + +#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ + +struct iwl_phy_db *iwl_phy_db_init(struct device *dev) +{ + struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), + GFP_KERNEL); + + if (!phy_db) + return phy_db; + + phy_db->dev = dev; + + /* TODO: add default values of the phy db. */ + return phy_db; +} + +/* + * get phy db section: returns a pointer to a phy db section specified by + * type and channel group id. + */ +static struct iwl_phy_db_entry * +iwl_phy_db_get_section(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, + u16 chg_id) +{ + if (!phy_db || type < 0 || type >= IWL_PHY_DB_MAX) + return NULL; + + switch (type) { + case IWL_PHY_DB_CFG: + return &phy_db->cfg; + case IWL_PHY_DB_CALIB_NCH: + return &phy_db->calib_nch; + case IWL_PHY_DB_CALIB_CH: + return &phy_db->calib_ch; + case IWL_PHY_DB_CALIB_CHG_PAPD: + if (chg_id < 0 || chg_id >= IWL_NUM_PAPD_CH_GROUPS) + return NULL; + return &phy_db->calib_ch_group_papd[chg_id]; + case IWL_PHY_DB_CALIB_CHG_TXP: + if (chg_id < 0 || chg_id >= IWL_NUM_TXP_CH_GROUPS) + return NULL; + return &phy_db->calib_ch_group_txp[chg_id]; + default: + return NULL; + } + return NULL; +} + +static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, + u16 chg_id) +{ + struct iwl_phy_db_entry *entry = + iwl_phy_db_get_section(phy_db, type, chg_id); + if (!entry) + return; + + kfree(entry->data); + entry->data = NULL; + entry->size = 0; +} + +void iwl_phy_db_free(struct iwl_phy_db *phy_db) +{ + int i; + + if (!phy_db) + return; + + iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0); + iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0); + iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0); + for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++) + iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i); + for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) + iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i); + + kfree(phy_db); +} + +int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, u8 *data, + u16 size, gfp_t alloc_ctx) +{ + struct iwl_phy_db_entry *entry; + u16 chg_id = 0; + + if (!phy_db) + return -EINVAL; + + if (type == IWL_PHY_DB_CALIB_CHG_PAPD || + type == IWL_PHY_DB_CALIB_CHG_TXP) + chg_id = le16_to_cpup((__le16 *)data); + + entry = iwl_phy_db_get_section(phy_db, type, chg_id); + if (!entry) + return -EINVAL; + + kfree(entry->data); + entry->data = kmemdup(data, size, alloc_ctx); + if (!entry->data) { + entry->size = 0; + return -ENOMEM; + } + + entry->size = size; + + if (type == IWL_PHY_DB_CALIB_CH) { + phy_db->channel_num = le32_to_cpup((__le32 *)data); + phy_db->channel_size = + (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; + } + + return 0; +} + +static int is_valid_channel(u16 ch_id) +{ + if (ch_id <= 14 || + (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) || + (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) || + (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1)) + return 1; + return 0; +} + +static u8 ch_id_to_ch_index(u16 ch_id) +{ + if (WARN_ON(!is_valid_channel(ch_id))) + return 0xff; + + if (ch_id <= 14) + return ch_id - 1; + if (ch_id <= 64) + return (ch_id + 20) / 4; + if (ch_id <= 140) + return (ch_id - 12) / 4; + return (ch_id - 13) / 4; +} + + +static u16 channel_id_to_papd(u16 ch_id) +{ + if (WARN_ON(!is_valid_channel(ch_id))) + return 0xff; + + if (1 <= ch_id && ch_id <= 14) + return 0; + if (36 <= ch_id && ch_id <= 64) + return 1; + if (100 <= ch_id && ch_id <= 140) + return 2; + return 3; +} + +static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) +{ + struct iwl_phy_db_chg_txp *txp_chg; + int i; + u8 ch_index = ch_id_to_ch_index(ch_id); + if (ch_index == 0xff) + return 0xff; + + for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) { + txp_chg = (void *)phy_db->calib_ch_group_txp[i].data; + if (!txp_chg) + return 0xff; + /* + * Looking for the first channel group that its max channel is + * higher then wanted channel. + */ + if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index) + return i; + } + return 0xff; +} + +int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, u8 **data, + u16 *size, u16 ch_id) +{ + struct iwl_phy_db_entry *entry; + u32 channel_num; + u32 channel_size; + u16 ch_group_id = 0; + u16 index; + + if (!phy_db) + return -EINVAL; + + /* find wanted channel group */ + if (type == IWL_PHY_DB_CALIB_CHG_PAPD) + ch_group_id = channel_id_to_papd(ch_id); + else if (type == IWL_PHY_DB_CALIB_CHG_TXP) + ch_group_id = channel_id_to_txp(phy_db, ch_id); + + entry = iwl_phy_db_get_section(phy_db, type, ch_group_id); + if (!entry) + return -EINVAL; + + if (type == IWL_PHY_DB_CALIB_CH) { + index = ch_id_to_ch_index(ch_id); + channel_num = phy_db->channel_num; + channel_size = phy_db->channel_size; + if (index >= channel_num) { + IWL_ERR(phy_db, "Wrong channel number %d", ch_id); + return -EINVAL; + } + *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size; + *size = channel_size; + } else { + *data = entry->data; + *size = entry->size; + } + return 0; +} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.h new file mode 100644 index 000000000000..c34c6a9303ab --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-phy-db.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#ifndef __IWL_PHYDB_H__ +#define __IWL_PHYDB_H__ + +#include + +#define IWL_NUM_PAPD_CH_GROUPS 4 +#define IWL_NUM_TXP_CH_GROUPS 8 + +struct iwl_phy_db_entry { + u16 size; + u8 *data; +}; + +struct iwl_shared; + +/** + * struct iwl_phy_db - stores phy configuration and calibration data. + * + * @cfg: phy configuration. + * @calib_nch: non channel specific calibration data. + * @calib_ch: channel specific calibration data. + * @calib_ch_group_papd: calibration data related to papd channel group. + * @calib_ch_group_txp: calibration data related to tx power chanel group. + */ +struct iwl_phy_db { + struct iwl_phy_db_entry cfg; + struct iwl_phy_db_entry calib_nch; + struct iwl_phy_db_entry calib_ch; + struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS]; + struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS]; + + u32 channel_num; + u32 channel_size; + + /* for an access to the logger */ + struct device *dev; +}; + +enum iwl_phy_db_section_type { + IWL_PHY_DB_CFG = 1, + IWL_PHY_DB_CALIB_NCH, + IWL_PHY_DB_CALIB_CH, + IWL_PHY_DB_CALIB_CHG_PAPD, + IWL_PHY_DB_CALIB_CHG_TXP, + IWL_PHY_DB_MAX +}; + +/* for parsing of tx power channel group data that comes from the firmware*/ +struct iwl_phy_db_chg_txp { + __le32 space; + __le16 max_channel_idx; +} __packed; + +struct iwl_phy_db *iwl_phy_db_init(struct device *dev); + +void iwl_phy_db_free(struct iwl_phy_db *phy_db); + +int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, u8 *data, + u16 size, gfp_t alloc_ctx); + +int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, + enum iwl_phy_db_section_type type, u8 **data, + u16 *size, u16 ch_id); + +#endif /* __IWL_PHYDB_H__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index e959207c630a..6213c05a4b52 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -347,7 +347,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - enum dma_data_direction dma_dir); + int index, enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs); int iwl_queue_space(const struct iwl_queue *q); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index a8750238ee09..21a8a672fbb2 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -204,39 +204,33 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); - - tfd->num_tbs = 0; } /** * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @trans - transport private data * @txq - tx queue - * @dma_dir - the direction of the DMA mapping + * @index - the index of the TFD to be freed + *@dma_dir - the direction of the DMA mapping * * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - enum dma_data_direction dma_dir) + int index, enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; - /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ - int rd_ptr = txq->q.read_ptr; - int idx = get_cmd_index(&txq->q, rd_ptr); - lockdep_assert_held(&txq->lock); - /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwlagn_unmap_tfd(trans, &txq->entries[idx].meta, - &tfd_tmp[rd_ptr], dma_dir); + iwlagn_unmap_tfd(trans, &txq->entries[index].meta, + &tfd_tmp[index], dma_dir); /* free SKB */ if (txq->entries) { struct sk_buff *skb; - skb = txq->entries[idx].skb; + skb = txq->entries[index].skb; /* Can be called from irqs-disabled context * If skb is not NULL, it means that the whole queue is being @@ -244,7 +238,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, */ if (skb) { iwl_op_mode_free_skb(trans->op_mode, skb); - txq->entries[idx].skb = NULL; + txq->entries[index].skb = NULL; } } } @@ -979,7 +973,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE); + iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); freed++; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec6fb395b84d..2e57161854b9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -435,7 +435,9 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - iwlagn_txq_free_tfd(trans, txq, dma_dir); + /* The read_ptr needs to bound by q->n_window */ + iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), + dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); diff --git a/trunk/drivers/net/wireless/ti/wl1251/sdio.c b/trunk/drivers/net/wireless/ti/wl1251/sdio.c index e2750a12c6f1..1b851f650e07 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/sdio.c +++ b/trunk/drivers/net/wireless/ti/wl1251/sdio.c @@ -260,7 +260,6 @@ static int wl1251_sdio_probe(struct sdio_func *func, } if (wl->irq) { - irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -268,6 +267,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; diff --git a/trunk/drivers/net/wireless/ti/wl1251/spi.c b/trunk/drivers/net/wireless/ti/wl1251/spi.c index 87f6305bda2c..6248c354fc5c 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/spi.c +++ b/trunk/drivers/net/wireless/ti/wl1251/spi.c @@ -281,7 +281,6 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) wl->use_eeprom = pdata->use_eeprom; - irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); @@ -290,6 +289,8 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + disable_irq(wl->irq); + ret = wl1251_init_ieee80211(wl); if (ret) goto out_irq; diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.c b/trunk/drivers/net/wireless/ti/wlcore/acx.c index f3d6fa508269..509aa881d790 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.c @@ -1715,7 +1715,6 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl) } -#ifdef CONFIG_PM /* Set the global behaviour of RX filters - On/Off + default action */ int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action) @@ -1795,4 +1794,3 @@ int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, kfree(acx); return ret; } -#endif /* CONFIG_PM */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.h b/trunk/drivers/net/wireless/ti/wlcore/acx.h index e6a74869a5ff..8106b2ebfe60 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.h @@ -1330,11 +1330,9 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_fm_coex(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); int wl12xx_acx_config_hangover(struct wl1271 *wl); - -#ifdef CONFIG_PM int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, enum rx_filter_action action); int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable, struct wl12xx_rx_filter *filter); -#endif /* CONFIG_PM */ + #endif /* __WL1271_ACX_H__ */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/rx.c b/trunk/drivers/net/wireless/ti/wlcore/rx.c index d6a3c6b07827..1f1d9488dfb6 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/rx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/rx.c @@ -279,7 +279,6 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) wl12xx_rearm_rx_streaming(wl, active_hlids); } -#ifdef CONFIG_PM int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, struct wl12xx_rx_filter *filter) @@ -315,4 +314,3 @@ void wl1271_rx_filter_clear_all(struct wl1271 *wl) wl1271_rx_filter_enable(wl, i, 0, NULL); } } -#endif /* CONFIG_PM */ diff --git a/trunk/drivers/net/xen-netback/netback.c b/trunk/drivers/net/xen-netback/netback.c index f4a6fcaeffb1..2596401308a8 100644 --- a/trunk/drivers/net/xen-netback/netback.c +++ b/trunk/drivers/net/xen-netback/netback.c @@ -325,7 +325,8 @@ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) unsigned int count; int i, copy_off; - count = DIV_ROUND_UP(skb_headlen(skb), PAGE_SIZE); + count = DIV_ROUND_UP( + offset_in_page(skb->data)+skb_headlen(skb), PAGE_SIZE); copy_off = skb_headlen(skb) % PAGE_SIZE; diff --git a/trunk/drivers/nfc/pn544_hci.c b/trunk/drivers/nfc/pn544_hci.c index 281f18c2fb82..46f4a9f9f5e4 100644 --- a/trunk/drivers/nfc/pn544_hci.c +++ b/trunk/drivers/nfc/pn544_hci.c @@ -232,7 +232,7 @@ static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) static int check_crc(u8 *buf, int buflen) { - int len; + u8 len; u16 crc; len = buf[0] + 1; diff --git a/trunk/drivers/power/Kconfig b/trunk/drivers/power/Kconfig index e3a3b4956f08..99dc29f2f2f2 100644 --- a/trunk/drivers/power/Kconfig +++ b/trunk/drivers/power/Kconfig @@ -1,5 +1,5 @@ menuconfig POWER_SUPPLY - bool "Power supply class support" + tristate "Power supply class support" help Say Y here to enable power supply class support. This allows power supply (batteries, AC, USB) monitoring by userspace @@ -77,7 +77,7 @@ config BATTERY_DS2780 Say Y here to enable support for batteries with ds2780 chip. config BATTERY_DS2781 - tristate "DS2781 battery driver" + tristate "2781 battery driver" depends on HAS_IOMEM select W1 select W1_SLAVE_DS2781 @@ -181,15 +181,14 @@ config BATTERY_MAX17040 to operate with a single lithium cell config BATTERY_MAX17042 - tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge" + tristate "Maxim MAX17042/8997/8966 Fuel Gauge" depends on I2C help MAX17042 is fuel-gauge systems for lithium-ion (Li+) batteries in handheld and portable equipment. The MAX17042 is configured to operate with a single lithium cell. MAX8997 and MAX8966 are multi-function devices that include fuel gauages that are compatible - with MAX17042. This driver also supports max17047/50 chips which are - improved version of max17042. + with MAX17042. config BATTERY_Z2 tristate "Z2 battery driver" @@ -292,7 +291,6 @@ config CHARGER_MAX8998 config CHARGER_SMB347 tristate "Summit Microelectronics SMB347 Battery Charger" depends on I2C - select REGMAP_I2C help Say Y to include support for Summit Microelectronics SMB347 Battery Charger. diff --git a/trunk/drivers/power/ab8500_btemp.c b/trunk/drivers/power/ab8500_btemp.c index bba3ccac72fe..d8bb99394ac0 100644 --- a/trunk/drivers/power/ab8500_btemp.c +++ b/trunk/drivers/power/ab8500_btemp.c @@ -964,15 +964,10 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev) { int irq, i, ret = 0; u8 val; - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; - struct ab8500_btemp *di; - - if (!plat_data) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } + struct abx500_bm_plat_data *plat_data; - di = kzalloc(sizeof(*di), GFP_KERNEL); + struct ab8500_btemp *di = + kzalloc(sizeof(struct ab8500_btemp), GFP_KERNEL); if (!di) return -ENOMEM; @@ -982,6 +977,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev) di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); /* get btemp specific platform data */ + plat_data = pdev->dev.platform_data; di->pdata = plat_data->btemp; if (!di->pdata) { dev_err(di->dev, "no btemp platform data supplied\n"); diff --git a/trunk/drivers/power/ab8500_charger.c b/trunk/drivers/power/ab8500_charger.c index d2303d0b7c75..e2b4accbec88 100644 --- a/trunk/drivers/power/ab8500_charger.c +++ b/trunk/drivers/power/ab8500_charger.c @@ -2534,15 +2534,10 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev) static int __devinit ab8500_charger_probe(struct platform_device *pdev) { int irq, i, charger_status, ret = 0; - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; - struct ab8500_charger *di; - - if (!plat_data) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } + struct abx500_bm_plat_data *plat_data; - di = kzalloc(sizeof(*di), GFP_KERNEL); + struct ab8500_charger *di = + kzalloc(sizeof(struct ab8500_charger), GFP_KERNEL); if (!di) return -ENOMEM; @@ -2555,7 +2550,9 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev) spin_lock_init(&di->usb_state.usb_lock); /* get charger specific platform data */ + plat_data = pdev->dev.platform_data; di->pdata = plat_data->charger; + if (!di->pdata) { dev_err(di->dev, "no charger platform data supplied\n"); ret = -EINVAL; diff --git a/trunk/drivers/power/ab8500_fg.c b/trunk/drivers/power/ab8500_fg.c index bf022255994c..c22f2f05657e 100644 --- a/trunk/drivers/power/ab8500_fg.c +++ b/trunk/drivers/power/ab8500_fg.c @@ -2446,15 +2446,10 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev) { int i, irq; int ret = 0; - struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data; - struct ab8500_fg *di; - - if (!plat_data) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } + struct abx500_bm_plat_data *plat_data; - di = kzalloc(sizeof(*di), GFP_KERNEL); + struct ab8500_fg *di = + kzalloc(sizeof(struct ab8500_fg), GFP_KERNEL); if (!di) return -ENOMEM; @@ -2466,6 +2461,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev) di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); /* get fg specific platform data */ + plat_data = pdev->dev.platform_data; di->pdata = plat_data->fg; if (!di->pdata) { dev_err(di->dev, "no fg platform data supplied\n"); diff --git a/trunk/drivers/power/charger-manager.c b/trunk/drivers/power/charger-manager.c index 86935ec18954..9eca9f1ff0ea 100644 --- a/trunk/drivers/power/charger-manager.c +++ b/trunk/drivers/power/charger-manager.c @@ -23,16 +23,6 @@ #include #include -static const char * const default_event_names[] = { - [CM_EVENT_UNKNOWN] = "Unknown", - [CM_EVENT_BATT_FULL] = "Battery Full", - [CM_EVENT_BATT_IN] = "Battery Inserted", - [CM_EVENT_BATT_OUT] = "Battery Pulled Out", - [CM_EVENT_EXT_PWR_IN_OUT] = "External Power Attach/Detach", - [CM_EVENT_CHG_START_STOP] = "Charging Start/Stop", - [CM_EVENT_OTHERS] = "Other battery events" -}; - /* * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for * delayed works so that we can run delayed works with CM_JIFFIES_SMALL @@ -67,12 +57,6 @@ static bool cm_suspended; static bool cm_rtc_set; static unsigned long cm_suspend_duration_ms; -/* About normal (not suspended) monitoring */ -static unsigned long polling_jiffy = ULONG_MAX; /* ULONG_MAX: no polling */ -static unsigned long next_polling; /* Next appointed polling time */ -static struct workqueue_struct *cm_wq; /* init at driver add */ -static struct delayed_work cm_monitor_work; /* init at driver add */ - /* Global charger-manager description */ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */ @@ -87,11 +71,6 @@ static bool is_batt_present(struct charger_manager *cm) int i, ret; switch (cm->desc->battery_present) { - case CM_BATTERY_PRESENT: - present = true; - break; - case CM_NO_BATTERY: - break; case CM_FUEL_GAUGE: ret = cm->fuel_gauge->get_property(cm->fuel_gauge, POWER_SUPPLY_PROP_PRESENT, &val); @@ -299,26 +278,6 @@ static int try_charger_enable(struct charger_manager *cm, bool enable) return err; } -/** - * try_charger_restart - Restart charging. - * @cm: the Charger Manager representing the battery. - * - * Restart charging by turning off and on the charger. - */ -static int try_charger_restart(struct charger_manager *cm) -{ - int err; - - if (cm->emergency_stop) - return -EAGAIN; - - err = try_charger_enable(cm, false); - if (err) - return err; - - return try_charger_enable(cm, true); -} - /** * uevent_notify - Let users know something has changed. * @cm: the Charger Manager representing the battery. @@ -374,46 +333,6 @@ static void uevent_notify(struct charger_manager *cm, const char *event) dev_info(cm->dev, event); } -/** - * fullbatt_vchk - Check voltage drop some times after "FULL" event. - * @work: the work_struct appointing the function - * - * If a user has designated "fullbatt_vchkdrop_ms/uV" values with - * charger_desc, Charger Manager checks voltage drop after the battery - * "FULL" event. It checks whether the voltage has dropped more than - * fullbatt_vchkdrop_uV by calling this function after fullbatt_vchkrop_ms. - */ -static void fullbatt_vchk(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct charger_manager *cm = container_of(dwork, - struct charger_manager, fullbatt_vchk_work); - struct charger_desc *desc = cm->desc; - int batt_uV, err, diff; - - /* remove the appointment for fullbatt_vchk */ - cm->fullbatt_vchk_jiffies_at = 0; - - if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms) - return; - - err = get_batt_uV(cm, &batt_uV); - if (err) { - dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err); - return; - } - - diff = cm->fullbatt_vchk_uV; - diff -= batt_uV; - - dev_dbg(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); - - if (diff > desc->fullbatt_vchkdrop_uV) { - try_charger_restart(cm); - uevent_notify(cm, "Recharge"); - } -} - /** * _cm_monitor - Monitor the temperature and return true for exceptions. * @cm: the Charger Manager representing the battery. @@ -473,131 +392,6 @@ static bool cm_monitor(void) return stop; } -/** - * _setup_polling - Setup the next instance of polling. - * @work: work_struct of the function _setup_polling. - */ -static void _setup_polling(struct work_struct *work) -{ - unsigned long min = ULONG_MAX; - struct charger_manager *cm; - bool keep_polling = false; - unsigned long _next_polling; - - mutex_lock(&cm_list_mtx); - - list_for_each_entry(cm, &cm_list, entry) { - if (is_polling_required(cm) && cm->desc->polling_interval_ms) { - keep_polling = true; - - if (min > cm->desc->polling_interval_ms) - min = cm->desc->polling_interval_ms; - } - } - - polling_jiffy = msecs_to_jiffies(min); - if (polling_jiffy <= CM_JIFFIES_SMALL) - polling_jiffy = CM_JIFFIES_SMALL + 1; - - if (!keep_polling) - polling_jiffy = ULONG_MAX; - if (polling_jiffy == ULONG_MAX) - goto out; - - WARN(cm_wq == NULL, "charger-manager: workqueue not initialized" - ". try it later. %s\n", __func__); - - _next_polling = jiffies + polling_jiffy; - - if (!delayed_work_pending(&cm_monitor_work) || - (delayed_work_pending(&cm_monitor_work) && - time_after(next_polling, _next_polling))) { - cancel_delayed_work_sync(&cm_monitor_work); - next_polling = jiffies + polling_jiffy; - queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy); - } - -out: - mutex_unlock(&cm_list_mtx); -} -static DECLARE_WORK(setup_polling, _setup_polling); - -/** - * cm_monitor_poller - The Monitor / Poller. - * @work: work_struct of the function cm_monitor_poller - * - * During non-suspended state, cm_monitor_poller is used to poll and monitor - * the batteries. - */ -static void cm_monitor_poller(struct work_struct *work) -{ - cm_monitor(); - schedule_work(&setup_polling); -} - -/** - * fullbatt_handler - Event handler for CM_EVENT_BATT_FULL - * @cm: the Charger Manager representing the battery. - */ -static void fullbatt_handler(struct charger_manager *cm) -{ - struct charger_desc *desc = cm->desc; - - if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms) - goto out; - - if (cm_suspended) - device_set_wakeup_capable(cm->dev, true); - - if (delayed_work_pending(&cm->fullbatt_vchk_work)) - cancel_delayed_work(&cm->fullbatt_vchk_work); - queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work, - msecs_to_jiffies(desc->fullbatt_vchkdrop_ms)); - cm->fullbatt_vchk_jiffies_at = jiffies + msecs_to_jiffies( - desc->fullbatt_vchkdrop_ms); - - if (cm->fullbatt_vchk_jiffies_at == 0) - cm->fullbatt_vchk_jiffies_at = 1; - -out: - dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n"); - uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]); -} - -/** - * battout_handler - Event handler for CM_EVENT_BATT_OUT - * @cm: the Charger Manager representing the battery. - */ -static void battout_handler(struct charger_manager *cm) -{ - if (cm_suspended) - device_set_wakeup_capable(cm->dev, true); - - if (!is_batt_present(cm)) { - dev_emerg(cm->dev, "Battery Pulled Out!\n"); - uevent_notify(cm, default_event_names[CM_EVENT_BATT_OUT]); - } else { - uevent_notify(cm, "Battery Reinserted?"); - } -} - -/** - * misc_event_handler - Handler for other evnets - * @cm: the Charger Manager representing the battery. - * @type: the Charger Manager representing the battery. - */ -static void misc_event_handler(struct charger_manager *cm, - enum cm_event_types type) -{ - if (cm_suspended) - device_set_wakeup_capable(cm->dev, true); - - if (!delayed_work_pending(&cm_monitor_work) && - is_polling_required(cm) && cm->desc->polling_interval_ms) - schedule_work(&setup_polling); - uevent_notify(cm, default_event_names[type]); -} - static int charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -819,21 +613,6 @@ static bool cm_setup_timer(void) mutex_lock(&cm_list_mtx); list_for_each_entry(cm, &cm_list, entry) { - unsigned int fbchk_ms = 0; - - /* fullbatt_vchk is required. setup timer for that */ - if (cm->fullbatt_vchk_jiffies_at) { - fbchk_ms = jiffies_to_msecs(cm->fullbatt_vchk_jiffies_at - - jiffies); - if (time_is_before_eq_jiffies( - cm->fullbatt_vchk_jiffies_at) || - msecs_to_jiffies(fbchk_ms) < CM_JIFFIES_SMALL) { - fullbatt_vchk(&cm->fullbatt_vchk_work.work); - fbchk_ms = 0; - } - } - CM_MIN_VALID(wakeup_ms, fbchk_ms); - /* Skip if polling is not required for this CM */ if (!is_polling_required(cm) && !cm->emergency_stop) continue; @@ -893,23 +672,6 @@ static bool cm_setup_timer(void) return false; } -static void _cm_fbchk_in_suspend(struct charger_manager *cm) -{ - unsigned long jiffy_now = jiffies; - - if (!cm->fullbatt_vchk_jiffies_at) - return; - - if (g_desc && g_desc->assume_timer_stops_in_suspend) - jiffy_now += msecs_to_jiffies(cm_suspend_duration_ms); - - /* Execute now if it's going to be executed not too long after */ - jiffy_now += CM_JIFFIES_SMALL; - - if (time_after_eq(jiffy_now, cm->fullbatt_vchk_jiffies_at)) - fullbatt_vchk(&cm->fullbatt_vchk_work.work); -} - /** * cm_suspend_again - Determine whether suspend again or not * @@ -931,8 +693,6 @@ bool cm_suspend_again(void) ret = true; mutex_lock(&cm_list_mtx); list_for_each_entry(cm, &cm_list, entry) { - _cm_fbchk_in_suspend(cm); - if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) || cm->status_save_batt != is_batt_present(cm)) { ret = false; @@ -1036,21 +796,6 @@ static int charger_manager_probe(struct platform_device *pdev) memcpy(cm->desc, desc, sizeof(struct charger_desc)); cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */ - /* - * The following two do not need to be errors. - * Users may intentionally ignore those two features. - */ - if (desc->fullbatt_uV == 0) { - dev_info(&pdev->dev, "Ignoring full-battery voltage threshold" - " as it is not supplied."); - } - if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) { - dev_info(&pdev->dev, "Disabling full-battery voltage drop " - "checking mechanism as it is not supplied."); - desc->fullbatt_vchkdrop_ms = 0; - desc->fullbatt_vchkdrop_uV = 0; - } - if (!desc->charger_regulators || desc->num_charger_regulators < 1) { ret = -EINVAL; dev_err(&pdev->dev, "charger_regulators undefined.\n"); @@ -1158,8 +903,6 @@ static int charger_manager_probe(struct platform_device *pdev) cm->charger_psy.num_properties++; } - INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk); - ret = power_supply_register(NULL, &cm->charger_psy); if (ret) { dev_err(&pdev->dev, "Cannot register charger-manager with" @@ -1185,15 +928,6 @@ static int charger_manager_probe(struct platform_device *pdev) list_add(&cm->entry, &cm_list); mutex_unlock(&cm_list_mtx); - /* - * Charger-manager is capable of waking up the systme from sleep - * when event is happend through cm_notify_event() - */ - device_init_wakeup(&pdev->dev, true); - device_set_wakeup_capable(&pdev->dev, false); - - schedule_work(&setup_polling); - return 0; err_chg_enable: @@ -1224,17 +958,9 @@ static int __devexit charger_manager_remove(struct platform_device *pdev) list_del(&cm->entry); mutex_unlock(&cm_list_mtx); - if (work_pending(&setup_polling)) - cancel_work_sync(&setup_polling); - if (delayed_work_pending(&cm_monitor_work)) - cancel_delayed_work_sync(&cm_monitor_work); - regulator_bulk_free(desc->num_charger_regulators, desc->charger_regulators); power_supply_unregister(&cm->charger_psy); - - try_charger_enable(cm, false); - kfree(cm->charger_psy.properties); kfree(cm->charger_stat); kfree(cm->desc); @@ -1249,18 +975,6 @@ static const struct platform_device_id charger_manager_id[] = { }; MODULE_DEVICE_TABLE(platform, charger_manager_id); -static int cm_suspend_noirq(struct device *dev) -{ - int ret = 0; - - if (device_may_wakeup(dev)) { - device_set_wakeup_capable(dev, false); - ret = -EAGAIN; - } - - return ret; -} - static int cm_suspend_prepare(struct device *dev) { struct charger_manager *cm = dev_get_drvdata(dev); @@ -1286,8 +1000,6 @@ static int cm_suspend_prepare(struct device *dev) cm_suspended = true; } - if (delayed_work_pending(&cm->fullbatt_vchk_work)) - cancel_delayed_work(&cm->fullbatt_vchk_work); cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm); cm->status_save_batt = is_batt_present(cm); @@ -1315,40 +1027,11 @@ static void cm_suspend_complete(struct device *dev) cm_rtc_set = false; } - /* Re-enqueue delayed work (fullbatt_vchk_work) */ - if (cm->fullbatt_vchk_jiffies_at) { - unsigned long delay = 0; - unsigned long now = jiffies + CM_JIFFIES_SMALL; - - if (time_after_eq(now, cm->fullbatt_vchk_jiffies_at)) { - delay = (unsigned long)((long)now - - (long)(cm->fullbatt_vchk_jiffies_at)); - delay = jiffies_to_msecs(delay); - } else { - delay = 0; - } - - /* - * Account for cm_suspend_duration_ms if - * assume_timer_stops_in_suspend is active - */ - if (g_desc && g_desc->assume_timer_stops_in_suspend) { - if (delay > cm_suspend_duration_ms) - delay -= cm_suspend_duration_ms; - else - delay = 0; - } - - queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work, - msecs_to_jiffies(delay)); - } - device_set_wakeup_capable(cm->dev, false); uevent_notify(cm, NULL); } static const struct dev_pm_ops charger_manager_pm = { .prepare = cm_suspend_prepare, - .suspend_noirq = cm_suspend_noirq, .complete = cm_suspend_complete, }; @@ -1365,91 +1048,16 @@ static struct platform_driver charger_manager_driver = { static int __init charger_manager_init(void) { - cm_wq = create_freezable_workqueue("charger_manager"); - INIT_DELAYED_WORK(&cm_monitor_work, cm_monitor_poller); - return platform_driver_register(&charger_manager_driver); } late_initcall(charger_manager_init); static void __exit charger_manager_cleanup(void) { - destroy_workqueue(cm_wq); - cm_wq = NULL; - platform_driver_unregister(&charger_manager_driver); } module_exit(charger_manager_cleanup); -/** - * find_power_supply - find the associated power_supply of charger - * @cm: the Charger Manager representing the battery - * @psy: pointer to instance of charger's power_supply - */ -static bool find_power_supply(struct charger_manager *cm, - struct power_supply *psy) -{ - int i; - bool found = false; - - for (i = 0; cm->charger_stat[i]; i++) { - if (psy == cm->charger_stat[i]) { - found = true; - break; - } - } - - return found; -} - -/** - * cm_notify_event - charger driver notify Charger Manager of charger event - * @psy: pointer to instance of charger's power_supply - * @type: type of charger event - * @msg: optional message passed to uevent_notify fuction - */ -void cm_notify_event(struct power_supply *psy, enum cm_event_types type, - char *msg) -{ - struct charger_manager *cm; - bool found_power_supply = false; - - if (psy == NULL) - return; - - mutex_lock(&cm_list_mtx); - list_for_each_entry(cm, &cm_list, entry) { - found_power_supply = find_power_supply(cm, psy); - if (found_power_supply) - break; - } - mutex_unlock(&cm_list_mtx); - - if (!found_power_supply) - return; - - switch (type) { - case CM_EVENT_BATT_FULL: - fullbatt_handler(cm); - break; - case CM_EVENT_BATT_OUT: - battout_handler(cm); - break; - case CM_EVENT_BATT_IN: - case CM_EVENT_EXT_PWR_IN_OUT ... CM_EVENT_CHG_START_STOP: - misc_event_handler(cm, type); - break; - case CM_EVENT_UNKNOWN: - case CM_EVENT_OTHERS: - uevent_notify(cm, msg ? msg : default_event_names[type]); - break; - default: - dev_err(cm->dev, "%s type not specified.\n", __func__); - break; - } -} -EXPORT_SYMBOL_GPL(cm_notify_event); - MODULE_AUTHOR("MyungJoo Ham "); MODULE_DESCRIPTION("Charger Manager"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/power/ds2781_battery.c b/trunk/drivers/power/ds2781_battery.c index 975684a40f15..ca0d653d0a7a 100644 --- a/trunk/drivers/power/ds2781_battery.c +++ b/trunk/drivers/power/ds2781_battery.c @@ -643,7 +643,9 @@ static ssize_t ds2781_read_param_eeprom_bin(struct file *filp, struct power_supply *psy = to_power_supply(dev); struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); - count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off); + count = min_t(loff_t, count, + DS2781_EEPROM_BLOCK1_END - + DS2781_EEPROM_BLOCK1_START + 1 - off); return ds2781_read_block(dev_info, buf, DS2781_EEPROM_BLOCK1_START + off, count); @@ -659,7 +661,9 @@ static ssize_t ds2781_write_param_eeprom_bin(struct file *filp, struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); int ret; - count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off); + count = min_t(loff_t, count, + DS2781_EEPROM_BLOCK1_END - + DS2781_EEPROM_BLOCK1_START + 1 - off); ret = ds2781_write(dev_info, buf, DS2781_EEPROM_BLOCK1_START + off, count); @@ -678,7 +682,7 @@ static struct bin_attribute ds2781_param_eeprom_bin_attr = { .name = "param_eeprom", .mode = S_IRUGO | S_IWUSR, }, - .size = DS2781_PARAM_EEPROM_SIZE, + .size = DS2781_EEPROM_BLOCK1_END - DS2781_EEPROM_BLOCK1_START + 1, .read = ds2781_read_param_eeprom_bin, .write = ds2781_write_param_eeprom_bin, }; @@ -692,7 +696,9 @@ static ssize_t ds2781_read_user_eeprom_bin(struct file *filp, struct power_supply *psy = to_power_supply(dev); struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); - count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off); + count = min_t(loff_t, count, + DS2781_EEPROM_BLOCK0_END - + DS2781_EEPROM_BLOCK0_START + 1 - off); return ds2781_read_block(dev_info, buf, DS2781_EEPROM_BLOCK0_START + off, count); @@ -709,7 +715,9 @@ static ssize_t ds2781_write_user_eeprom_bin(struct file *filp, struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); int ret; - count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off); + count = min_t(loff_t, count, + DS2781_EEPROM_BLOCK0_END - + DS2781_EEPROM_BLOCK0_START + 1 - off); ret = ds2781_write(dev_info, buf, DS2781_EEPROM_BLOCK0_START + off, count); @@ -728,7 +736,7 @@ static struct bin_attribute ds2781_user_eeprom_bin_attr = { .name = "user_eeprom", .mode = S_IRUGO | S_IWUSR, }, - .size = DS2781_USER_EEPROM_SIZE, + .size = DS2781_EEPROM_BLOCK0_END - DS2781_EEPROM_BLOCK0_START + 1, .read = ds2781_read_user_eeprom_bin, .write = ds2781_write_user_eeprom_bin, }; diff --git a/trunk/drivers/power/isp1704_charger.c b/trunk/drivers/power/isp1704_charger.c index e5ccd2979773..39eb50f35f09 100644 --- a/trunk/drivers/power/isp1704_charger.c +++ b/trunk/drivers/power/isp1704_charger.c @@ -474,13 +474,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) fail2: power_supply_unregister(&isp->psy); fail1: - isp1704_charger_set_power(isp, 0); usb_put_transceiver(isp->phy); fail0: kfree(isp); dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); + isp1704_charger_set_power(isp, 0); return ret; } diff --git a/trunk/drivers/power/max17042_battery.c b/trunk/drivers/power/max17042_battery.c index 140788b309f8..04620c2cb388 100644 --- a/trunk/drivers/power/max17042_battery.c +++ b/trunk/drivers/power/max17042_battery.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -62,13 +61,9 @@ #define dP_ACC_100 0x1900 #define dP_ACC_200 0x3200 -#define MAX17042_IC_VERSION 0x0092 -#define MAX17047_IC_VERSION 0x00AC /* same for max17050 */ - struct max17042_chip { struct i2c_client *client; struct power_supply battery; - enum max170xx_chip_type chip_type; struct max17042_platform_data *pdata; struct work_struct work; int init_complete; @@ -110,7 +105,6 @@ static enum power_supply_property max17042_battery_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_VOLTAGE_OCV, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_TEMP, @@ -156,10 +150,7 @@ static int max17042_get_property(struct power_supply *psy, val->intval *= 20000; /* Units of LSB = 20mV */ break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - if (chip->chip_type == MAX17042) - ret = max17042_read_reg(chip->client, MAX17042_V_empty); - else - ret = max17042_read_reg(chip->client, MAX17047_V_empty); + ret = max17042_read_reg(chip->client, MAX17042_V_empty); if (ret < 0) return ret; @@ -178,13 +169,6 @@ static int max17042_get_property(struct power_supply *psy, if (ret < 0) return ret; - val->intval = ret * 625 / 8; - break; - case POWER_SUPPLY_PROP_VOLTAGE_OCV: - ret = max17042_read_reg(chip->client, MAX17042_OCVInternal); - if (ret < 0) - return ret; - val->intval = ret * 625 / 8; break; case POWER_SUPPLY_PROP_CAPACITY: @@ -341,10 +325,11 @@ static inline int max17042_model_data_compare(struct max17042_chip *chip, static int max17042_init_model(struct max17042_chip *chip) { int ret; - int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); + int table_size = + sizeof(chip->pdata->config_data->cell_char_tbl)/sizeof(u16); u16 *temp_data; - temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); + temp_data = kzalloc(table_size, GFP_KERNEL); if (!temp_data) return -ENOMEM; @@ -369,11 +354,12 @@ static int max17042_init_model(struct max17042_chip *chip) static int max17042_verify_model_lock(struct max17042_chip *chip) { int i; - int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); + int table_size = + sizeof(chip->pdata->config_data->cell_char_tbl); u16 *temp_data; int ret = 0; - temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL); + temp_data = kzalloc(table_size, GFP_KERNEL); if (!temp_data) return -ENOMEM; @@ -396,9 +382,6 @@ static void max17042_write_config_regs(struct max17042_chip *chip) max17042_write_reg(chip->client, MAX17042_FilterCFG, config->filter_cfg); max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg); - if (chip->chip_type == MAX17047) - max17042_write_reg(chip->client, MAX17047_FullSOCThr, - config->full_soc_thresh); } static void max17042_write_custom_regs(struct max17042_chip *chip) @@ -409,23 +392,12 @@ static void max17042_write_custom_regs(struct max17042_chip *chip) config->rcomp0); max17042_write_verify_reg(chip->client, MAX17042_TempCo, config->tcompc0); + max17042_write_reg(chip->client, MAX17042_EmptyTempCo, + config->empty_tempco); + max17042_write_verify_reg(chip->client, MAX17042_K_empty0, + config->kempty0); max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm, config->ichgt_term); - if (chip->chip_type == MAX17042) { - max17042_write_reg(chip->client, MAX17042_EmptyTempCo, - config->empty_tempco); - max17042_write_verify_reg(chip->client, MAX17042_K_empty0, - config->kempty0); - } else { - max17042_write_verify_reg(chip->client, MAX17047_QRTbl00, - config->qrtbl00); - max17042_write_verify_reg(chip->client, MAX17047_QRTbl10, - config->qrtbl10); - max17042_write_verify_reg(chip->client, MAX17047_QRTbl20, - config->qrtbl20); - max17042_write_verify_reg(chip->client, MAX17047_QRTbl30, - config->qrtbl30); - } } static void max17042_update_capacity_regs(struct max17042_chip *chip) @@ -481,8 +453,6 @@ static void max17042_load_new_capacity_params(struct max17042_chip *chip) config->design_cap); max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, config->fullcapnom); - /* Update SOC register with new SOC */ - max17042_write_reg(chip->client, MAX17042_RepSOC, vfSoc); } /* @@ -519,28 +489,20 @@ static inline void max17042_override_por_values(struct max17042_chip *chip) max17042_override_por(client, MAX17042_FullCAP, config->fullcap); max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom); - if (chip->chip_type == MAX17042) - max17042_override_por(client, MAX17042_SOC_empty, - config->socempty); + max17042_override_por(client, MAX17042_SOC_empty, config->socempty); max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty); max17042_override_por(client, MAX17042_dQacc, config->dqacc); max17042_override_por(client, MAX17042_dPacc, config->dpacc); - if (chip->chip_type == MAX17042) - max17042_override_por(client, MAX17042_V_empty, config->vempty); - else - max17042_override_por(client, MAX17047_V_empty, config->vempty); + max17042_override_por(client, MAX17042_V_empty, config->vempty); max17042_override_por(client, MAX17042_TempNom, config->temp_nom); max17042_override_por(client, MAX17042_TempLim, config->temp_lim); max17042_override_por(client, MAX17042_FCTC, config->fctc); max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0); max17042_override_por(client, MAX17042_TempCo, config->tcompc0); - if (chip->chip_type) { - max17042_override_por(client, MAX17042_EmptyTempCo, - config->empty_tempco); - max17042_override_por(client, MAX17042_K_empty0, - config->kempty0); - } + max17042_override_por(client, MAX17042_EmptyTempCo, + config->empty_tempco); + max17042_override_por(client, MAX17042_K_empty0, config->kempty0); } static int max17042_init_chip(struct max17042_chip *chip) @@ -697,19 +659,7 @@ static int __devinit max17042_probe(struct i2c_client *client, i2c_set_clientdata(client, chip); - ret = max17042_read_reg(chip->client, MAX17042_DevName); - if (ret == MAX17042_IC_VERSION) { - dev_dbg(&client->dev, "chip type max17042 detected\n"); - chip->chip_type = MAX17042; - } else if (ret == MAX17047_IC_VERSION) { - dev_dbg(&client->dev, "chip type max17047/50 detected\n"); - chip->chip_type = MAX17047; - } else { - dev_err(&client->dev, "device version mismatch: %x\n", ret); - return -EIO; - } - - chip->battery.name = "max170xx_battery"; + chip->battery.name = "max17042_battery"; chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; chip->battery.get_property = max17042_get_property; chip->battery.properties = max17042_battery_props; @@ -733,12 +683,6 @@ static int __devinit max17042_probe(struct i2c_client *client, max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); } - ret = power_supply_register(&client->dev, &chip->battery); - if (ret) { - dev_err(&client->dev, "failed: power supply register\n"); - return ret; - } - if (client->irq) { ret = request_threaded_irq(client->irq, NULL, max17042_thread_handler, @@ -749,14 +693,13 @@ static int __devinit max17042_probe(struct i2c_client *client, reg |= CONFIG_ALRT_BIT_ENBL; max17042_write_reg(client, MAX17042_CONFIG, reg); max17042_set_soc_threshold(chip, 1); - } else { - client->irq = 0; + } else dev_err(&client->dev, "%s(): cannot get IRQ\n", __func__); - } } reg = max17042_read_reg(chip->client, MAX17042_STATUS); + if (reg & STATUS_POR_BIT) { INIT_WORK(&chip->work, max17042_init_worker); schedule_work(&chip->work); @@ -764,65 +707,23 @@ static int __devinit max17042_probe(struct i2c_client *client, chip->init_complete = 1; } - return 0; + ret = power_supply_register(&client->dev, &chip->battery); + if (ret) + dev_err(&client->dev, "failed: power supply register\n"); + return ret; } static int __devexit max17042_remove(struct i2c_client *client) { struct max17042_chip *chip = i2c_get_clientdata(client); - if (client->irq) - free_irq(client->irq, chip); power_supply_unregister(&chip->battery); return 0; } -#ifdef CONFIG_PM -static int max17042_suspend(struct device *dev) -{ - struct max17042_chip *chip = dev_get_drvdata(dev); - - /* - * disable the irq and enable irq_wake - * capability to the interrupt line. - */ - if (chip->client->irq) { - disable_irq(chip->client->irq); - enable_irq_wake(chip->client->irq); - } - - return 0; -} - -static int max17042_resume(struct device *dev) -{ - struct max17042_chip *chip = dev_get_drvdata(dev); - - if (chip->client->irq) { - disable_irq_wake(chip->client->irq); - enable_irq(chip->client->irq); - /* re-program the SOC thresholds to 1% change */ - max17042_set_soc_threshold(chip, 1); - } - - return 0; -} - -static const struct dev_pm_ops max17042_pm_ops = { - .suspend = max17042_suspend, - .resume = max17042_resume, -}; - -#define MAX17042_PM_OPS (&max17042_pm_ops) -#else -#define MAX17042_PM_OPS NULL -#endif - #ifdef CONFIG_OF static const struct of_device_id max17042_dt_match[] = { { .compatible = "maxim,max17042" }, - { .compatible = "maxim,max17047" }, - { .compatible = "maxim,max17050" }, { }, }; MODULE_DEVICE_TABLE(of, max17042_dt_match); @@ -830,8 +731,6 @@ MODULE_DEVICE_TABLE(of, max17042_dt_match); static const struct i2c_device_id max17042_id[] = { { "max17042", 0 }, - { "max17047", 1 }, - { "max17050", 2 }, { } }; MODULE_DEVICE_TABLE(i2c, max17042_id); @@ -840,7 +739,6 @@ static struct i2c_driver max17042_i2c_driver = { .driver = { .name = "max17042", .of_match_table = of_match_ptr(max17042_dt_match), - .pm = MAX17042_PM_OPS, }, .probe = max17042_probe, .remove = __devexit_p(max17042_remove), diff --git a/trunk/drivers/power/power_supply_sysfs.c b/trunk/drivers/power/power_supply_sysfs.c index 4150747f9186..4368e7d61316 100644 --- a/trunk/drivers/power/power_supply_sysfs.c +++ b/trunk/drivers/power/power_supply_sysfs.c @@ -146,7 +146,6 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(voltage_min_design), POWER_SUPPLY_ATTR(voltage_now), POWER_SUPPLY_ATTR(voltage_avg), - POWER_SUPPLY_ATTR(voltage_ocv), POWER_SUPPLY_ATTR(current_max), POWER_SUPPLY_ATTR(current_now), POWER_SUPPLY_ATTR(current_avg), diff --git a/trunk/drivers/power/sbs-battery.c b/trunk/drivers/power/sbs-battery.c index a5b6849d4123..06b659d91790 100644 --- a/trunk/drivers/power/sbs-battery.c +++ b/trunk/drivers/power/sbs-battery.c @@ -89,7 +89,7 @@ static const struct chip_data { [REG_CURRENT] = SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767), [REG_CAPACITY] = - SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0D, 0, 100), + SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0E, 0, 100), [REG_REMAINING_CAPACITY] = SBS_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535), [REG_REMAINING_CAPACITY_CHARGE] = diff --git a/trunk/drivers/power/smb347-charger.c b/trunk/drivers/power/smb347-charger.c index f8eedd8a676f..ce1694d1a365 100644 --- a/trunk/drivers/power/smb347-charger.c +++ b/trunk/drivers/power/smb347-charger.c @@ -11,7 +11,7 @@ * published by the Free Software Foundation. */ -#include +#include #include #include #include @@ -21,7 +21,7 @@ #include #include #include -#include +#include /* * Configuration registers. These are mirrored to volatile RAM and can be @@ -39,7 +39,6 @@ #define CFG_CURRENT_LIMIT_DC_SHIFT 4 #define CFG_CURRENT_LIMIT_USB_MASK 0x0f #define CFG_FLOAT_VOLTAGE 0x03 -#define CFG_FLOAT_VOLTAGE_FLOAT_MASK 0x3f #define CFG_FLOAT_VOLTAGE_THRESHOLD_MASK 0xc0 #define CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT 6 #define CFG_STAT 0x05 @@ -114,31 +113,29 @@ #define STAT_C_CHARGER_ERROR BIT(6) #define STAT_E 0x3f -#define SMB347_MAX_REGISTER 0x3f - /** * struct smb347_charger - smb347 charger instance * @lock: protects concurrent access to online variables - * @dev: pointer to device - * @regmap: pointer to driver regmap + * @client: pointer to i2c client * @mains: power_supply instance for AC/DC power * @usb: power_supply instance for USB power * @battery: power_supply instance for battery * @mains_online: is AC/DC input connected * @usb_online: is USB input connected * @charging_enabled: is charging enabled + * @dentry: for debugfs * @pdata: pointer to platform data */ struct smb347_charger { struct mutex lock; - struct device *dev; - struct regmap *regmap; + struct i2c_client *client; struct power_supply mains; struct power_supply usb; struct power_supply battery; bool mains_online; bool usb_online; bool charging_enabled; + struct dentry *dentry; const struct smb347_charger_platform_data *pdata; }; @@ -196,6 +193,14 @@ static const unsigned int ccc_tbl[] = { 1200000, }; +/* Convert register value to current using lookup table */ +static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val) +{ + if (val >= size) + return -EINVAL; + return tbl[val]; +} + /* Convert current to register value using lookup table */ static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val) { @@ -207,22 +212,43 @@ static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val) return i > 0 ? i - 1 : -EINVAL; } +static int smb347_read(struct smb347_charger *smb, u8 reg) +{ + int ret; + + ret = i2c_smbus_read_byte_data(smb->client, reg); + if (ret < 0) + dev_warn(&smb->client->dev, "failed to read reg 0x%x: %d\n", + reg, ret); + return ret; +} + +static int smb347_write(struct smb347_charger *smb, u8 reg, u8 val) +{ + int ret; + + ret = i2c_smbus_write_byte_data(smb->client, reg, val); + if (ret < 0) + dev_warn(&smb->client->dev, "failed to write reg 0x%x: %d\n", + reg, ret); + return ret; +} + /** - * smb347_update_ps_status - refreshes the power source status + * smb347_update_status - updates the charging status * @smb: pointer to smb347 charger instance * - * Function checks whether any power source is connected to the charger and - * updates internal state accordingly. If there is a change to previous state - * function returns %1, otherwise %0 and negative errno in case of errror. + * Function checks status of the charging and updates internal state + * accordingly. Returns %0 if there is no change in status, %1 if the + * status has changed and negative errno in case of failure. */ -static int smb347_update_ps_status(struct smb347_charger *smb) +static int smb347_update_status(struct smb347_charger *smb) { bool usb = false; bool dc = false; - unsigned int val; int ret; - ret = regmap_read(smb->regmap, IRQSTAT_E, &val); + ret = smb347_read(smb, IRQSTAT_E); if (ret < 0) return ret; @@ -231,9 +257,9 @@ static int smb347_update_ps_status(struct smb347_charger *smb) * platform data _and_ whether corresponding undervoltage is set. */ if (smb->pdata->use_mains) - dc = !(val & IRQSTAT_E_DCIN_UV_STAT); + dc = !(ret & IRQSTAT_E_DCIN_UV_STAT); if (smb->pdata->use_usb) - usb = !(val & IRQSTAT_E_USBIN_UV_STAT); + usb = !(ret & IRQSTAT_E_USBIN_UV_STAT); mutex_lock(&smb->lock); ret = smb->mains_online != dc || smb->usb_online != usb; @@ -245,15 +271,15 @@ static int smb347_update_ps_status(struct smb347_charger *smb) } /* - * smb347_is_ps_online - returns whether input power source is connected + * smb347_is_online - returns whether input power source is connected * @smb: pointer to smb347 charger instance * * Returns %true if input power source is connected. Note that this is * dependent on what platform has configured for usable power sources. For - * example if USB is disabled, this will return %false even if the USB cable - * is connected. + * example if USB is disabled, this will return %false even if the USB + * cable is connected. */ -static bool smb347_is_ps_online(struct smb347_charger *smb) +static bool smb347_is_online(struct smb347_charger *smb) { bool ret; @@ -273,17 +299,16 @@ static bool smb347_is_ps_online(struct smb347_charger *smb) */ static int smb347_charging_status(struct smb347_charger *smb) { - unsigned int val; int ret; - if (!smb347_is_ps_online(smb)) + if (!smb347_is_online(smb)) return 0; - ret = regmap_read(smb->regmap, STAT_C, &val); + ret = smb347_read(smb, STAT_C); if (ret < 0) return 0; - return (val & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT; + return (ret & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT; } static int smb347_charging_set(struct smb347_charger *smb, bool enable) @@ -291,17 +316,27 @@ static int smb347_charging_set(struct smb347_charger *smb, bool enable) int ret = 0; if (smb->pdata->enable_control != SMB347_CHG_ENABLE_SW) { - dev_dbg(smb->dev, "charging enable/disable in SW disabled\n"); + dev_dbg(&smb->client->dev, + "charging enable/disable in SW disabled\n"); return 0; } mutex_lock(&smb->lock); if (smb->charging_enabled != enable) { - ret = regmap_update_bits(smb->regmap, CMD_A, CMD_A_CHG_ENABLED, - enable ? CMD_A_CHG_ENABLED : 0); - if (!ret) - smb->charging_enabled = enable; + ret = smb347_read(smb, CMD_A); + if (ret < 0) + goto out; + + smb->charging_enabled = enable; + + if (enable) + ret |= CMD_A_CHG_ENABLED; + else + ret &= ~CMD_A_CHG_ENABLED; + + ret = smb347_write(smb, CMD_A, ret); } +out: mutex_unlock(&smb->lock); return ret; } @@ -316,7 +351,7 @@ static inline int smb347_charging_disable(struct smb347_charger *smb) return smb347_charging_set(smb, false); } -static int smb347_start_stop_charging(struct smb347_charger *smb) +static int smb347_update_online(struct smb347_charger *smb) { int ret; @@ -325,14 +360,16 @@ static int smb347_start_stop_charging(struct smb347_charger *smb) * disable or enable the charging. We do it manually because it * depends on how the platform has configured the valid inputs. */ - if (smb347_is_ps_online(smb)) { + if (smb347_is_online(smb)) { ret = smb347_charging_enable(smb); if (ret < 0) - dev_err(smb->dev, "failed to enable charging\n"); + dev_err(&smb->client->dev, + "failed to enable charging\n"); } else { ret = smb347_charging_disable(smb); if (ret < 0) - dev_err(smb->dev, "failed to disable charging\n"); + dev_err(&smb->client->dev, + "failed to disable charging\n"); } return ret; @@ -340,120 +377,112 @@ static int smb347_start_stop_charging(struct smb347_charger *smb) static int smb347_set_charge_current(struct smb347_charger *smb) { - int ret; + int ret, val; + + ret = smb347_read(smb, CFG_CHARGE_CURRENT); + if (ret < 0) + return ret; if (smb->pdata->max_charge_current) { - ret = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl), + val = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl), smb->pdata->max_charge_current); - if (ret < 0) - return ret; + if (val < 0) + return val; - ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, - CFG_CHARGE_CURRENT_FCC_MASK, - ret << CFG_CHARGE_CURRENT_FCC_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_CHARGE_CURRENT_FCC_MASK; + ret |= val << CFG_CHARGE_CURRENT_FCC_SHIFT; } if (smb->pdata->pre_charge_current) { - ret = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl), + val = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl), smb->pdata->pre_charge_current); - if (ret < 0) - return ret; + if (val < 0) + return val; - ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, - CFG_CHARGE_CURRENT_PCC_MASK, - ret << CFG_CHARGE_CURRENT_PCC_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_CHARGE_CURRENT_PCC_MASK; + ret |= val << CFG_CHARGE_CURRENT_PCC_SHIFT; } if (smb->pdata->termination_current) { - ret = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl), + val = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl), smb->pdata->termination_current); - if (ret < 0) - return ret; + if (val < 0) + return val; - ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, - CFG_CHARGE_CURRENT_TC_MASK, ret); - if (ret < 0) - return ret; + ret &= ~CFG_CHARGE_CURRENT_TC_MASK; + ret |= val; } - return 0; + return smb347_write(smb, CFG_CHARGE_CURRENT, ret); } static int smb347_set_current_limits(struct smb347_charger *smb) { - int ret; + int ret, val; + + ret = smb347_read(smb, CFG_CURRENT_LIMIT); + if (ret < 0) + return ret; if (smb->pdata->mains_current_limit) { - ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), + val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), smb->pdata->mains_current_limit); - if (ret < 0) - return ret; + if (val < 0) + return val; - ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT, - CFG_CURRENT_LIMIT_DC_MASK, - ret << CFG_CURRENT_LIMIT_DC_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_CURRENT_LIMIT_DC_MASK; + ret |= val << CFG_CURRENT_LIMIT_DC_SHIFT; } if (smb->pdata->usb_hc_current_limit) { - ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), + val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), smb->pdata->usb_hc_current_limit); - if (ret < 0) - return ret; + if (val < 0) + return val; - ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT, - CFG_CURRENT_LIMIT_USB_MASK, ret); - if (ret < 0) - return ret; + ret &= ~CFG_CURRENT_LIMIT_USB_MASK; + ret |= val; } - return 0; + return smb347_write(smb, CFG_CURRENT_LIMIT, ret); } static int smb347_set_voltage_limits(struct smb347_charger *smb) { - int ret; + int ret, val; + + ret = smb347_read(smb, CFG_FLOAT_VOLTAGE); + if (ret < 0) + return ret; if (smb->pdata->pre_to_fast_voltage) { - ret = smb->pdata->pre_to_fast_voltage; + val = smb->pdata->pre_to_fast_voltage; /* uV */ - ret = clamp_val(ret, 2400000, 3000000) - 2400000; - ret /= 200000; + val = clamp_val(val, 2400000, 3000000) - 2400000; + val /= 200000; - ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE, - CFG_FLOAT_VOLTAGE_THRESHOLD_MASK, - ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_FLOAT_VOLTAGE_THRESHOLD_MASK; + ret |= val << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT; } if (smb->pdata->max_charge_voltage) { - ret = smb->pdata->max_charge_voltage; + val = smb->pdata->max_charge_voltage; /* uV */ - ret = clamp_val(ret, 3500000, 4500000) - 3500000; - ret /= 20000; + val = clamp_val(val, 3500000, 4500000) - 3500000; + val /= 20000; - ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE, - CFG_FLOAT_VOLTAGE_FLOAT_MASK, ret); - if (ret < 0) - return ret; + ret |= val; } - return 0; + return smb347_write(smb, CFG_FLOAT_VOLTAGE, ret); } static int smb347_set_temp_limits(struct smb347_charger *smb) { bool enable_therm_monitor = false; - int ret = 0; - int val; + int ret, val; if (smb->pdata->chip_temp_threshold) { val = smb->pdata->chip_temp_threshold; @@ -462,13 +491,22 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) val = clamp_val(val, 100, 130) - 100; val /= 10; - ret = regmap_update_bits(smb->regmap, CFG_OTG, - CFG_OTG_TEMP_THRESHOLD_MASK, - val << CFG_OTG_TEMP_THRESHOLD_SHIFT); + ret = smb347_read(smb, CFG_OTG); + if (ret < 0) + return ret; + + ret &= ~CFG_OTG_TEMP_THRESHOLD_MASK; + ret |= val << CFG_OTG_TEMP_THRESHOLD_SHIFT; + + ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } + ret = smb347_read(smb, CFG_TEMP_LIMIT); + if (ret < 0) + return ret; + if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->soft_cold_temp_limit; @@ -477,11 +515,8 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) /* this goes from higher to lower so invert the value */ val = ~val & 0x3; - ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, - CFG_TEMP_LIMIT_SOFT_COLD_MASK, - val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_TEMP_LIMIT_SOFT_COLD_MASK; + ret |= val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT; enable_therm_monitor = true; } @@ -492,11 +527,8 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) val = clamp_val(val, 40, 55) - 40; val /= 5; - ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, - CFG_TEMP_LIMIT_SOFT_HOT_MASK, - val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_TEMP_LIMIT_SOFT_HOT_MASK; + ret |= val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT; enable_therm_monitor = true; } @@ -509,11 +541,8 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) /* this goes from higher to lower so invert the value */ val = ~val & 0x3; - ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, - CFG_TEMP_LIMIT_HARD_COLD_MASK, - val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_TEMP_LIMIT_HARD_COLD_MASK; + ret |= val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT; enable_therm_monitor = true; } @@ -524,15 +553,16 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) val = clamp_val(val, 50, 65) - 50; val /= 5; - ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, - CFG_TEMP_LIMIT_HARD_HOT_MASK, - val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT); - if (ret < 0) - return ret; + ret &= ~CFG_TEMP_LIMIT_HARD_HOT_MASK; + ret |= val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT; enable_therm_monitor = true; } + ret = smb347_write(smb, CFG_TEMP_LIMIT, ret); + if (ret < 0) + return ret; + /* * If any of the temperature limits are set, we also enable the * thermistor monitoring. @@ -544,15 +574,25 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) * depending on the configuration. */ if (enable_therm_monitor) { - ret = regmap_update_bits(smb->regmap, CFG_THERM, - CFG_THERM_MONITOR_DISABLED, 0); + ret = smb347_read(smb, CFG_THERM); + if (ret < 0) + return ret; + + ret &= ~CFG_THERM_MONITOR_DISABLED; + + ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } if (smb->pdata->suspend_on_hard_temp_limit) { - ret = regmap_update_bits(smb->regmap, CFG_SYSOK, - CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0); + ret = smb347_read(smb, CFG_SYSOK); + if (ret < 0) + return ret; + + ret &= ~CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED; + + ret = smb347_write(smb, CFG_SYSOK, ret); if (ret < 0) return ret; } @@ -561,15 +601,17 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) { val = smb->pdata->soft_temp_limit_compensation & 0x3; - ret = regmap_update_bits(smb->regmap, CFG_THERM, - CFG_THERM_SOFT_HOT_COMPENSATION_MASK, - val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT); + ret = smb347_read(smb, CFG_THERM); if (ret < 0) return ret; - ret = regmap_update_bits(smb->regmap, CFG_THERM, - CFG_THERM_SOFT_COLD_COMPENSATION_MASK, - val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT); + ret &= ~CFG_THERM_SOFT_HOT_COMPENSATION_MASK; + ret |= val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT; + + ret &= ~CFG_THERM_SOFT_COLD_COMPENSATION_MASK; + ret |= val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT; + + ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } @@ -580,9 +622,14 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) if (val < 0) return val; - ret = regmap_update_bits(smb->regmap, CFG_OTG, - CFG_OTG_CC_COMPENSATION_MASK, - (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT); + ret = smb347_read(smb, CFG_OTG); + if (ret < 0) + return ret; + + ret &= ~CFG_OTG_CC_COMPENSATION_MASK; + ret |= (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT; + + ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } @@ -601,13 +648,22 @@ static int smb347_set_temp_limits(struct smb347_charger *smb) */ static int smb347_set_writable(struct smb347_charger *smb, bool writable) { - return regmap_update_bits(smb->regmap, CMD_A, CMD_A_ALLOW_WRITE, - writable ? CMD_A_ALLOW_WRITE : 0); + int ret; + + ret = smb347_read(smb, CMD_A); + if (ret < 0) + return ret; + + if (writable) + ret |= CMD_A_ALLOW_WRITE; + else + ret &= ~CMD_A_ALLOW_WRITE; + + return smb347_write(smb, CMD_A, ret); } static int smb347_hw_init(struct smb347_charger *smb) { - unsigned int val; int ret; ret = smb347_set_writable(smb, true); @@ -636,19 +692,34 @@ static int smb347_hw_init(struct smb347_charger *smb) /* If USB charging is disabled we put the USB in suspend mode */ if (!smb->pdata->use_usb) { - ret = regmap_update_bits(smb->regmap, CMD_A, - CMD_A_SUSPEND_ENABLED, - CMD_A_SUSPEND_ENABLED); + ret = smb347_read(smb, CMD_A); + if (ret < 0) + goto fail; + + ret |= CMD_A_SUSPEND_ENABLED; + + ret = smb347_write(smb, CMD_A, ret); if (ret < 0) goto fail; } + ret = smb347_read(smb, CFG_OTHER); + if (ret < 0) + goto fail; + /* * If configured by platform data, we enable hardware Auto-OTG * support for driving VBUS. Otherwise we disable it. */ - ret = regmap_update_bits(smb->regmap, CFG_OTHER, CFG_OTHER_RID_MASK, - smb->pdata->use_usb_otg ? CFG_OTHER_RID_ENABLED_AUTO_OTG : 0); + ret &= ~CFG_OTHER_RID_MASK; + if (smb->pdata->use_usb_otg) + ret |= CFG_OTHER_RID_ENABLED_AUTO_OTG; + + ret = smb347_write(smb, CFG_OTHER, ret); + if (ret < 0) + goto fail; + + ret = smb347_read(smb, CFG_PIN); if (ret < 0) goto fail; @@ -657,33 +728,32 @@ static int smb347_hw_init(struct smb347_charger *smb) * command register unless pin control is specified in the platform * data. */ + ret &= ~CFG_PIN_EN_CTRL_MASK; + switch (smb->pdata->enable_control) { + case SMB347_CHG_ENABLE_SW: + /* Do nothing, 0 means i2c control */ + break; case SMB347_CHG_ENABLE_PIN_ACTIVE_LOW: - val = CFG_PIN_EN_CTRL_ACTIVE_LOW; + ret |= CFG_PIN_EN_CTRL_ACTIVE_LOW; break; case SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH: - val = CFG_PIN_EN_CTRL_ACTIVE_HIGH; - break; - default: - val = 0; + ret |= CFG_PIN_EN_CTRL_ACTIVE_HIGH; break; } - ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CTRL_MASK, - val); - if (ret < 0) - goto fail; - /* Disable Automatic Power Source Detection (APSD) interrupt. */ - ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_APSD_IRQ, 0); + ret &= ~CFG_PIN_EN_APSD_IRQ; + + ret = smb347_write(smb, CFG_PIN, ret); if (ret < 0) goto fail; - ret = smb347_update_ps_status(smb); + ret = smb347_update_status(smb); if (ret < 0) goto fail; - ret = smb347_start_stop_charging(smb); + ret = smb347_update_online(smb); fail: smb347_set_writable(smb, false); @@ -693,25 +763,24 @@ static int smb347_hw_init(struct smb347_charger *smb) static irqreturn_t smb347_interrupt(int irq, void *data) { struct smb347_charger *smb = data; - unsigned int stat_c, irqstat_e, irqstat_c; - bool handled = false; - int ret; + int stat_c, irqstat_e, irqstat_c; + irqreturn_t ret = IRQ_NONE; - ret = regmap_read(smb->regmap, STAT_C, &stat_c); - if (ret < 0) { - dev_warn(smb->dev, "reading STAT_C failed\n"); + stat_c = smb347_read(smb, STAT_C); + if (stat_c < 0) { + dev_warn(&smb->client->dev, "reading STAT_C failed\n"); return IRQ_NONE; } - ret = regmap_read(smb->regmap, IRQSTAT_C, &irqstat_c); - if (ret < 0) { - dev_warn(smb->dev, "reading IRQSTAT_C failed\n"); + irqstat_c = smb347_read(smb, IRQSTAT_C); + if (irqstat_c < 0) { + dev_warn(&smb->client->dev, "reading IRQSTAT_C failed\n"); return IRQ_NONE; } - ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e); - if (ret < 0) { - dev_warn(smb->dev, "reading IRQSTAT_E failed\n"); + irqstat_e = smb347_read(smb, IRQSTAT_E); + if (irqstat_e < 0) { + dev_warn(&smb->client->dev, "reading IRQSTAT_E failed\n"); return IRQ_NONE; } @@ -720,11 +789,13 @@ static irqreturn_t smb347_interrupt(int irq, void *data) * disable charging. */ if (stat_c & STAT_C_CHARGER_ERROR) { - dev_err(smb->dev, "error in charger, disabling charging\n"); + dev_err(&smb->client->dev, + "error in charger, disabling charging\n"); smb347_charging_disable(smb); power_supply_changed(&smb->battery); - handled = true; + + ret = IRQ_HANDLED; } /* @@ -735,7 +806,7 @@ static irqreturn_t smb347_interrupt(int irq, void *data) if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) power_supply_changed(&smb->battery); - handled = true; + ret = IRQ_HANDLED; } /* @@ -743,17 +814,15 @@ static irqreturn_t smb347_interrupt(int irq, void *data) * was connected or disconnected. */ if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) { - if (smb347_update_ps_status(smb) > 0) { - smb347_start_stop_charging(smb); - if (smb->pdata->use_mains) - power_supply_changed(&smb->mains); - if (smb->pdata->use_usb) - power_supply_changed(&smb->usb); + if (smb347_update_status(smb) > 0) { + smb347_update_online(smb); + power_supply_changed(&smb->mains); + power_supply_changed(&smb->usb); } - handled = true; + ret = IRQ_HANDLED; } - return handled ? IRQ_HANDLED : IRQ_NONE; + return ret; } static int smb347_irq_set(struct smb347_charger *smb, bool enable) @@ -770,18 +839,41 @@ static int smb347_irq_set(struct smb347_charger *smb, bool enable) * - termination current reached * - charger error */ - ret = regmap_update_bits(smb->regmap, CFG_FAULT_IRQ, 0xff, - enable ? CFG_FAULT_IRQ_DCIN_UV : 0); - if (ret < 0) - goto fail; + if (enable) { + ret = smb347_write(smb, CFG_FAULT_IRQ, CFG_FAULT_IRQ_DCIN_UV); + if (ret < 0) + goto fail; - ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff, - enable ? CFG_STATUS_IRQ_TERMINATION_OR_TAPER : 0); - if (ret < 0) - goto fail; + ret = smb347_write(smb, CFG_STATUS_IRQ, + CFG_STATUS_IRQ_TERMINATION_OR_TAPER); + if (ret < 0) + goto fail; + + ret = smb347_read(smb, CFG_PIN); + if (ret < 0) + goto fail; + + ret |= CFG_PIN_EN_CHARGER_ERROR; + + ret = smb347_write(smb, CFG_PIN, ret); + } else { + ret = smb347_write(smb, CFG_FAULT_IRQ, 0); + if (ret < 0) + goto fail; + + ret = smb347_write(smb, CFG_STATUS_IRQ, 0); + if (ret < 0) + goto fail; + + ret = smb347_read(smb, CFG_PIN); + if (ret < 0) + goto fail; + + ret &= ~CFG_PIN_EN_CHARGER_ERROR; + + ret = smb347_write(smb, CFG_PIN, ret); + } - ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CHARGER_ERROR, - enable ? CFG_PIN_EN_CHARGER_ERROR : 0); fail: smb347_set_writable(smb, false); return ret; @@ -797,18 +889,18 @@ static inline int smb347_irq_disable(struct smb347_charger *smb) return smb347_irq_set(smb, false); } -static int smb347_irq_init(struct smb347_charger *smb, - struct i2c_client *client) +static int smb347_irq_init(struct smb347_charger *smb) { const struct smb347_charger_platform_data *pdata = smb->pdata; int ret, irq = gpio_to_irq(pdata->irq_gpio); - ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name); + ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, smb->client->name); if (ret < 0) goto fail; ret = request_threaded_irq(irq, NULL, smb347_interrupt, - IRQF_TRIGGER_FALLING, client->name, smb); + IRQF_TRIGGER_FALLING, smb->client->name, + smb); if (ret < 0) goto fail_gpio; @@ -820,14 +912,23 @@ static int smb347_irq_init(struct smb347_charger *smb, * Configure the STAT output to be suitable for interrupts: disable * all other output (except interrupts) and make it active low. */ - ret = regmap_update_bits(smb->regmap, CFG_STAT, - CFG_STAT_ACTIVE_HIGH | CFG_STAT_DISABLED, - CFG_STAT_DISABLED); + ret = smb347_read(smb, CFG_STAT); + if (ret < 0) + goto fail_readonly; + + ret &= ~CFG_STAT_ACTIVE_HIGH; + ret |= CFG_STAT_DISABLED; + + ret = smb347_write(smb, CFG_STAT, ret); + if (ret < 0) + goto fail_readonly; + + ret = smb347_irq_enable(smb); if (ret < 0) goto fail_readonly; smb347_set_writable(smb, false); - client->irq = irq; + smb->client->irq = irq; return 0; fail_readonly: @@ -837,7 +938,7 @@ static int smb347_irq_init(struct smb347_charger *smb, fail_gpio: gpio_free(pdata->irq_gpio); fail: - client->irq = 0; + smb->client->irq = 0; return ret; } @@ -886,13 +987,13 @@ static int smb347_battery_get_property(struct power_supply *psy, const struct smb347_charger_platform_data *pdata = smb->pdata; int ret; - ret = smb347_update_ps_status(smb); + ret = smb347_update_status(smb); if (ret < 0) return ret; switch (prop) { case POWER_SUPPLY_PROP_STATUS: - if (!smb347_is_ps_online(smb)) { + if (!smb347_is_online(smb)) { val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; } @@ -903,7 +1004,7 @@ static int smb347_battery_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CHARGE_TYPE: - if (!smb347_is_ps_online(smb)) + if (!smb347_is_online(smb)) return -ENODATA; /* @@ -935,6 +1036,44 @@ static int smb347_battery_get_property(struct power_supply *psy, val->intval = pdata->battery_info.voltage_max_design; break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (!smb347_is_online(smb)) + return -ENODATA; + ret = smb347_read(smb, STAT_A); + if (ret < 0) + return ret; + + ret &= STAT_A_FLOAT_VOLTAGE_MASK; + if (ret > 0x3d) + ret = 0x3d; + + val->intval = 3500000 + ret * 20000; + break; + + case POWER_SUPPLY_PROP_CURRENT_NOW: + if (!smb347_is_online(smb)) + return -ENODATA; + + ret = smb347_read(smb, STAT_B); + if (ret < 0) + return ret; + + /* + * The current value is composition of FCC and PCC values + * and we can detect which table to use from bit 5. + */ + if (ret & 0x20) { + val->intval = hw_to_current(fcc_tbl, + ARRAY_SIZE(fcc_tbl), + ret & 7); + } else { + ret >>= 3; + val->intval = hw_to_current(pcc_tbl, + ARRAY_SIZE(pcc_tbl), + ret & 7); + } + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: val->intval = pdata->battery_info.charge_full_design; break; @@ -956,58 +1095,64 @@ static enum power_supply_property smb347_battery_properties[] = { POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_MODEL_NAME, }; -static bool smb347_volatile_reg(struct device *dev, unsigned int reg) +static int smb347_debugfs_show(struct seq_file *s, void *data) { - switch (reg) { - case IRQSTAT_A: - case IRQSTAT_C: - case IRQSTAT_E: - case IRQSTAT_F: - case STAT_A: - case STAT_B: - case STAT_C: - case STAT_E: - return true; + struct smb347_charger *smb = s->private; + int ret; + u8 reg; + + seq_printf(s, "Control registers:\n"); + seq_printf(s, "==================\n"); + for (reg = CFG_CHARGE_CURRENT; reg <= CFG_ADDRESS; reg++) { + ret = smb347_read(smb, reg); + seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); + } + seq_printf(s, "\n"); + + seq_printf(s, "Command registers:\n"); + seq_printf(s, "==================\n"); + ret = smb347_read(smb, CMD_A); + seq_printf(s, "0x%02x:\t0x%02x\n", CMD_A, ret); + ret = smb347_read(smb, CMD_B); + seq_printf(s, "0x%02x:\t0x%02x\n", CMD_B, ret); + ret = smb347_read(smb, CMD_C); + seq_printf(s, "0x%02x:\t0x%02x\n", CMD_C, ret); + seq_printf(s, "\n"); + + seq_printf(s, "Interrupt status registers:\n"); + seq_printf(s, "===========================\n"); + for (reg = IRQSTAT_A; reg <= IRQSTAT_F; reg++) { + ret = smb347_read(smb, reg); + seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); + } + seq_printf(s, "\n"); + + seq_printf(s, "Status registers:\n"); + seq_printf(s, "=================\n"); + for (reg = STAT_A; reg <= STAT_E; reg++) { + ret = smb347_read(smb, reg); + seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); } - return false; + return 0; } -static bool smb347_readable_reg(struct device *dev, unsigned int reg) +static int smb347_debugfs_open(struct inode *inode, struct file *file) { - switch (reg) { - case CFG_CHARGE_CURRENT: - case CFG_CURRENT_LIMIT: - case CFG_FLOAT_VOLTAGE: - case CFG_STAT: - case CFG_PIN: - case CFG_THERM: - case CFG_SYSOK: - case CFG_OTHER: - case CFG_OTG: - case CFG_TEMP_LIMIT: - case CFG_FAULT_IRQ: - case CFG_STATUS_IRQ: - case CFG_ADDRESS: - case CMD_A: - case CMD_B: - case CMD_C: - return true; - } - - return smb347_volatile_reg(dev, reg); + return single_open(file, smb347_debugfs_show, inode->i_private); } -static const struct regmap_config smb347_regmap = { - .reg_bits = 8, - .val_bits = 8, - .max_register = SMB347_MAX_REGISTER, - .volatile_reg = smb347_volatile_reg, - .readable_reg = smb347_readable_reg, +static const struct file_operations smb347_debugfs_fops = { + .open = smb347_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, }; static int smb347_probe(struct i2c_client *client, @@ -1033,45 +1178,28 @@ static int smb347_probe(struct i2c_client *client, i2c_set_clientdata(client, smb); mutex_init(&smb->lock); - smb->dev = &client->dev; + smb->client = client; smb->pdata = pdata; - smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap); - if (IS_ERR(smb->regmap)) - return PTR_ERR(smb->regmap); - ret = smb347_hw_init(smb); if (ret < 0) return ret; - if (smb->pdata->use_mains) { - smb->mains.name = "smb347-mains"; - smb->mains.type = POWER_SUPPLY_TYPE_MAINS; - smb->mains.get_property = smb347_mains_get_property; - smb->mains.properties = smb347_mains_properties; - smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties); - smb->mains.supplied_to = battery; - smb->mains.num_supplicants = ARRAY_SIZE(battery); - ret = power_supply_register(dev, &smb->mains); - if (ret < 0) - return ret; - } - - if (smb->pdata->use_usb) { - smb->usb.name = "smb347-usb"; - smb->usb.type = POWER_SUPPLY_TYPE_USB; - smb->usb.get_property = smb347_usb_get_property; - smb->usb.properties = smb347_usb_properties; - smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties); - smb->usb.supplied_to = battery; - smb->usb.num_supplicants = ARRAY_SIZE(battery); - ret = power_supply_register(dev, &smb->usb); - if (ret < 0) { - if (smb->pdata->use_mains) - power_supply_unregister(&smb->mains); - return ret; - } - } + smb->mains.name = "smb347-mains"; + smb->mains.type = POWER_SUPPLY_TYPE_MAINS; + smb->mains.get_property = smb347_mains_get_property; + smb->mains.properties = smb347_mains_properties; + smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties); + smb->mains.supplied_to = battery; + smb->mains.num_supplicants = ARRAY_SIZE(battery); + + smb->usb.name = "smb347-usb"; + smb->usb.type = POWER_SUPPLY_TYPE_USB; + smb->usb.get_property = smb347_usb_get_property; + smb->usb.properties = smb347_usb_properties; + smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties); + smb->usb.supplied_to = battery; + smb->usb.num_supplicants = ARRAY_SIZE(battery); smb->battery.name = "smb347-battery"; smb->battery.type = POWER_SUPPLY_TYPE_BATTERY; @@ -1079,13 +1207,20 @@ static int smb347_probe(struct i2c_client *client, smb->battery.properties = smb347_battery_properties; smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties); + ret = power_supply_register(dev, &smb->mains); + if (ret < 0) + return ret; + + ret = power_supply_register(dev, &smb->usb); + if (ret < 0) { + power_supply_unregister(&smb->mains); + return ret; + } ret = power_supply_register(dev, &smb->battery); if (ret < 0) { - if (smb->pdata->use_usb) - power_supply_unregister(&smb->usb); - if (smb->pdata->use_mains) - power_supply_unregister(&smb->mains); + power_supply_unregister(&smb->usb); + power_supply_unregister(&smb->mains); return ret; } @@ -1094,15 +1229,15 @@ static int smb347_probe(struct i2c_client *client, * interrupt support here. */ if (pdata->irq_gpio >= 0) { - ret = smb347_irq_init(smb, client); + ret = smb347_irq_init(smb); if (ret < 0) { dev_warn(dev, "failed to initialize IRQ: %d\n", ret); dev_warn(dev, "disabling IRQ support\n"); - } else { - smb347_irq_enable(smb); } } + smb->dentry = debugfs_create_file("smb347-regs", S_IRUSR, NULL, smb, + &smb347_debugfs_fops); return 0; } @@ -1110,6 +1245,9 @@ static int smb347_remove(struct i2c_client *client) { struct smb347_charger *smb = i2c_get_clientdata(client); + if (!IS_ERR_OR_NULL(smb->dentry)) + debugfs_remove(smb->dentry); + if (client->irq) { smb347_irq_disable(smb); free_irq(client->irq, smb); @@ -1117,10 +1255,8 @@ static int smb347_remove(struct i2c_client *client) } power_supply_unregister(&smb->battery); - if (smb->pdata->use_usb) - power_supply_unregister(&smb->usb); - if (smb->pdata->use_mains) - power_supply_unregister(&smb->mains); + power_supply_unregister(&smb->usb); + power_supply_unregister(&smb->mains); return 0; } @@ -1139,7 +1275,17 @@ static struct i2c_driver smb347_driver = { .id_table = smb347_id, }; -module_i2c_driver(smb347_driver); +static int __init smb347_init(void) +{ + return i2c_add_driver(&smb347_driver); +} +module_init(smb347_init); + +static void __exit smb347_exit(void) +{ + i2c_del_driver(&smb347_driver); +} +module_exit(smb347_exit); MODULE_AUTHOR("Bruce E. Robertson "); MODULE_AUTHOR("Mika Westerberg "); diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index c05da00583f0..33a6743ddc55 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -10,6 +10,8 @@ #ifndef DASD_INT_H #define DASD_INT_H +#ifdef __KERNEL__ + /* we keep old device allocation scheme; IOW, minors are still in 0..255 */ #define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS)) #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1) @@ -789,4 +791,6 @@ static inline int dasd_eer_enabled(struct dasd_device *device) #define dasd_eer_enabled(d) (0) #endif /* CONFIG_DASD_ERR */ +#endif /* __KERNEL__ */ + #endif /* DASD_H */ diff --git a/trunk/drivers/s390/char/sclp_sdias.c b/trunk/drivers/s390/char/sclp_sdias.c index 50f7115990ff..69e6c50d4cfb 100644 --- a/trunk/drivers/s390/char/sclp_sdias.c +++ b/trunk/drivers/s390/char/sclp_sdias.c @@ -211,7 +211,7 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) sccb.evbuf.event_qual = EQ_STORE_DATA; sccb.evbuf.data_id = DI_FCP_DUMP; sccb.evbuf.event_id = 4712; -#ifdef CONFIG_64BIT +#ifdef __s390x__ sccb.evbuf.asa_size = ASA_SIZE_64; #else sccb.evbuf.asa_size = ASA_SIZE_32; diff --git a/trunk/drivers/scsi/be2iscsi/be_mgmt.c b/trunk/drivers/scsi/be2iscsi/be_mgmt.c index 2a096795b9aa..01bb04cd9e75 100644 --- a/trunk/drivers/scsi/be2iscsi/be_mgmt.c +++ b/trunk/drivers/scsi/be2iscsi/be_mgmt.c @@ -571,12 +571,13 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba, static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd, int iscsi_cmd, int size) { - cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma); + cmd->va = pci_alloc_consistent(phba->ctrl.pdev, sizeof(size), + &cmd->dma); if (!cmd->va) { SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n"); return -ENOMEM; } - memset(cmd->va, 0, size); + memset(cmd->va, 0, sizeof(size)); cmd->size = size; be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size); return 0; diff --git a/trunk/drivers/scsi/bfa/bfad_attr.c b/trunk/drivers/scsi/bfa/bfad_attr.c index b83927440171..8b6c6bf7837e 100644 --- a/trunk/drivers/scsi/bfa/bfad_attr.c +++ b/trunk/drivers/scsi/bfa/bfad_attr.c @@ -426,23 +426,6 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) vshost = vport->drv_port.im_port->shost; fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn); fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn); - fc_host_supported_classes(vshost) = FC_COS_CLASS3; - - memset(fc_host_supported_fc4s(vshost), 0, - sizeof(fc_host_supported_fc4s(vshost))); - - /* For FCP type 0x08 */ - if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM) - fc_host_supported_fc4s(vshost)[2] = 1; - - /* For fibre channel services type 0x20 */ - fc_host_supported_fc4s(vshost)[7] = 1; - - fc_host_supported_speeds(vshost) = - bfad_im_supported_speeds(&bfad->bfa); - fc_host_maxframe_size(vshost) = - bfa_fcport_get_maxfrsize(&bfad->bfa); - fc_vport->dd_data = vport; vport->drv_port.im_port->fc_vport = fc_vport; } else if (rc == BFA_STATUS_INVALID_WWN) diff --git a/trunk/drivers/scsi/bfa/bfad_im.c b/trunk/drivers/scsi/bfa/bfad_im.c index 1ac09afe35ee..3153923f5b60 100644 --- a/trunk/drivers/scsi/bfa/bfad_im.c +++ b/trunk/drivers/scsi/bfa/bfad_im.c @@ -987,7 +987,7 @@ bfad_im_slave_alloc(struct scsi_device *sdev) return 0; } -u32 +static u32 bfad_im_supported_speeds(struct bfa_s *bfa) { struct bfa_ioc_attr_s *ioc_attr; diff --git a/trunk/drivers/scsi/bfa/bfad_im.h b/trunk/drivers/scsi/bfa/bfad_im.h index f6c1023e502a..0814367ef101 100644 --- a/trunk/drivers/scsi/bfa/bfad_im.h +++ b/trunk/drivers/scsi/bfa/bfad_im.h @@ -37,7 +37,6 @@ int bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port, struct device *dev); void bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port); -u32 bfad_im_supported_speeds(struct bfa_s *bfa); #define MAX_FCP_TARGET 1024 #define MAX_FCP_LUN 16384 diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc.h b/trunk/drivers/scsi/bnx2fc/bnx2fc.h index 0578fa0dc14b..a4953ef9e53a 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc.h +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc.h @@ -62,7 +62,7 @@ #include "bnx2fc_constants.h" #define BNX2FC_NAME "bnx2fc" -#define BNX2FC_VERSION "1.0.11" +#define BNX2FC_VERSION "1.0.10" #define PFX "bnx2fc: " @@ -228,16 +228,13 @@ struct bnx2fc_interface { struct packet_type fip_packet_type; struct workqueue_struct *timer_work_queue; struct kref kref; + struct fcoe_ctlr ctlr; u8 vlan_enabled; int vlan_id; bool enabled; }; -#define bnx2fc_from_ctlr(x) \ - ((struct bnx2fc_interface *)((x) + 1)) - -#define bnx2fc_to_ctlr(x) \ - ((struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1)) +#define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_interface, ctlr) struct bnx2fc_lport { struct list_head list; diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c index bdbbb13b8534..ce0ce3e32f33 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -854,6 +854,7 @@ static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, struct fc_exch *exch = fc_seq_exch(seq); struct fc_lport *lport = exch->lp; u8 *mac; + struct fc_frame_header *fh; u8 op; if (IS_ERR(fp)) @@ -861,6 +862,13 @@ static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, mac = fr_cb(fp)->granted_mac; if (is_zero_ether_addr(mac)) { + fh = fc_frame_header_get(fp); + if (fh->fh_type != FC_TYPE_ELS) { + printk(KERN_ERR PFX "bnx2fc_flogi_resp:" + "fh_type != FC_TYPE_ELS\n"); + fc_frame_free(fp); + return; + } op = fc_frame_payload_op(fp); if (lport->vport) { if (op == ELS_LS_RJT) { @@ -870,10 +878,12 @@ static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, return; } } - fcoe_ctlr_recv_flogi(fip, lport, fp); + if (fcoe_ctlr_recv_flogi(fip, lport, fp)) { + fc_frame_free(fp); + return; + } } - if (!is_zero_ether_addr(mac)) - fip->update_mac(lport, mac); + fip->update_mac(lport, mac); done: fc_lport_flogi_resp(seq, fp, lport); } @@ -900,7 +910,7 @@ struct fc_seq *bnx2fc_elsct_send(struct fc_lport *lport, u32 did, { struct fcoe_port *port = lport_priv(lport); struct bnx2fc_interface *interface = port->priv; - struct fcoe_ctlr *fip = bnx2fc_to_ctlr(interface); + struct fcoe_ctlr *fip = &interface->ctlr; struct fc_frame_header *fh = fc_frame_header_get(fp); switch (op) { diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index f52f668fd247..c1c6a92a0b98 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); #define DRV_MODULE_NAME "bnx2fc" #define DRV_MODULE_VERSION BNX2FC_VERSION -#define DRV_MODULE_RELDATE "Apr 24, 2012" +#define DRV_MODULE_RELDATE "Jan 22, 2011" static char version[] __devinitdata = @@ -54,7 +54,6 @@ static struct cnic_ulp_ops bnx2fc_cnic_cb; static struct libfc_function_template bnx2fc_libfc_fcn_templ; static struct scsi_host_template bnx2fc_shost_template; static struct fc_function_template bnx2fc_transport_function; -static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ; static struct fc_function_template bnx2fc_vport_xport_function; static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); static void __bnx2fc_destroy(struct bnx2fc_interface *interface); @@ -89,7 +88,6 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport); static void bnx2fc_stop(struct bnx2fc_interface *interface); static int __init bnx2fc_mod_init(void); static void __exit bnx2fc_mod_exit(void); -static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev); unsigned int bnx2fc_debug_level; module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); @@ -120,41 +118,6 @@ static void bnx2fc_get_lesb(struct fc_lport *lport, __fcoe_get_lesb(lport, fc_lesb, netdev); } -static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) -{ - struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); - struct net_device *netdev = bnx2fc_netdev(fip->lp); - struct fcoe_fc_els_lesb *fcoe_lesb; - struct fc_els_lesb fc_lesb; - - __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); - fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); - - ctlr_dev->lesb.lesb_link_fail = - ntohl(fcoe_lesb->lesb_link_fail); - ctlr_dev->lesb.lesb_vlink_fail = - ntohl(fcoe_lesb->lesb_vlink_fail); - ctlr_dev->lesb.lesb_miss_fka = - ntohl(fcoe_lesb->lesb_miss_fka); - ctlr_dev->lesb.lesb_symb_err = - ntohl(fcoe_lesb->lesb_symb_err); - ctlr_dev->lesb.lesb_err_block = - ntohl(fcoe_lesb->lesb_err_block); - ctlr_dev->lesb.lesb_fcs_error = - ntohl(fcoe_lesb->lesb_fcs_error); -} -EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb); - -static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) -{ - struct fcoe_ctlr_device *ctlr_dev = - fcoe_fcf_dev_to_ctlr_dev(fcf_dev); - struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); - struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr); - - fcf_dev->vlan_id = fcoe->vlan_id; -} - static void bnx2fc_clean_rx_queue(struct fc_lport *lp) { struct fcoe_percpu_s *bg; @@ -281,7 +244,6 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) struct sk_buff *skb; struct fc_frame_header *fh; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; struct bnx2fc_hba *hba; struct fcoe_port *port; struct fcoe_hdr *hp; @@ -294,7 +256,6 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) port = (struct fcoe_port *)lport_priv(lport); interface = port->priv; - ctlr = bnx2fc_to_ctlr(interface); hba = interface->hba; fh = fc_frame_header_get(fp); @@ -307,12 +268,12 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) } if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) { - if (!ctlr->sel_fcf) { + if (!interface->ctlr.sel_fcf) { BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n"); kfree_skb(skb); return -EINVAL; } - if (fcoe_ctlr_els_send(ctlr, lport, skb)) + if (fcoe_ctlr_els_send(&interface->ctlr, lport, skb)) return 0; } @@ -385,14 +346,14 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) /* fill up mac and fcoe headers */ eh = eth_hdr(skb); eh->h_proto = htons(ETH_P_FCOE); - if (ctlr->map_dest) + if (interface->ctlr.map_dest) fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id); else /* insert GW address */ - memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN); + memcpy(eh->h_dest, interface->ctlr.dest_addr, ETH_ALEN); - if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN)) - memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN); + if (unlikely(interface->ctlr.flogi_oxid != FC_XID_UNKNOWN)) + memcpy(eh->h_source, interface->ctlr.ctl_src_addr, ETH_ALEN); else memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); @@ -442,7 +403,6 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, { struct fc_lport *lport; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; struct fc_frame_header *fh; struct fcoe_rcv_info *fr; struct fcoe_percpu_s *bg; @@ -450,8 +410,7 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, interface = container_of(ptype, struct bnx2fc_interface, fcoe_packet_type); - ctlr = bnx2fc_to_ctlr(interface); - lport = ctlr->lp; + lport = interface->ctlr.lp; if (unlikely(lport == NULL)) { printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n"); @@ -799,13 +758,11 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev) { struct bnx2fc_hba *hba; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; struct fcoe_port *port; u64 wwnn, wwpn; port = lport_priv(lport); interface = port->priv; - ctlr = bnx2fc_to_ctlr(interface); hba = interface->hba; /* require support for get_pauseparam ethtool op. */ @@ -824,13 +781,13 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev) if (!lport->vport) { if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) - wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, + wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 1, 0); BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn); fc_set_wwnn(lport, wwnn); if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) - wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, + wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 2, 0); BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn); @@ -867,7 +824,6 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, struct fc_lport *lport; struct fc_lport *vport; struct bnx2fc_interface *interface, *tmp; - struct fcoe_ctlr *ctlr; int wait_for_upload = 0; u32 link_possible = 1; @@ -918,8 +874,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, if (interface->hba != hba) continue; - ctlr = bnx2fc_to_ctlr(interface); - lport = ctlr->lp; + lport = interface->ctlr.lp; BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n", interface->netdev->name, event); @@ -934,8 +889,8 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, * on a stale vlan */ if (interface->enabled) - fcoe_ctlr_link_up(ctlr); - } else if (fcoe_ctlr_link_down(ctlr)) { + fcoe_ctlr_link_up(&interface->ctlr); + } else if (fcoe_ctlr_link_down(&interface->ctlr)) { mutex_lock(&lport->lp_mutex); list_for_each_entry(vport, &lport->vports, list) fc_host_port_type(vport->host) = @@ -1040,11 +995,9 @@ static int bnx2fc_fip_recv(struct sk_buff *skb, struct net_device *dev, struct net_device *orig_dev) { struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; interface = container_of(ptype, struct bnx2fc_interface, fip_packet_type); - ctlr = bnx2fc_to_ctlr(interface); - fcoe_ctlr_recv(ctlr, skb); + fcoe_ctlr_recv(&interface->ctlr, skb); return 0; } @@ -1202,7 +1155,6 @@ static int bnx2fc_interface_setup(struct bnx2fc_interface *interface) { struct net_device *netdev = interface->netdev; struct net_device *physdev = interface->hba->phys_dev; - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct netdev_hw_addr *ha; int sel_san_mac = 0; @@ -1217,7 +1169,7 @@ static int bnx2fc_interface_setup(struct bnx2fc_interface *interface) if ((ha->type == NETDEV_HW_ADDR_T_SAN) && (is_valid_ether_addr(ha->addr))) { - memcpy(ctlr->ctl_src_addr, ha->addr, + memcpy(interface->ctlr.ctl_src_addr, ha->addr, ETH_ALEN); sel_san_mac = 1; BNX2FC_MISC_DBG("Found SAN MAC\n"); @@ -1272,23 +1224,19 @@ static void bnx2fc_release_transport(void) static void bnx2fc_interface_release(struct kref *kref) { - struct fcoe_ctlr_device *ctlr_dev; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; struct net_device *netdev; interface = container_of(kref, struct bnx2fc_interface, kref); BNX2FC_MISC_DBG("Interface is being released\n"); - ctlr = bnx2fc_to_ctlr(interface); - ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); netdev = interface->netdev; /* tear-down FIP controller */ if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) - fcoe_ctlr_destroy(ctlr); + fcoe_ctlr_destroy(&interface->ctlr); - fcoe_ctlr_device_delete(ctlr_dev); + kfree(interface); dev_put(netdev); module_put(THIS_MODULE); @@ -1381,40 +1329,33 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, struct net_device *netdev, enum fip_state fip_mode) { - struct fcoe_ctlr_device *ctlr_dev; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; - int size; int rc = 0; - size = (sizeof(*interface) + sizeof(struct fcoe_ctlr)); - ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ, - size); - if (!ctlr_dev) { + interface = kzalloc(sizeof(*interface), GFP_KERNEL); + if (!interface) { printk(KERN_ERR PFX "Unable to allocate interface structure\n"); return NULL; } - ctlr = fcoe_ctlr_device_priv(ctlr_dev); - interface = fcoe_ctlr_priv(ctlr); dev_hold(netdev); kref_init(&interface->kref); interface->hba = hba; interface->netdev = netdev; /* Initialize FIP */ - fcoe_ctlr_init(ctlr, fip_mode); - ctlr->send = bnx2fc_fip_send; - ctlr->update_mac = bnx2fc_update_src_mac; - ctlr->get_src_addr = bnx2fc_get_src_mac; + fcoe_ctlr_init(&interface->ctlr, fip_mode); + interface->ctlr.send = bnx2fc_fip_send; + interface->ctlr.update_mac = bnx2fc_update_src_mac; + interface->ctlr.get_src_addr = bnx2fc_get_src_mac; set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags); rc = bnx2fc_interface_setup(interface); if (!rc) return interface; - fcoe_ctlr_destroy(ctlr); + fcoe_ctlr_destroy(&interface->ctlr); dev_put(netdev); - fcoe_ctlr_device_delete(ctlr_dev); + kfree(interface); return NULL; } @@ -1432,7 +1373,6 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct device *parent, int npiv) { - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct fc_lport *lport, *n_port; struct fcoe_port *port; struct Scsi_Host *shost; @@ -1443,7 +1383,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL); if (!blport) { - BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n"); + BNX2FC_HBA_DBG(interface->ctlr.lp, "Unable to alloc blport\n"); return NULL; } @@ -1539,8 +1479,7 @@ static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface) static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) { - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); - struct fc_lport *lport = ctlr->lp; + struct fc_lport *lport = interface->ctlr.lp; struct fcoe_port *port = lport_priv(lport); struct bnx2fc_hba *hba = interface->hba; @@ -1580,8 +1519,7 @@ static void bnx2fc_if_destroy(struct fc_lport *lport) static void __bnx2fc_destroy(struct bnx2fc_interface *interface) { - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); - struct fc_lport *lport = ctlr->lp; + struct fc_lport *lport = interface->ctlr.lp; struct fcoe_port *port = lport_priv(lport); bnx2fc_interface_cleanup(interface); @@ -1605,15 +1543,13 @@ static int bnx2fc_destroy(struct net_device *netdev) { struct bnx2fc_interface *interface = NULL; struct workqueue_struct *timer_work_queue; - struct fcoe_ctlr *ctlr; int rc = 0; rtnl_lock(); mutex_lock(&bnx2fc_dev_lock); interface = bnx2fc_interface_lookup(netdev); - ctlr = bnx2fc_to_ctlr(interface); - if (!interface || !ctlr->lp) { + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n"); goto netdev_err; @@ -1710,7 +1646,6 @@ static void bnx2fc_ulp_start(void *handle) { struct bnx2fc_hba *hba = handle; struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; struct fc_lport *lport; mutex_lock(&bnx2fc_dev_lock); @@ -1722,8 +1657,7 @@ static void bnx2fc_ulp_start(void *handle) list_for_each_entry(interface, &if_list, list) { if (interface->hba == hba) { - ctlr = bnx2fc_to_ctlr(interface); - lport = ctlr->lp; + lport = interface->ctlr.lp; /* Kick off Fabric discovery*/ printk(KERN_ERR PFX "ulp_init: start discovery\n"); lport->tt.frame_send = bnx2fc_xmit; @@ -1743,14 +1677,13 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport) static void bnx2fc_stop(struct bnx2fc_interface *interface) { - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct fc_lport *lport; struct fc_lport *vport; if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) return; - lport = ctlr->lp; + lport = interface->ctlr.lp; bnx2fc_port_shutdown(lport); mutex_lock(&lport->lp_mutex); @@ -1759,7 +1692,7 @@ static void bnx2fc_stop(struct bnx2fc_interface *interface) FC_PORTTYPE_UNKNOWN; mutex_unlock(&lport->lp_mutex); fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; - fcoe_ctlr_link_down(ctlr); + fcoe_ctlr_link_down(&interface->ctlr); fcoe_clean_pending_queue(lport); } @@ -1871,7 +1804,6 @@ static void bnx2fc_ulp_stop(void *handle) static void bnx2fc_start_disc(struct bnx2fc_interface *interface) { - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct fc_lport *lport; int wait_cnt = 0; @@ -1882,18 +1814,18 @@ static void bnx2fc_start_disc(struct bnx2fc_interface *interface) return; } - lport = ctlr->lp; + lport = interface->ctlr.lp; BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n"); if (!bnx2fc_link_ok(lport) && interface->enabled) { BNX2FC_HBA_DBG(lport, "ctlr_link_up\n"); - fcoe_ctlr_link_up(ctlr); + fcoe_ctlr_link_up(&interface->ctlr); fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); } /* wait for the FCF to be selected before issuing FLOGI */ - while (!ctlr->sel_fcf) { + while (!interface->ctlr.sel_fcf) { msleep(250); /* give up after 3 secs */ if (++wait_cnt > 12) @@ -1957,21 +1889,19 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev) static int bnx2fc_disable(struct net_device *netdev) { struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; int rc = 0; rtnl_lock(); mutex_lock(&bnx2fc_dev_lock); interface = bnx2fc_interface_lookup(netdev); - ctlr = bnx2fc_to_ctlr(interface); - if (!interface || !ctlr->lp) { + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); } else { interface->enabled = false; - fcoe_ctlr_link_down(ctlr); - fcoe_clean_pending_queue(ctlr->lp); + fcoe_ctlr_link_down(&interface->ctlr); + fcoe_clean_pending_queue(interface->ctlr.lp); } mutex_unlock(&bnx2fc_dev_lock); @@ -1983,19 +1913,17 @@ static int bnx2fc_disable(struct net_device *netdev) static int bnx2fc_enable(struct net_device *netdev) { struct bnx2fc_interface *interface; - struct fcoe_ctlr *ctlr; int rc = 0; rtnl_lock(); mutex_lock(&bnx2fc_dev_lock); interface = bnx2fc_interface_lookup(netdev); - ctlr = bnx2fc_to_ctlr(interface); - if (!interface || !ctlr->lp) { + if (!interface || !interface->ctlr.lp) { rc = -ENODEV; printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); - } else if (!bnx2fc_link_ok(ctlr->lp)) { - fcoe_ctlr_link_up(ctlr); + } else if (!bnx2fc_link_ok(interface->ctlr.lp)) { + fcoe_ctlr_link_up(&interface->ctlr); interface->enabled = true; } @@ -2016,7 +1944,6 @@ static int bnx2fc_enable(struct net_device *netdev) */ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) { - struct fcoe_ctlr *ctlr; struct bnx2fc_interface *interface; struct bnx2fc_hba *hba; struct net_device *phys_dev; @@ -2083,7 +2010,6 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) goto ifput_err; } - ctlr = bnx2fc_to_ctlr(interface); interface->vlan_id = vlan_id; interface->vlan_enabled = 1; @@ -2109,10 +2035,10 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) lport->boot_time = jiffies; /* Make this master N_port */ - ctlr->lp = lport; + interface->ctlr.lp = lport; if (!bnx2fc_link_ok(lport)) { - fcoe_ctlr_link_up(ctlr); + fcoe_ctlr_link_up(&interface->ctlr); fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); } @@ -2513,19 +2439,6 @@ static void __exit bnx2fc_mod_exit(void) module_init(bnx2fc_mod_init); module_exit(bnx2fc_mod_exit); -static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { - .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, - .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, - .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, - .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, - .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb, - .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb, - .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb, - - .get_fcoe_fcf_selected = fcoe_fcf_get_selected, - .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id, -}; - static struct fc_function_template bnx2fc_transport_function = { .show_host_node_name = 1, .show_host_port_name = 1, diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 2ca6bfe4ce5e..afd570962b8c 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -167,7 +167,6 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, { struct fc_lport *lport = port->lport; struct bnx2fc_interface *interface = port->priv; - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct bnx2fc_hba *hba = interface->hba; struct kwqe *kwqe_arr[4]; struct fcoe_kwqe_conn_offload1 ofld_req1; @@ -315,13 +314,13 @@ int bnx2fc_send_session_ofld_req(struct fcoe_port *port, ofld_req4.src_mac_addr_mid[1] = port->data_src_addr[2]; ofld_req4.src_mac_addr_hi[0] = port->data_src_addr[1]; ofld_req4.src_mac_addr_hi[1] = port->data_src_addr[0]; - ofld_req4.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; + ofld_req4.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; /* fcf mac */ - ofld_req4.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; - ofld_req4.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; - ofld_req4.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; - ofld_req4.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; - ofld_req4.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; + ofld_req4.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + ofld_req4.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + ofld_req4.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + ofld_req4.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + ofld_req4.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma; ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32); @@ -352,7 +351,6 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, { struct kwqe *kwqe_arr[2]; struct bnx2fc_interface *interface = port->priv; - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct bnx2fc_hba *hba = interface->hba; struct fcoe_kwqe_conn_enable_disable enbl_req; struct fc_lport *lport = port->lport; @@ -376,12 +374,12 @@ static int bnx2fc_send_session_enable_req(struct fcoe_port *port, enbl_req.src_mac_addr_hi[1] = port->data_src_addr[0]; memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN); - enbl_req.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; - enbl_req.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; - enbl_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; - enbl_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; - enbl_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; - enbl_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; + enbl_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; + enbl_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + enbl_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + enbl_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + enbl_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + enbl_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; port_id = fc_host_port_id(lport->host); if (port_id != tgt->sid) { @@ -421,7 +419,6 @@ int bnx2fc_send_session_disable_req(struct fcoe_port *port, struct bnx2fc_rport *tgt) { struct bnx2fc_interface *interface = port->priv; - struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); struct bnx2fc_hba *hba = interface->hba; struct fcoe_kwqe_conn_enable_disable disable_req; struct kwqe *kwqe_arr[2]; @@ -443,12 +440,12 @@ int bnx2fc_send_session_disable_req(struct fcoe_port *port, disable_req.src_mac_addr_hi[0] = tgt->src_addr[1]; disable_req.src_mac_addr_hi[1] = tgt->src_addr[0]; - disable_req.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; - disable_req.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; - disable_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; - disable_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; - disable_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; - disable_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; + disable_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; + disable_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; + disable_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; + disable_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; + disable_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; + disable_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; port_id = tgt->sid; disable_req.s_id[0] = (port_id & 0x000000FF); diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c index 4f7453b9e41e..e897ce975bb8 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -810,22 +810,8 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) spin_lock_bh(&tgt->tgt_lock); io_req->wait_for_comp = 0; - if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) { + if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) set_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags); - if (io_req->on_tmf_queue) { - list_del_init(&io_req->link); - io_req->on_tmf_queue = 0; - } - io_req->wait_for_comp = 1; - bnx2fc_initiate_cleanup(io_req); - spin_unlock_bh(&tgt->tgt_lock); - rc = wait_for_completion_timeout(&io_req->tm_done, - BNX2FC_FW_TIMEOUT); - spin_lock_bh(&tgt->tgt_lock); - io_req->wait_for_comp = 0; - if (!rc) - kref_put(&io_req->refcount, bnx2fc_cmd_release); - } spin_unlock_bh(&tgt->tgt_lock); @@ -1103,48 +1089,6 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); } -int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) -{ - struct bnx2fc_rport *tgt = io_req->tgt; - struct fc_rport_priv *rdata = tgt->rdata; - int logo_issued; - int rc = SUCCESS; - int wait_cnt = 0; - - BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n", - tgt->flags); - logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO, - &tgt->flags); - io_req->wait_for_comp = 1; - bnx2fc_initiate_cleanup(io_req); - - spin_unlock_bh(&tgt->tgt_lock); - - wait_for_completion(&io_req->tm_done); - - io_req->wait_for_comp = 0; - /* - * release the reference taken in eh_abort to allow the - * target to re-login after flushing IOs - */ - kref_put(&io_req->refcount, bnx2fc_cmd_release); - - if (!logo_issued) { - clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags); - mutex_lock(&lport->disc.disc_mutex); - lport->tt.rport_logoff(rdata); - mutex_unlock(&lport->disc.disc_mutex); - do { - msleep(BNX2FC_RELOGIN_WAIT_TIME); - if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) { - rc = FAILED; - break; - } - } while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)); - } - spin_lock_bh(&tgt->tgt_lock); - return rc; -} /** * bnx2fc_eh_abort - eh_abort_handler api to abort an outstanding * SCSI command @@ -1159,7 +1103,10 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) struct fc_rport_libfc_priv *rp = rport->dd_data; struct bnx2fc_cmd *io_req; struct fc_lport *lport; + struct fc_rport_priv *rdata; struct bnx2fc_rport *tgt; + int logo_issued; + int wait_cnt = 0; int rc = FAILED; @@ -1236,31 +1183,58 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) list_add_tail(&io_req->link, &tgt->io_retire_queue); init_completion(&io_req->tm_done); + io_req->wait_for_comp = 1; - if (test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) { + if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) { + /* Cancel the current timer running on this io_req */ + if (cancel_delayed_work(&io_req->timeout_work)) + kref_put(&io_req->refcount, + bnx2fc_cmd_release); /* drop timer hold */ + set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags); + rc = bnx2fc_initiate_abts(io_req); + } else { printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) " "already in abts processing\n", io_req->xid); if (cancel_delayed_work(&io_req->timeout_work)) kref_put(&io_req->refcount, bnx2fc_cmd_release); /* drop timer hold */ - rc = bnx2fc_expl_logo(lport, io_req); - goto out; - } - - /* Cancel the current timer running on this io_req */ - if (cancel_delayed_work(&io_req->timeout_work)) - kref_put(&io_req->refcount, - bnx2fc_cmd_release); /* drop timer hold */ - set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags); - io_req->wait_for_comp = 1; - rc = bnx2fc_initiate_abts(io_req); - if (rc == FAILED) { bnx2fc_initiate_cleanup(io_req); + spin_unlock_bh(&tgt->tgt_lock); + wait_for_completion(&io_req->tm_done); + spin_lock_bh(&tgt->tgt_lock); io_req->wait_for_comp = 0; - goto done; + rdata = io_req->tgt->rdata; + logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO, + &tgt->flags); + kref_put(&io_req->refcount, bnx2fc_cmd_release); + spin_unlock_bh(&tgt->tgt_lock); + + if (!logo_issued) { + BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n", + tgt->flags); + mutex_lock(&lport->disc.disc_mutex); + lport->tt.rport_logoff(rdata); + mutex_unlock(&lport->disc.disc_mutex); + do { + msleep(BNX2FC_RELOGIN_WAIT_TIME); + /* + * If session not recovered, let SCSI-ml + * escalate error recovery. + */ + if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) + return FAILED; + } while (!test_bit(BNX2FC_FLAG_SESSION_READY, + &tgt->flags)); + } + return SUCCESS; + } + if (rc == FAILED) { + kref_put(&io_req->refcount, bnx2fc_cmd_release); + spin_unlock_bh(&tgt->tgt_lock); + return rc; } spin_unlock_bh(&tgt->tgt_lock); @@ -1273,8 +1247,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) /* Let the scsi-ml try to recover this command */ printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", io_req->xid); - rc = bnx2fc_expl_logo(lport, io_req); - goto out; + rc = FAILED; } else { /* * We come here even when there was a race condition @@ -1286,10 +1259,9 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) bnx2fc_scsi_done(io_req, DID_ABORT); kref_put(&io_req->refcount, bnx2fc_cmd_release); } -done: + /* release the reference taken in eh_abort */ kref_put(&io_req->refcount, bnx2fc_cmd_release); -out: spin_unlock_bh(&tgt->tgt_lock); return rc; } diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 082a25c3117e..c1800b531270 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -185,16 +185,6 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) BUG_ON(rc); } - list_for_each_safe(list, tmp, &tgt->active_tm_queue) { - i++; - io_req = (struct bnx2fc_cmd *)list; - list_del_init(&io_req->link); - io_req->on_tmf_queue = 0; - BNX2FC_IO_DBG(io_req, "tm_queue cleanup\n"); - if (io_req->wait_for_comp) - complete(&io_req->tm_done); - } - list_for_each_safe(list, tmp, &tgt->els_queue) { i++; io_req = (struct bnx2fc_cmd *)list; @@ -223,17 +213,8 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) BNX2FC_IO_DBG(io_req, "retire_queue flush\n"); - if (cancel_delayed_work(&io_req->timeout_work)) { - if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT, - &io_req->req_flags)) { - /* Handle eh_abort timeout */ - BNX2FC_IO_DBG(io_req, "eh_abort for IO " - "in retire_q\n"); - if (io_req->wait_for_comp) - complete(&io_req->tm_done); - } + if (cancel_delayed_work(&io_req->timeout_work)) kref_put(&io_req->refcount, bnx2fc_cmd_release); - } clear_bit(BNX2FC_FLAG_ISSUE_RRQ, &io_req->req_flags); } diff --git a/trunk/drivers/scsi/fcoe/Makefile b/trunk/drivers/scsi/fcoe/Makefile index aed0f5db3668..f6d37d0271f7 100644 --- a/trunk/drivers/scsi/fcoe/Makefile +++ b/trunk/drivers/scsi/fcoe/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_FCOE) += fcoe.o obj-$(CONFIG_LIBFCOE) += libfcoe.o -libfcoe-objs := fcoe_ctlr.o fcoe_transport.o fcoe_sysfs.o +libfcoe-objs := fcoe_ctlr.o fcoe_transport.o diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index fe30b1b65e1d..76e3d0b5bfa6 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -151,21 +150,6 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled); static int fcoe_vport_disable(struct fc_vport *, bool disable); static void fcoe_set_vport_symbolic_name(struct fc_vport *); static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); -static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *); -static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); - -static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { - .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, - .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, - .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, - .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, - .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb, - .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb, - .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb, - - .get_fcoe_fcf_selected = fcoe_fcf_get_selected, - .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id, -}; static struct libfc_function_template fcoe_libfc_fcn_templ = { .frame_send = fcoe_xmit, @@ -298,7 +282,7 @@ static struct scsi_host_template fcoe_shost_template = { static int fcoe_interface_setup(struct fcoe_interface *fcoe, struct net_device *netdev) { - struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); + struct fcoe_ctlr *fip = &fcoe->ctlr; struct netdev_hw_addr *ha; struct net_device *real_dev; u8 flogi_maddr[ETH_ALEN]; @@ -382,10 +366,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, enum fip_state fip_mode) { - struct fcoe_ctlr_device *ctlr_dev; - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; - int size; int err; if (!try_module_get(THIS_MODULE)) { @@ -395,32 +376,27 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, goto out; } - size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); - ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ, - size); - if (!ctlr_dev) { - FCOE_DBG("Failed to add fcoe_ctlr_device\n"); + fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); + if (!fcoe) { + FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); fcoe = ERR_PTR(-ENOMEM); goto out_putmod; } - ctlr = fcoe_ctlr_device_priv(ctlr_dev); - fcoe = fcoe_ctlr_priv(ctlr); - dev_hold(netdev); /* * Initialize FIP. */ - fcoe_ctlr_init(ctlr, fip_mode); - ctlr->send = fcoe_fip_send; - ctlr->update_mac = fcoe_update_src_mac; - ctlr->get_src_addr = fcoe_get_src_mac; + fcoe_ctlr_init(&fcoe->ctlr, fip_mode); + fcoe->ctlr.send = fcoe_fip_send; + fcoe->ctlr.update_mac = fcoe_update_src_mac; + fcoe->ctlr.get_src_addr = fcoe_get_src_mac; err = fcoe_interface_setup(fcoe, netdev); if (err) { - fcoe_ctlr_destroy(ctlr); - fcoe_ctlr_device_delete(ctlr_dev); + fcoe_ctlr_destroy(&fcoe->ctlr); + kfree(fcoe); dev_put(netdev); fcoe = ERR_PTR(err); goto out_putmod; @@ -443,7 +419,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, static void fcoe_interface_remove(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; - struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); + struct fcoe_ctlr *fip = &fcoe->ctlr; u8 flogi_maddr[ETH_ALEN]; const struct net_device_ops *ops; @@ -486,8 +462,7 @@ static void fcoe_interface_remove(struct fcoe_interface *fcoe) static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; - struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); - struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); + struct fcoe_ctlr *fip = &fcoe->ctlr; rtnl_lock(); if (!fcoe->removed) @@ -497,8 +472,8 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) /* Release the self-reference taken during fcoe_interface_create() */ /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); - scsi_host_put(fip->lp->host); - fcoe_ctlr_device_delete(ctlr_dev); + scsi_host_put(fcoe->ctlr.lp->host); + kfree(fcoe); dev_put(netdev); module_put(THIS_MODULE); } @@ -518,11 +493,9 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, struct net_device *orig_dev) { struct fcoe_interface *fcoe; - struct fcoe_ctlr *ctlr; fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type); - ctlr = fcoe_to_ctlr(fcoe); - fcoe_ctlr_recv(ctlr, skb); + fcoe_ctlr_recv(&fcoe->ctlr, skb); return 0; } @@ -672,13 +645,11 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) u32 mfs; u64 wwnn, wwpn; struct fcoe_interface *fcoe; - struct fcoe_ctlr *ctlr; struct fcoe_port *port; /* Setup lport private data to point to fcoe softc */ port = lport_priv(lport); fcoe = port->priv; - ctlr = fcoe_to_ctlr(fcoe); /* * Determine max frame size based on underlying device and optional @@ -705,10 +676,10 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) if (!lport->vport) { if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) - wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0); + wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); fc_set_wwnn(lport, wwnn); if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) - wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, + wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 2, 0); fc_set_wwpn(lport, wwpn); } @@ -1085,7 +1056,6 @@ static int fcoe_ddp_done(struct fc_lport *lport, u16 xid) static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, struct device *parent, int npiv) { - struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); struct net_device *netdev = fcoe->netdev; struct fc_lport *lport, *n_port; struct fcoe_port *port; @@ -1149,7 +1119,7 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, } /* Initialize the library */ - rc = fcoe_libfc_config(lport, ctlr, &fcoe_libfc_fcn_templ, 1); + rc = fcoe_libfc_config(lport, &fcoe->ctlr, &fcoe_libfc_fcn_templ, 1); if (rc) { FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " "interface\n"); @@ -1416,7 +1386,6 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, { struct fc_lport *lport; struct fcoe_rcv_info *fr; - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct fc_frame_header *fh; struct fcoe_percpu_s *fps; @@ -1424,8 +1393,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, unsigned int cpu; fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); - ctlr = fcoe_to_ctlr(fcoe); - lport = ctlr->lp; + lport = fcoe->ctlr.lp; if (unlikely(!lport)) { FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); goto err2; @@ -1441,8 +1409,8 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, eh = eth_hdr(skb); - if (is_fip_mode(ctlr) && - compare_ether_addr(eh->h_source, ctlr->dest_addr)) { + if (is_fip_mode(&fcoe->ctlr) && + compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) { FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", eh->h_source); goto err; @@ -1576,7 +1544,6 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) unsigned int elen; /* eth header, may include vlan */ struct fcoe_port *port = lport_priv(lport); struct fcoe_interface *fcoe = port->priv; - struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); u8 sof, eof; struct fcoe_hdr *hp; @@ -1592,7 +1559,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) } if (unlikely(fh->fh_type == FC_TYPE_ELS) && - fcoe_ctlr_els_send(ctlr, lport, skb)) + fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) return 0; sof = fr_sof(fp); @@ -1656,12 +1623,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) /* fill up mac and fcoe headers */ eh = eth_hdr(skb); eh->h_proto = htons(ETH_P_FCOE); - memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN); - if (ctlr->map_dest) + memcpy(eh->h_dest, fcoe->ctlr.dest_addr, ETH_ALEN); + if (fcoe->ctlr.map_dest) memcpy(eh->h_dest + 3, fh->fh_d_id, 3); - if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN)) - memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN); + if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN)) + memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); else memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); @@ -1710,7 +1677,6 @@ static void fcoe_percpu_flush_done(struct sk_buff *skb) static inline int fcoe_filter_frames(struct fc_lport *lport, struct fc_frame *fp) { - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct fc_frame_header *fh; struct sk_buff *skb = (struct sk_buff *)fp; @@ -1732,8 +1698,7 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, return 0; fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; - ctlr = fcoe_to_ctlr(fcoe); - if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && + if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); return -EINVAL; @@ -1912,7 +1877,6 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, ulong event, void *ptr) { struct dcb_app_type *entry = ptr; - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct net_device *netdev; struct fcoe_port *port; @@ -1930,8 +1894,6 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, if (!fcoe) return NOTIFY_OK; - ctlr = fcoe_to_ctlr(fcoe); - if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) prio = ffs(entry->app.priority) - 1; else @@ -1942,10 +1904,10 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, if (entry->app.protocol == ETH_P_FIP || entry->app.protocol == ETH_P_FCOE) - ctlr->priority = prio; + fcoe->ctlr.priority = prio; if (entry->app.protocol == ETH_P_FCOE) { - port = lport_priv(ctlr->lp); + port = lport_priv(fcoe->ctlr.lp); port->priority = prio; } @@ -1967,7 +1929,6 @@ static int fcoe_device_notification(struct notifier_block *notifier, { struct fc_lport *lport = NULL; struct net_device *netdev = ptr; - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct fcoe_port *port; struct fcoe_dev_stats *stats; @@ -1977,8 +1938,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, list_for_each_entry(fcoe, &fcoe_hostlist, list) { if (fcoe->netdev == netdev) { - ctlr = fcoe_to_ctlr(fcoe); - lport = ctlr->lp; + lport = fcoe->ctlr.lp; break; } } @@ -2007,7 +1967,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, break; case NETDEV_UNREGISTER: list_del(&fcoe->list); - port = lport_priv(ctlr->lp); + port = lport_priv(fcoe->ctlr.lp); queue_work(fcoe_wq, &port->destroy_work); goto out; break; @@ -2022,8 +1982,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, fcoe_link_speed_update(lport); if (link_possible && !fcoe_link_ok(lport)) - fcoe_ctlr_link_up(ctlr); - else if (fcoe_ctlr_link_down(ctlr)) { + fcoe_ctlr_link_up(&fcoe->ctlr); + else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { stats = per_cpu_ptr(lport->dev_stats, get_cpu()); stats->LinkFailureCount++; put_cpu(); @@ -2043,7 +2003,6 @@ static int fcoe_device_notification(struct notifier_block *notifier, */ static int fcoe_disable(struct net_device *netdev) { - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; int rc = 0; @@ -2054,9 +2013,8 @@ static int fcoe_disable(struct net_device *netdev) rtnl_unlock(); if (fcoe) { - ctlr = fcoe_to_ctlr(fcoe); - fcoe_ctlr_link_down(ctlr); - fcoe_clean_pending_queue(ctlr->lp); + fcoe_ctlr_link_down(&fcoe->ctlr); + fcoe_clean_pending_queue(fcoe->ctlr.lp); } else rc = -ENODEV; @@ -2074,7 +2032,6 @@ static int fcoe_disable(struct net_device *netdev) */ static int fcoe_enable(struct net_device *netdev) { - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; int rc = 0; @@ -2083,17 +2040,11 @@ static int fcoe_enable(struct net_device *netdev) fcoe = fcoe_hostlist_lookup_port(netdev); rtnl_unlock(); - if (!fcoe) { + if (!fcoe) rc = -ENODEV; - goto out; - } - - ctlr = fcoe_to_ctlr(fcoe); - - if (!fcoe_link_ok(ctlr->lp)) - fcoe_ctlr_link_up(ctlr); + else if (!fcoe_link_ok(fcoe->ctlr.lp)) + fcoe_ctlr_link_up(&fcoe->ctlr); -out: mutex_unlock(&fcoe_config_mutex); return rc; } @@ -2108,7 +2059,6 @@ static int fcoe_enable(struct net_device *netdev) */ static int fcoe_destroy(struct net_device *netdev) { - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct fc_lport *lport; struct fcoe_port *port; @@ -2121,8 +2071,7 @@ static int fcoe_destroy(struct net_device *netdev) rc = -ENODEV; goto out_nodev; } - ctlr = fcoe_to_ctlr(fcoe); - lport = ctlr->lp; + lport = fcoe->ctlr.lp; port = lport_priv(lport); list_del(&fcoe->list); queue_work(fcoe_wq, &port->destroy_work); @@ -2177,8 +2126,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) int dcbx; u8 fup, up; struct net_device *netdev = fcoe->realdev; - struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); - struct fcoe_port *port = lport_priv(ctlr->lp); + struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); struct dcb_app app = { .priority = 0, .protocol = ETH_P_FCOE @@ -2201,7 +2149,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) } port->priority = ffs(up) ? ffs(up) - 1 : 0; - ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority; + fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; } #endif } @@ -2218,8 +2166,6 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) { int rc = 0; - struct fcoe_ctlr_device *ctlr_dev; - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; struct fc_lport *lport; @@ -2238,9 +2184,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) goto out_nodev; } - ctlr = fcoe_to_ctlr(fcoe); - ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); - lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0); + lport = fcoe_if_create(fcoe, &netdev->dev, 0); if (IS_ERR(lport)) { printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", netdev->name); @@ -2251,7 +2195,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) } /* Make this the "master" N_Port */ - ctlr->lp = lport; + fcoe->ctlr.lp = lport; /* setup DCB priority attributes. */ fcoe_dcb_create(fcoe); @@ -2264,7 +2208,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) fc_fabric_login(lport); if (!fcoe_link_ok(lport)) { rtnl_unlock(); - fcoe_ctlr_link_up(ctlr); + fcoe_ctlr_link_up(&fcoe->ctlr); mutex_unlock(&fcoe_config_mutex); return rc; } @@ -2376,12 +2320,11 @@ static int fcoe_reset(struct Scsi_Host *shost) struct fc_lport *lport = shost_priv(shost); struct fcoe_port *port = lport_priv(lport); struct fcoe_interface *fcoe = port->priv; - struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); - fcoe_ctlr_link_down(ctlr); - fcoe_clean_pending_queue(ctlr->lp); - if (!fcoe_link_ok(ctlr->lp)) - fcoe_ctlr_link_up(ctlr); + fcoe_ctlr_link_down(&fcoe->ctlr); + fcoe_clean_pending_queue(fcoe->ctlr.lp); + if (!fcoe_link_ok(fcoe->ctlr.lp)) + fcoe_ctlr_link_up(&fcoe->ctlr); return 0; } @@ -2416,12 +2359,10 @@ fcoe_hostlist_lookup_port(const struct net_device *netdev) */ static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) { - struct fcoe_ctlr *ctlr; struct fcoe_interface *fcoe; fcoe = fcoe_hostlist_lookup_port(netdev); - ctlr = fcoe_to_ctlr(fcoe); - return (fcoe) ? ctlr->lp : NULL; + return (fcoe) ? fcoe->ctlr.lp : NULL; } /** @@ -2525,7 +2466,6 @@ module_init(fcoe_init); static void __exit fcoe_exit(void) { struct fcoe_interface *fcoe, *tmp; - struct fcoe_ctlr *ctlr; struct fcoe_port *port; unsigned int cpu; @@ -2537,8 +2477,7 @@ static void __exit fcoe_exit(void) rtnl_lock(); list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { list_del(&fcoe->list); - ctlr = fcoe_to_ctlr(fcoe); - port = lport_priv(ctlr->lp); + port = lport_priv(fcoe->ctlr.lp); queue_work(fcoe_wq, &port->destroy_work); } rtnl_unlock(); @@ -2634,7 +2573,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, { struct fcoe_port *port = lport_priv(lport); struct fcoe_interface *fcoe = port->priv; - struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); + struct fcoe_ctlr *fip = &fcoe->ctlr; struct fc_frame_header *fh = fc_frame_header_get(fp); switch (op) { @@ -2791,40 +2730,6 @@ static void fcoe_get_lesb(struct fc_lport *lport, __fcoe_get_lesb(lport, fc_lesb, netdev); } -static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) -{ - struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); - struct net_device *netdev = fcoe_netdev(fip->lp); - struct fcoe_fc_els_lesb *fcoe_lesb; - struct fc_els_lesb fc_lesb; - - __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); - fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); - - ctlr_dev->lesb.lesb_link_fail = - ntohl(fcoe_lesb->lesb_link_fail); - ctlr_dev->lesb.lesb_vlink_fail = - ntohl(fcoe_lesb->lesb_vlink_fail); - ctlr_dev->lesb.lesb_miss_fka = - ntohl(fcoe_lesb->lesb_miss_fka); - ctlr_dev->lesb.lesb_symb_err = - ntohl(fcoe_lesb->lesb_symb_err); - ctlr_dev->lesb.lesb_err_block = - ntohl(fcoe_lesb->lesb_err_block); - ctlr_dev->lesb.lesb_fcs_error = - ntohl(fcoe_lesb->lesb_fcs_error); -} - -static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) -{ - struct fcoe_ctlr_device *ctlr_dev = - fcoe_fcf_dev_to_ctlr_dev(fcf_dev); - struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); - struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr); - - fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev); -} - /** * fcoe_set_port_id() - Callback from libfc when Port_ID is set. * @lport: the local port @@ -2842,8 +2747,7 @@ static void fcoe_set_port_id(struct fc_lport *lport, { struct fcoe_port *port = lport_priv(lport); struct fcoe_interface *fcoe = port->priv; - struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) - fcoe_ctlr_recv_flogi(ctlr, lport, fp); + fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); } diff --git a/trunk/drivers/scsi/fcoe/fcoe.h b/trunk/drivers/scsi/fcoe/fcoe.h index a624add4f8ec..96ac938d39cc 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.h +++ b/trunk/drivers/scsi/fcoe/fcoe.h @@ -68,6 +68,7 @@ do { \ * @netdev: The associated net device * @fcoe_packet_type: FCoE packet type * @fip_packet_type: FIP packet type + * @ctlr: The FCoE controller (for FIP) * @oem: The offload exchange manager for all local port * instances associated with this port * @removed: Indicates fcoe interface removed from net device @@ -79,15 +80,12 @@ struct fcoe_interface { struct net_device *realdev; struct packet_type fcoe_packet_type; struct packet_type fip_packet_type; + struct fcoe_ctlr ctlr; struct fc_exch_mgr *oem; u8 removed; }; -#define fcoe_to_ctlr(x) \ - (struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1) - -#define fcoe_from_ctlr(x) \ - ((struct fcoe_interface *)((x) + 1)) +#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) /** * fcoe_netdev() - Return the net device associated with a local port diff --git a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c index d68d57241ee6..5a4c7250aa77 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c @@ -160,76 +160,6 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode) } EXPORT_SYMBOL(fcoe_ctlr_init); -static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) -{ - struct fcoe_ctlr *fip = new->fip; - struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); - struct fcoe_fcf_device temp, *fcf_dev; - int rc = 0; - - LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n", - new->fabric_name, new->fcf_mac); - - mutex_lock(&ctlr_dev->lock); - - temp.fabric_name = new->fabric_name; - temp.switch_name = new->switch_name; - temp.fc_map = new->fc_map; - temp.vfid = new->vfid; - memcpy(temp.mac, new->fcf_mac, ETH_ALEN); - temp.priority = new->pri; - temp.fka_period = new->fka_period; - temp.selected = 0; /* default to unselected */ - - fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp); - if (unlikely(!fcf_dev)) { - rc = -ENOMEM; - goto out; - } - - /* - * The fcoe_sysfs layer can return a CONNECTED fcf that - * has a priv (fcf was never deleted) or a CONNECTED fcf - * that doesn't have a priv (fcf was deleted). However, - * libfcoe will always delete FCFs before trying to add - * them. This is ensured because both recv_adv and - * age_fcfs are protected by the the fcoe_ctlr's mutex. - * This means that we should never get a FCF with a - * non-NULL priv pointer. - */ - BUG_ON(fcf_dev->priv); - - fcf_dev->priv = new; - new->fcf_dev = fcf_dev; - - list_add(&new->list, &fip->fcfs); - fip->fcf_count++; - -out: - mutex_unlock(&ctlr_dev->lock); - return rc; -} - -static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new) -{ - struct fcoe_ctlr *fip = new->fip; - struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); - struct fcoe_fcf_device *fcf_dev; - - list_del(&new->list); - fip->fcf_count--; - - mutex_lock(&ctlr_dev->lock); - - fcf_dev = fcoe_fcf_to_fcf_dev(new); - WARN_ON(!fcf_dev); - new->fcf_dev = NULL; - fcoe_fcf_device_delete(fcf_dev); - kfree(new); - - mutex_unlock(&ctlr_dev->lock); -} - /** * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller * @fip: The FCoE controller whose FCFs are to be reset @@ -243,10 +173,10 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) fip->sel_fcf = NULL; list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { - fcoe_sysfs_fcf_del(fcf); + list_del(&fcf->list); + kfree(fcf); } - WARN_ON(fip->fcf_count); - + fip->fcf_count = 0; fip->sel_time = 0; } @@ -787,11 +717,8 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); unsigned long deadline; unsigned long sel_time = 0; - struct list_head del_list; struct fcoe_dev_stats *stats; - INIT_LIST_HEAD(&del_list); - stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu()); list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { @@ -812,13 +739,10 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) if (time_after_eq(jiffies, deadline)) { if (fip->sel_fcf == fcf) fip->sel_fcf = NULL; - /* - * Move to delete list so we can call - * fcoe_sysfs_fcf_del (which can sleep) - * after the put_cpu(). - */ list_del(&fcf->list); - list_add(&fcf->list, &del_list); + WARN_ON(!fip->fcf_count); + fip->fcf_count--; + kfree(fcf); stats->VLinkFailureCount++; } else { if (time_after(next_timer, deadline)) @@ -829,12 +753,6 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) } } put_cpu(); - - list_for_each_entry_safe(fcf, next, &del_list, list) { - /* Removes fcf from current list */ - fcoe_sysfs_fcf_del(fcf); - } - if (sel_time && !fip->sel_fcf && !fip->sel_time) { sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY); fip->sel_time = sel_time; @@ -985,23 +903,23 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) { struct fcoe_fcf *fcf; struct fcoe_fcf new; + struct fcoe_fcf *found; unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV); int first = 0; int mtu_valid; - int found = 0; - int rc = 0; if (fcoe_ctlr_parse_adv(fip, skb, &new)) return; mutex_lock(&fip->ctlr_mutex); first = list_empty(&fip->fcfs); + found = NULL; list_for_each_entry(fcf, &fip->fcfs, list) { if (fcf->switch_name == new.switch_name && fcf->fabric_name == new.fabric_name && fcf->fc_map == new.fc_map && compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) { - found = 1; + found = fcf; break; } } @@ -1013,16 +931,9 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) if (!fcf) goto out; + fip->fcf_count++; memcpy(fcf, &new, sizeof(new)); - fcf->fip = fip; - rc = fcoe_sysfs_fcf_add(fcf); - if (rc) { - printk(KERN_ERR "Failed to allocate sysfs instance " - "for FCF, fab %16.16llx mac %pM\n", - new.fabric_name, new.fcf_mac); - kfree(fcf); - goto out; - } + list_add(&fcf->list, &fip->fcfs); } else { /* * Update the FCF's keep-alive descriptor flags. @@ -1043,7 +954,6 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) fcf->fka_period = new.fka_period; memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN); } - mtu_valid = fcoe_ctlr_mtu_valid(fcf); fcf->time = jiffies; if (!found) @@ -1086,7 +996,6 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) time_before(fip->sel_time, fip->timer.expires)) mod_timer(&fip->timer, fip->sel_time); } - out: mutex_unlock(&fip->ctlr_mutex); } @@ -2809,9 +2718,9 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip) /** * fcoe_libfc_config() - Sets up libfc related properties for local port - * @lport: The local port to configure libfc for - * @fip: The FCoE controller in use by the local port - * @tt: The libfc function template + * @lp: The local port to configure libfc for + * @fip: The FCoE controller in use by the local port + * @tt: The libfc function template * @init_fcp: If non-zero, the FCP portion of libfc should be initialized * * Returns : 0 for success @@ -2844,43 +2753,3 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, return 0; } EXPORT_SYMBOL_GPL(fcoe_libfc_config); - -void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev) -{ - struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev); - struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); - struct fcoe_fcf *fcf; - - mutex_lock(&fip->ctlr_mutex); - mutex_lock(&ctlr_dev->lock); - - fcf = fcoe_fcf_device_priv(fcf_dev); - if (fcf) - fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0; - else - fcf_dev->selected = 0; - - mutex_unlock(&ctlr_dev->lock); - mutex_unlock(&fip->ctlr_mutex); -} -EXPORT_SYMBOL(fcoe_fcf_get_selected); - -void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev) -{ - struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); - - mutex_lock(&ctlr->ctlr_mutex); - switch (ctlr->mode) { - case FIP_MODE_FABRIC: - ctlr_dev->mode = FIP_CONN_TYPE_FABRIC; - break; - case FIP_MODE_VN2VN: - ctlr_dev->mode = FIP_CONN_TYPE_VN2VN; - break; - default: - ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN; - break; - } - mutex_unlock(&ctlr->ctlr_mutex); -} -EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode); diff --git a/trunk/drivers/scsi/fcoe/fcoe_sysfs.c b/trunk/drivers/scsi/fcoe/fcoe_sysfs.c deleted file mode 100644 index 2bc163198d33..000000000000 --- a/trunk/drivers/scsi/fcoe/fcoe_sysfs.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright(c) 2011 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#include -#include -#include -#include - -#include - -static atomic_t ctlr_num; -static atomic_t fcf_num; - -/* - * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs - * should insulate the loss of a fcf. - */ -static unsigned int fcoe_fcf_dev_loss_tmo = 1800; /* seconds */ - -module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo, - uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(fcf_dev_loss_tmo, - "Maximum number of seconds that libfcoe should" - " insulate the loss of a fcf. Once this value is" - " exceeded, the fcf is removed."); - -/* - * These are used by the fcoe_*_show_function routines, they - * are intentionally placed in the .c file as they're not intended - * for use throughout the code. - */ -#define fcoe_ctlr_id(x) \ - ((x)->id) -#define fcoe_ctlr_work_q_name(x) \ - ((x)->work_q_name) -#define fcoe_ctlr_work_q(x) \ - ((x)->work_q) -#define fcoe_ctlr_devloss_work_q_name(x) \ - ((x)->devloss_work_q_name) -#define fcoe_ctlr_devloss_work_q(x) \ - ((x)->devloss_work_q) -#define fcoe_ctlr_mode(x) \ - ((x)->mode) -#define fcoe_ctlr_fcf_dev_loss_tmo(x) \ - ((x)->fcf_dev_loss_tmo) -#define fcoe_ctlr_link_fail(x) \ - ((x)->lesb.lesb_link_fail) -#define fcoe_ctlr_vlink_fail(x) \ - ((x)->lesb.lesb_vlink_fail) -#define fcoe_ctlr_miss_fka(x) \ - ((x)->lesb.lesb_miss_fka) -#define fcoe_ctlr_symb_err(x) \ - ((x)->lesb.lesb_symb_err) -#define fcoe_ctlr_err_block(x) \ - ((x)->lesb.lesb_err_block) -#define fcoe_ctlr_fcs_error(x) \ - ((x)->lesb.lesb_fcs_error) -#define fcoe_fcf_state(x) \ - ((x)->state) -#define fcoe_fcf_fabric_name(x) \ - ((x)->fabric_name) -#define fcoe_fcf_switch_name(x) \ - ((x)->switch_name) -#define fcoe_fcf_fc_map(x) \ - ((x)->fc_map) -#define fcoe_fcf_vfid(x) \ - ((x)->vfid) -#define fcoe_fcf_mac(x) \ - ((x)->mac) -#define fcoe_fcf_priority(x) \ - ((x)->priority) -#define fcoe_fcf_fka_period(x) \ - ((x)->fka_period) -#define fcoe_fcf_dev_loss_tmo(x) \ - ((x)->dev_loss_tmo) -#define fcoe_fcf_selected(x) \ - ((x)->selected) -#define fcoe_fcf_vlan_id(x) \ - ((x)->vlan_id) - -/* - * dev_loss_tmo attribute - */ -static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val) -{ - int ret; - - ret = kstrtoul(buf, 0, val); - if (ret || *val < 0) - return -EINVAL; - /* - * Check for overflow; dev_loss_tmo is u32 - */ - if (*val > UINT_MAX) - return -EINVAL; - - return 0; -} - -static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf, - unsigned long val) -{ - if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) || - (fcf->state == FCOE_FCF_STATE_DISCONNECTED) || - (fcf->state == FCOE_FCF_STATE_DELETED)) - return -EBUSY; - /* - * Check for overflow; dev_loss_tmo is u32 - */ - if (val > UINT_MAX) - return -EINVAL; - - fcoe_fcf_dev_loss_tmo(fcf) = val; - return 0; -} - -#define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store) \ -struct device_attribute device_attr_fcoe_##_prefix##_##_name = \ - __ATTR(_name, _mode, _show, _store) - -#define fcoe_ctlr_show_function(field, format_string, sz, cast) \ -static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ - if (ctlr->f->get_fcoe_ctlr_##field) \ - ctlr->f->get_fcoe_ctlr_##field(ctlr); \ - return snprintf(buf, sz, format_string, \ - cast fcoe_ctlr_##field(ctlr)); \ -} - -#define fcoe_fcf_show_function(field, format_string, sz, cast) \ -static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ - struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); \ - if (ctlr->f->get_fcoe_fcf_##field) \ - ctlr->f->get_fcoe_fcf_##field(fcf); \ - return snprintf(buf, sz, format_string, \ - cast fcoe_fcf_##field(fcf)); \ -} - -#define fcoe_ctlr_private_show_function(field, format_string, sz, cast) \ -static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ - return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \ -} - -#define fcoe_fcf_private_show_function(field, format_string, sz, cast) \ -static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ - return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \ -} - -#define fcoe_ctlr_private_rd_attr(field, format_string, sz) \ - fcoe_ctlr_private_show_function(field, format_string, sz, ) \ - static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ - show_fcoe_ctlr_device_##field, NULL) - -#define fcoe_ctlr_rd_attr(field, format_string, sz) \ - fcoe_ctlr_show_function(field, format_string, sz, ) \ - static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ - show_fcoe_ctlr_device_##field, NULL) - -#define fcoe_fcf_rd_attr(field, format_string, sz) \ - fcoe_fcf_show_function(field, format_string, sz, ) \ - static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ - show_fcoe_fcf_device_##field, NULL) - -#define fcoe_fcf_private_rd_attr(field, format_string, sz) \ - fcoe_fcf_private_show_function(field, format_string, sz, ) \ - static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ - show_fcoe_fcf_device_##field, NULL) - -#define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast) \ - fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \ - static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ - show_fcoe_ctlr_device_##field, NULL) - -#define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast) \ - fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \ - static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ - show_fcoe_fcf_device_##field, NULL) - -#define fcoe_enum_name_search(title, table_type, table) \ -static const char *get_fcoe_##title##_name(enum table_type table_key) \ -{ \ - int i; \ - char *name = NULL; \ - \ - for (i = 0; i < ARRAY_SIZE(table); i++) { \ - if (table[i].value == table_key) { \ - name = table[i].name; \ - break; \ - } \ - } \ - return name; \ -} - -static struct { - enum fcf_state value; - char *name; -} fcf_state_names[] = { - { FCOE_FCF_STATE_UNKNOWN, "Unknown" }, - { FCOE_FCF_STATE_DISCONNECTED, "Disconnected" }, - { FCOE_FCF_STATE_CONNECTED, "Connected" }, -}; -fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names) -#define FCOE_FCF_STATE_MAX_NAMELEN 50 - -static ssize_t show_fcf_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct fcoe_fcf_device *fcf = dev_to_fcf(dev); - const char *name; - name = get_fcoe_fcf_state_name(fcf->state); - if (!name) - return -EINVAL; - return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name); -} -static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL); - -static struct { - enum fip_conn_type value; - char *name; -} fip_conn_type_names[] = { - { FIP_CONN_TYPE_UNKNOWN, "Unknown" }, - { FIP_CONN_TYPE_FABRIC, "Fabric" }, - { FIP_CONN_TYPE_VN2VN, "VN2VN" }, -}; -fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names) -#define FCOE_CTLR_MODE_MAX_NAMELEN 50 - -static ssize_t show_ctlr_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); - const char *name; - - if (ctlr->f->get_fcoe_ctlr_mode) - ctlr->f->get_fcoe_ctlr_mode(ctlr); - - name = get_fcoe_ctlr_mode_name(ctlr->mode); - if (!name) - return -EINVAL; - return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN, - "%s\n", name); -} -static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO, - show_ctlr_mode, NULL); - -static ssize_t -store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); - struct fcoe_fcf_device *fcf; - unsigned long val; - int rc; - - rc = fcoe_str_to_dev_loss(buf, &val); - if (rc) - return rc; - - fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val; - mutex_lock(&ctlr->lock); - list_for_each_entry(fcf, &ctlr->fcfs, peers) - fcoe_fcf_set_dev_loss_tmo(fcf, val); - mutex_unlock(&ctlr->lock); - return count; -} -fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, ); -static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR, - show_fcoe_ctlr_device_fcf_dev_loss_tmo, - store_private_fcoe_ctlr_fcf_dev_loss_tmo); - -/* Link Error Status Block (LESB) */ -fcoe_ctlr_rd_attr(link_fail, "%u\n", 20); -fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20); -fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20); -fcoe_ctlr_rd_attr(symb_err, "%u\n", 20); -fcoe_ctlr_rd_attr(err_block, "%u\n", 20); -fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20); - -fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); -fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long); -fcoe_fcf_private_rd_attr(priority, "%u\n", 20); -fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20); -fcoe_fcf_private_rd_attr(vfid, "%u\n", 20); -fcoe_fcf_private_rd_attr(mac, "%pM\n", 20); -fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20); -fcoe_fcf_rd_attr(selected, "%u\n", 20); -fcoe_fcf_rd_attr(vlan_id, "%u\n", 20); - -fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, ) -static ssize_t -store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fcoe_fcf_device *fcf = dev_to_fcf(dev); - unsigned long val; - int rc; - - rc = fcoe_str_to_dev_loss(buf, &val); - if (rc) - return rc; - - rc = fcoe_fcf_set_dev_loss_tmo(fcf, val); - if (rc) - return rc; - return count; -} -static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR, - show_fcoe_fcf_device_dev_loss_tmo, - store_fcoe_fcf_dev_loss_tmo); - -static struct attribute *fcoe_ctlr_lesb_attrs[] = { - &device_attr_fcoe_ctlr_link_fail.attr, - &device_attr_fcoe_ctlr_vlink_fail.attr, - &device_attr_fcoe_ctlr_miss_fka.attr, - &device_attr_fcoe_ctlr_symb_err.attr, - &device_attr_fcoe_ctlr_err_block.attr, - &device_attr_fcoe_ctlr_fcs_error.attr, - NULL, -}; - -static struct attribute_group fcoe_ctlr_lesb_attr_group = { - .name = "lesb", - .attrs = fcoe_ctlr_lesb_attrs, -}; - -static struct attribute *fcoe_ctlr_attrs[] = { - &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr, - &device_attr_fcoe_ctlr_mode.attr, - NULL, -}; - -static struct attribute_group fcoe_ctlr_attr_group = { - .attrs = fcoe_ctlr_attrs, -}; - -static const struct attribute_group *fcoe_ctlr_attr_groups[] = { - &fcoe_ctlr_attr_group, - &fcoe_ctlr_lesb_attr_group, - NULL, -}; - -static struct attribute *fcoe_fcf_attrs[] = { - &device_attr_fcoe_fcf_fabric_name.attr, - &device_attr_fcoe_fcf_switch_name.attr, - &device_attr_fcoe_fcf_dev_loss_tmo.attr, - &device_attr_fcoe_fcf_fc_map.attr, - &device_attr_fcoe_fcf_vfid.attr, - &device_attr_fcoe_fcf_mac.attr, - &device_attr_fcoe_fcf_priority.attr, - &device_attr_fcoe_fcf_fka_period.attr, - &device_attr_fcoe_fcf_state.attr, - &device_attr_fcoe_fcf_selected.attr, - &device_attr_fcoe_fcf_vlan_id.attr, - NULL -}; - -static struct attribute_group fcoe_fcf_attr_group = { - .attrs = fcoe_fcf_attrs, -}; - -static const struct attribute_group *fcoe_fcf_attr_groups[] = { - &fcoe_fcf_attr_group, - NULL, -}; - -struct bus_type fcoe_bus_type; - -static int fcoe_bus_match(struct device *dev, - struct device_driver *drv) -{ - if (dev->bus == &fcoe_bus_type) - return 1; - return 0; -} - -/** - * fcoe_ctlr_device_release() - Release the FIP ctlr memory - * @dev: Pointer to the FIP ctlr's embedded device - * - * Called when the last FIP ctlr reference is released. - */ -static void fcoe_ctlr_device_release(struct device *dev) -{ - struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); - kfree(ctlr); -} - -/** - * fcoe_fcf_device_release() - Release the FIP fcf memory - * @dev: Pointer to the fcf's embedded device - * - * Called when the last FIP fcf reference is released. - */ -static void fcoe_fcf_device_release(struct device *dev) -{ - struct fcoe_fcf_device *fcf = dev_to_fcf(dev); - kfree(fcf); -} - -struct device_type fcoe_ctlr_device_type = { - .name = "fcoe_ctlr", - .groups = fcoe_ctlr_attr_groups, - .release = fcoe_ctlr_device_release, -}; - -struct device_type fcoe_fcf_device_type = { - .name = "fcoe_fcf", - .groups = fcoe_fcf_attr_groups, - .release = fcoe_fcf_device_release, -}; - -struct bus_type fcoe_bus_type = { - .name = "fcoe", - .match = &fcoe_bus_match, -}; - -/** - * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue - * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed - */ -void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) -{ - if (!fcoe_ctlr_work_q(ctlr)) { - printk(KERN_ERR - "ERROR: FIP Ctlr '%d' attempted to flush work, " - "when no workqueue created.\n", ctlr->id); - dump_stack(); - return; - } - - flush_workqueue(fcoe_ctlr_work_q(ctlr)); -} - -/** - * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue - * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue - * @work: Work to queue for execution - * - * Return value: - * 1 on success / 0 already queued / < 0 for error - */ -int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, - struct work_struct *work) -{ - if (unlikely(!fcoe_ctlr_work_q(ctlr))) { - printk(KERN_ERR - "ERROR: FIP Ctlr '%d' attempted to queue work, " - "when no workqueue created.\n", ctlr->id); - dump_stack(); - - return -EINVAL; - } - - return queue_work(fcoe_ctlr_work_q(ctlr), work); -} - -/** - * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue - * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed - */ -void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) -{ - if (!fcoe_ctlr_devloss_work_q(ctlr)) { - printk(KERN_ERR - "ERROR: FIP Ctlr '%d' attempted to flush work, " - "when no workqueue created.\n", ctlr->id); - dump_stack(); - return; - } - - flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr)); -} - -/** - * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue - * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue - * @work: Work to queue for execution - * @delay: jiffies to delay the work queuing - * - * Return value: - * 1 on success / 0 already queued / < 0 for error - */ -int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, - struct delayed_work *work, - unsigned long delay) -{ - if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) { - printk(KERN_ERR - "ERROR: FIP Ctlr '%d' attempted to queue work, " - "when no workqueue created.\n", ctlr->id); - dump_stack(); - - return -EINVAL; - } - - return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay); -} - -static int fcoe_fcf_device_match(struct fcoe_fcf_device *new, - struct fcoe_fcf_device *old) -{ - if (new->switch_name == old->switch_name && - new->fabric_name == old->fabric_name && - new->fc_map == old->fc_map && - compare_ether_addr(new->mac, old->mac) == 0) - return 1; - return 0; -} - -/** - * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs - * @parent: The parent device to which the fcoe_ctlr instance - * should be attached - * @f: The LLD's FCoE sysfs function template pointer - * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD - * - * This routine allocates a FIP ctlr object with some additional memory - * for the LLD. The FIP ctlr is initialized, added to sysfs and then - * attributes are added to it. - */ -struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, - struct fcoe_sysfs_function_template *f, - int priv_size) -{ - struct fcoe_ctlr_device *ctlr; - int error = 0; - - ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size, - GFP_KERNEL); - if (!ctlr) - goto out; - - ctlr->id = atomic_inc_return(&ctlr_num) - 1; - ctlr->f = f; - INIT_LIST_HEAD(&ctlr->fcfs); - mutex_init(&ctlr->lock); - ctlr->dev.parent = parent; - ctlr->dev.bus = &fcoe_bus_type; - ctlr->dev.type = &fcoe_ctlr_device_type; - - ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo; - - snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name), - "ctlr_wq_%d", ctlr->id); - ctlr->work_q = create_singlethread_workqueue( - ctlr->work_q_name); - if (!ctlr->work_q) - goto out_del; - - snprintf(ctlr->devloss_work_q_name, - sizeof(ctlr->devloss_work_q_name), - "ctlr_dl_wq_%d", ctlr->id); - ctlr->devloss_work_q = create_singlethread_workqueue( - ctlr->devloss_work_q_name); - if (!ctlr->devloss_work_q) - goto out_del_q; - - dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); - error = device_register(&ctlr->dev); - if (error) - goto out_del_q2; - - return ctlr; - -out_del_q2: - destroy_workqueue(ctlr->devloss_work_q); - ctlr->devloss_work_q = NULL; -out_del_q: - destroy_workqueue(ctlr->work_q); - ctlr->work_q = NULL; -out_del: - kfree(ctlr); -out: - return NULL; -} -EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add); - -/** - * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs - * @ctlr: A pointer to the ctlr to be deleted - * - * Deletes a FIP ctlr and any fcfs attached - * to it. Deleting fcfs will cause their childen - * to be deleted as well. - * - * The ctlr is detached from sysfs and it's resources - * are freed (work q), but the memory is not freed - * until its last reference is released. - * - * This routine expects no locks to be held before - * calling. - * - * TODO: Currently there are no callbacks to clean up LLD data - * for a fcoe_fcf_device. LLDs must keep this in mind as they need - * to clean up each of their LLD data for all fcoe_fcf_device before - * calling fcoe_ctlr_device_delete. - */ -void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr) -{ - struct fcoe_fcf_device *fcf, *next; - /* Remove any attached fcfs */ - mutex_lock(&ctlr->lock); - list_for_each_entry_safe(fcf, next, - &ctlr->fcfs, peers) { - list_del(&fcf->peers); - fcf->state = FCOE_FCF_STATE_DELETED; - fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); - } - mutex_unlock(&ctlr->lock); - - fcoe_ctlr_device_flush_work(ctlr); - - destroy_workqueue(ctlr->devloss_work_q); - ctlr->devloss_work_q = NULL; - destroy_workqueue(ctlr->work_q); - ctlr->work_q = NULL; - - device_unregister(&ctlr->dev); -} -EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete); - -/** - * fcoe_fcf_device_final_delete() - Final delete routine - * @work: The FIP fcf's embedded work struct - * - * It is expected that the fcf has been removed from - * the FIP ctlr's list before calling this routine. - */ -static void fcoe_fcf_device_final_delete(struct work_struct *work) -{ - struct fcoe_fcf_device *fcf = - container_of(work, struct fcoe_fcf_device, delete_work); - struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); - - /* - * Cancel any outstanding timers. These should really exist - * only when rmmod'ing the LLDD and we're asking for - * immediate termination of the rports - */ - if (!cancel_delayed_work(&fcf->dev_loss_work)) - fcoe_ctlr_device_flush_devloss(ctlr); - - device_unregister(&fcf->dev); -} - -/** - * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires - * @work: The FIP fcf's embedded work struct - * - * Removes the fcf from the FIP ctlr's list of fcfs and - * queues the final deletion. - */ -static void fip_timeout_deleted_fcf(struct work_struct *work) -{ - struct fcoe_fcf_device *fcf = - container_of(work, struct fcoe_fcf_device, dev_loss_work.work); - struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); - - mutex_lock(&ctlr->lock); - - /* - * If the fcf is deleted or reconnected before the timer - * fires the devloss queue will be flushed, but the state will - * either be CONNECTED or DELETED. If that is the case we - * cancel deleting the fcf. - */ - if (fcf->state != FCOE_FCF_STATE_DISCONNECTED) - goto out; - - dev_printk(KERN_ERR, &fcf->dev, - "FIP fcf connection time out: removing fcf\n"); - - list_del(&fcf->peers); - fcf->state = FCOE_FCF_STATE_DELETED; - fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); - -out: - mutex_unlock(&ctlr->lock); -} - -/** - * fcoe_fcf_device_delete() - Delete a FIP fcf - * @fcf: Pointer to the fcf which is to be deleted - * - * Queues the FIP fcf on the devloss workqueue - * - * Expects the ctlr_attrs mutex to be held for fcf - * state change. - */ -void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf) -{ - struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); - int timeout = fcf->dev_loss_tmo; - - if (fcf->state != FCOE_FCF_STATE_CONNECTED) - return; - - fcf->state = FCOE_FCF_STATE_DISCONNECTED; - - /* - * FCF will only be re-connected by the LLD calling - * fcoe_fcf_device_add, and it should be setting up - * priv then. - */ - fcf->priv = NULL; - - fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work, - timeout * HZ); -} -EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete); - -/** - * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system - * @ctlr: The fcoe_ctlr_device that will be the fcoe_fcf_device parent - * @new_fcf: A temporary FCF used for lookups on the current list of fcfs - * - * Expects to be called with the ctlr->lock held - */ -struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, - struct fcoe_fcf_device *new_fcf) -{ - struct fcoe_fcf_device *fcf; - int error = 0; - - list_for_each_entry(fcf, &ctlr->fcfs, peers) { - if (fcoe_fcf_device_match(new_fcf, fcf)) { - if (fcf->state == FCOE_FCF_STATE_CONNECTED) - return fcf; - - fcf->state = FCOE_FCF_STATE_CONNECTED; - - if (!cancel_delayed_work(&fcf->dev_loss_work)) - fcoe_ctlr_device_flush_devloss(ctlr); - - return fcf; - } - } - - fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC); - if (unlikely(!fcf)) - goto out; - - INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete); - INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf); - - fcf->dev.parent = &ctlr->dev; - fcf->dev.bus = &fcoe_bus_type; - fcf->dev.type = &fcoe_fcf_device_type; - fcf->id = atomic_inc_return(&fcf_num) - 1; - fcf->state = FCOE_FCF_STATE_UNKNOWN; - - fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo; - - dev_set_name(&fcf->dev, "fcf_%d", fcf->id); - - fcf->fabric_name = new_fcf->fabric_name; - fcf->switch_name = new_fcf->switch_name; - fcf->fc_map = new_fcf->fc_map; - fcf->vfid = new_fcf->vfid; - memcpy(fcf->mac, new_fcf->mac, ETH_ALEN); - fcf->priority = new_fcf->priority; - fcf->fka_period = new_fcf->fka_period; - fcf->selected = new_fcf->selected; - - error = device_register(&fcf->dev); - if (error) - goto out_del; - - fcf->state = FCOE_FCF_STATE_CONNECTED; - list_add_tail(&fcf->peers, &ctlr->fcfs); - - return fcf; - -out_del: - kfree(fcf); -out: - return NULL; -} -EXPORT_SYMBOL_GPL(fcoe_fcf_device_add); - -int __init fcoe_sysfs_setup(void) -{ - int error; - - atomic_set(&ctlr_num, 0); - atomic_set(&fcf_num, 0); - - error = bus_register(&fcoe_bus_type); - if (error) - return error; - - return 0; -} - -void __exit fcoe_sysfs_teardown(void) -{ - bus_unregister(&fcoe_bus_type); -} diff --git a/trunk/drivers/scsi/fcoe/fcoe_transport.c b/trunk/drivers/scsi/fcoe/fcoe_transport.c index b46f43dced78..710e149d41b6 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_transport.c +++ b/trunk/drivers/scsi/fcoe/fcoe_transport.c @@ -815,17 +815,9 @@ static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp) */ static int __init libfcoe_init(void) { - int rc = 0; - - rc = fcoe_transport_init(); - if (rc) - return rc; + fcoe_transport_init(); - rc = fcoe_sysfs_setup(); - if (rc) - fcoe_transport_exit(); - - return rc; + return 0; } module_init(libfcoe_init); @@ -834,7 +826,6 @@ module_init(libfcoe_init); */ static void __exit libfcoe_exit(void) { - fcoe_sysfs_teardown(); fcoe_transport_exit(); } module_exit(libfcoe_exit); diff --git a/trunk/drivers/scsi/qla2xxx/Kconfig b/trunk/drivers/scsi/qla2xxx/Kconfig index 317a7fdc3b82..6208d562890d 100644 --- a/trunk/drivers/scsi/qla2xxx/Kconfig +++ b/trunk/drivers/scsi/qla2xxx/Kconfig @@ -25,12 +25,3 @@ config SCSI_QLA_FC Firmware images can be retrieved from: ftp://ftp.qlogic.com/outgoing/linux/firmware/ - -config TCM_QLA2XXX - tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs" - depends on SCSI_QLA_FC && TARGET_CORE - select LIBFC - select BTREE - default n - ---help--- - Say Y here to enable the TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs diff --git a/trunk/drivers/scsi/qla2xxx/Makefile b/trunk/drivers/scsi/qla2xxx/Makefile index dce7d788cdc9..5df782f4a097 100644 --- a/trunk/drivers/scsi/qla2xxx/Makefile +++ b/trunk/drivers/scsi/qla2xxx/Makefile @@ -1,6 +1,5 @@ qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ - qla_nx.o qla_target.o + qla_nx.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o -obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index 5ab953029f8d..5926f5a87ea8 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -5,7 +5,6 @@ * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" -#include "qla_target.h" #include #include @@ -577,7 +576,6 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, scsi_block_requests(vha->host); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); if (IS_QLA82XX(ha)) { - ha->flags.isp82xx_no_md_cap = 1; qla82xx_idc_lock(ha); qla82xx_set_reset_owner(vha); qla82xx_idc_unlock(ha); @@ -587,7 +585,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, scsi_unblock_requests(vha->host); break; case 0x2025d: - if (!IS_QLA81XX(ha) || !IS_QLA8031(ha)) + if (!IS_QLA81XX(ha)) return -EPERM; ql_log(ql_log_info, vha, 0x706f, @@ -1107,8 +1105,9 @@ qla2x00_total_isp_aborts_show(struct device *dev, struct device_attribute *attr, char *buf) { scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + struct qla_hw_data *ha = vha->hw; return snprintf(buf, PAGE_SIZE, "%d\n", - vha->qla_stats.total_isp_aborts); + ha->qla_stats.total_isp_aborts); } static ssize_t @@ -1155,7 +1154,7 @@ qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr, scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", @@ -1538,7 +1537,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) dma_addr_t stats_dma; struct fc_host_statistics *pfc_host_stat; - pfc_host_stat = &vha->fc_host_stat; + pfc_host_stat = &ha->fc_host_stat; memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); if (test_bit(UNLOADING, &vha->dpc_flags)) @@ -1581,8 +1580,8 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) pfc_host_stat->dumped_frames = stats->dumped_frames; pfc_host_stat->nos_count = stats->nos_rcvd; } - pfc_host_stat->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20; - pfc_host_stat->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20; + pfc_host_stat->fcp_input_megabytes = ha->qla_stats.input_bytes >> 20; + pfc_host_stat->fcp_output_megabytes = ha->qla_stats.output_bytes >> 20; done_free: dma_pool_free(ha->s_dma_pool, stats, stats_dma); @@ -1738,7 +1737,6 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) fc_host_supported_speeds(vha->host) = fc_host_supported_speeds(base_vha->host); - qlt_vport_create(vha, ha); qla24xx_vport_disable(fc_vport, disable); if (ha->flags.cpu_affinity_enabled) { @@ -1953,16 +1951,12 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); - fc_host_supported_classes(vha->host) = ha->tgt.enable_class_2 ? - (FC_COS_CLASS2|FC_COS_CLASS3) : FC_COS_CLASS3; + fc_host_supported_classes(vha->host) = FC_COS_CLASS3; fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; if (IS_CNA_CAPABLE(ha)) speed = FC_PORTSPEED_10GBIT; - else if (IS_QLA2031(ha)) - speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT | - FC_PORTSPEED_4GBIT; else if (IS_QLA25XX(ha)) speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; diff --git a/trunk/drivers/scsi/qla2xxx/qla_bsg.c b/trunk/drivers/scsi/qla2xxx/qla_bsg.c index c68883806c54..bc3cc6d91117 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_bsg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_bsg.c @@ -297,6 +297,7 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) /* Initialize all required fields of fcport */ fcport->vha = vha; + fcport->vp_idx = vha->vp_idx; fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_els.port_id[0]; fcport->d_id.b.area = @@ -482,6 +483,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) /* Initialize all required fields of fcport */ fcport->vha = vha; + fcport->vp_idx = vha->vp_idx; fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0]; fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1]; fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2]; @@ -542,7 +544,7 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, int rval = 0; struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) goto done_set_internal; new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1); @@ -584,7 +586,7 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, uint16_t new_config[4]; struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) goto done_reset_internal; memset(new_config, 0 , sizeof(new_config)); @@ -708,7 +710,8 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; if ((ha->current_topology == ISP_CFG_F || - ((IS_QLA81XX(ha) || IS_QLA8031(ha)) && + (atomic_read(&vha->loop_state) == LOOP_DOWN) || + ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && elreq.options == EXTERNAL_LOOPBACK) { @@ -1399,9 +1402,6 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job) if (rval) return rval; - /* Set the isp82xx_no_md_cap not to capture minidump */ - ha->flags.isp82xx_no_md_cap = 1; - sg_copy_to_buffer(bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, ha->optrom_buffer, ha->optrom_region_size); diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index fdee5611f3e2..62324a1d5573 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -11,31 +11,27 @@ * ---------------------------------------------------------------------- * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- - * | Module Init and Probe | 0x0122 | 0x4b,0xba,0xfa | - * | Mailbox commands | 0x1140 | 0x111a-0x111b | - * | | | 0x112c-0x112e | + * | Module Init and Probe | 0x0120 | 0x4b,0xba,0xfa | + * | Mailbox commands | 0x113e | 0x112c-0x112e | * | | | 0x113a | * | Device Discovery | 0x2086 | 0x2020-0x2022 | * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | * | | | 0x302d-0x302e | - * | DPC Thread | 0x401c | 0x4002,0x4013 | - * | Async Events | 0x505f | 0x502b-0x502f | + * | DPC Thread | 0x401c | | + * | Async Events | 0x505d | 0x502b-0x502f | * | | | 0x5047,0x5052 | - * | Timer Routines | 0x6011 | | + * | Timer Routines | 0x6011 | 0x600e-0x600f | * | User Space Interactions | 0x709f | 0x7018,0x702e, | * | | | 0x7039,0x7045, | * | | | 0x7073-0x7075, | * | | | 0x708c | * | Task Management | 0x803c | 0x8025-0x8026 | * | | | 0x800b,0x8039 | - * | AER/EEH | 0x9011 | | + * | AER/EEH | 0x900f | | * | Virtual Port | 0xa007 | | - * | ISP82XX Specific | 0xb054 | 0xb024 | + * | ISP82XX Specific | 0xb054 | 0xb053 | * | MultiQ | 0xc00c | | * | Misc | 0xd010 | | - * | Target Mode | 0xe06f | | - * | Target Mode Management | 0xf071 | | - * | Target Mode Task Management | 0x1000b | | * ---------------------------------------------------------------------- */ @@ -382,54 +378,6 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) return (char *)iter_reg + ntohl(fcec->size); } -static inline void * -qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, - uint32_t **last_chain) -{ - struct qla2xxx_mqueue_chain *q; - struct qla2xxx_mqueue_header *qh; - uint32_t num_queues; - int que; - struct { - int length; - void *ring; - } aq, *aqp; - - if (!ha->tgt.atio_q_length) - return ptr; - - num_queues = 1; - aqp = &aq; - aqp->length = ha->tgt.atio_q_length; - aqp->ring = ha->tgt.atio_ring; - - for (que = 0; que < num_queues; que++) { - /* aqp = ha->atio_q_map[que]; */ - q = ptr; - *last_chain = &q->type; - q->type = __constant_htonl(DUMP_CHAIN_QUEUE); - q->chain_size = htonl( - sizeof(struct qla2xxx_mqueue_chain) + - sizeof(struct qla2xxx_mqueue_header) + - (aqp->length * sizeof(request_t))); - ptr += sizeof(struct qla2xxx_mqueue_chain); - - /* Add header. */ - qh = ptr; - qh->queue = __constant_htonl(TYPE_ATIO_QUEUE); - qh->number = htonl(que); - qh->size = htonl(aqp->length * sizeof(request_t)); - ptr += sizeof(struct qla2xxx_mqueue_header); - - /* Add data. */ - memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t)); - - ptr += aqp->length * sizeof(request_t); - } - - return ptr; -} - static inline void * qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) { @@ -925,8 +873,6 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) struct qla24xx_fw_dump *fw; uint32_t ext_mem_cnt; void *nxt; - void *nxt_chain; - uint32_t *last_chain = NULL; struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); if (IS_QLA82XX(ha)) @@ -1145,16 +1091,6 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) qla24xx_copy_eft(ha, nxt); - nxt_chain = (void *)ha->fw_dump + ha->chain_offset; - nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); - if (last_chain) { - ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); - *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); - } - - /* Adjust valid length. */ - ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); - qla24xx_fw_dump_failed_0: qla2xxx_dump_post_process(base_vha, rval); @@ -1463,7 +1399,6 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); - nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); if (last_chain) { ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); @@ -1782,7 +1717,6 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); - nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); if (last_chain) { ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); @@ -2284,7 +2218,6 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); - nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); if (last_chain) { ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.h b/trunk/drivers/scsi/qla2xxx/qla_dbg.h index f278df8cce0f..2157bdf1569a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.h +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.h @@ -244,7 +244,6 @@ struct qla2xxx_mqueue_header { uint32_t queue; #define TYPE_REQUEST_QUEUE 0x1 #define TYPE_RESPONSE_QUEUE 0x2 -#define TYPE_ATIO_QUEUE 0x3 uint32_t number; uint32_t size; }; @@ -340,11 +339,3 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); #define ql_dbg_misc 0x00010000 /* For dumping everything that is not * not covered by upper categories */ -#define ql_dbg_verbose 0x00008000 /* More verbosity for each level - * This is to be used with other levels where - * more verbosity is required. It might not - * be applicable to all the levels. - */ -#define ql_dbg_tgt 0x00004000 /* Target mode */ -#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ -#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 39007f53aec0..a2443031dbe7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -186,7 +186,6 @@ #define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/ #define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/ #define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/ -#define ATIO_ENTRY_CNT_24XX 4096 /* Number of ATIO entries. */ struct req_que; @@ -1235,27 +1234,11 @@ typedef struct { * ISP queue - response queue entry definition. */ typedef struct { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System defined handle */ - uint8_t data[52]; + uint8_t data[60]; uint32_t signature; #define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */ } response_t; -/* - * ISP queue - ATIO queue entry definition. - */ -struct atio { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t data[58]; - uint32_t signature; -#define ATIO_PROCESSED 0xDEADDEAD /* Signature */ -}; - typedef union { uint16_t extended; struct { @@ -1736,13 +1719,11 @@ typedef struct fc_port { struct fc_rport *rport, *drport; u32 supported_classes; + uint16_t vp_idx; uint8_t fc4_type; uint8_t scan_state; } fc_port_t; -#define QLA_FCPORT_SCAN_NONE 0 -#define QLA_FCPORT_SCAN_FOUND 1 - /* * Fibre channel port/lun states. */ @@ -1766,7 +1747,6 @@ static const char * const port_state_str[] = { #define FCF_LOGIN_NEEDED BIT_1 #define FCF_FCP2_DEVICE BIT_2 #define FCF_ASYNC_SENT BIT_3 -#define FCF_CONF_COMP_SUPPORTED BIT_4 /* No loop ID flag. */ #define FC_NO_LOOP_ID 0x1000 @@ -2439,40 +2419,6 @@ struct qlfc_fw { uint32_t len; }; -struct qlt_hw_data { - /* Protected by hw lock */ - uint32_t enable_class_2:1; - uint32_t enable_explicit_conf:1; - uint32_t ini_mode_force_reverse:1; - uint32_t node_name_set:1; - - dma_addr_t atio_dma; /* Physical address. */ - struct atio *atio_ring; /* Base virtual address */ - struct atio *atio_ring_ptr; /* Current address. */ - uint16_t atio_ring_index; /* Current index. */ - uint16_t atio_q_length; - - void *target_lport_ptr; - struct qla_tgt_func_tmpl *tgt_ops; - struct qla_tgt *qla_tgt; - struct qla_tgt_cmd *cmds[MAX_OUTSTANDING_COMMANDS]; - uint16_t current_handle; - - struct qla_tgt_vp_map *tgt_vp_map; - struct mutex tgt_mutex; - struct mutex tgt_host_action_mutex; - - int saved_set; - uint16_t saved_exchange_count; - uint32_t saved_firmware_options_1; - uint32_t saved_firmware_options_2; - uint32_t saved_firmware_options_3; - uint8_t saved_firmware_options[2]; - uint8_t saved_add_firmware_options[2]; - - uint8_t tgt_node_name[WWN_SIZE]; -}; - /* * Qlogic host adapter specific data structure. */ @@ -2514,9 +2460,7 @@ struct qla_hw_data { uint32_t thermal_supported:1; uint32_t isp82xx_reset_hdlr_active:1; uint32_t isp82xx_reset_owner:1; - uint32_t isp82xx_no_md_cap:1; - uint32_t host_shutting_down:1; - /* 30 bits */ + /* 28 bits */ } flags; /* This spinlock is used to protect "io transactions", you must @@ -2860,6 +2804,7 @@ struct qla_hw_data { /* ISP2322: red, green, amber. */ uint16_t zio_mode; uint16_t zio_timer; + struct fc_host_statistics fc_host_stat; struct qla_msix_entry *msix_entries; @@ -2872,6 +2817,7 @@ struct qla_hw_data { int cur_vport_count; struct qla_chip_state_84xx *cs84xx; + struct qla_statistics qla_stats; struct isp_operations *isp_ops; struct workqueue_struct *wq; struct qlfc_fw fw_buf; @@ -2917,8 +2863,6 @@ struct qla_hw_data { dma_addr_t md_tmplt_hdr_dma; void *md_dump; uint32_t md_dump_size; - - struct qlt_hw_data tgt; }; /* @@ -2976,7 +2920,6 @@ typedef struct scsi_qla_host { #define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ #define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */ #define ISP_QUIESCE_NEEDED 20 /* Driver need some quiescence */ -#define SCR_PENDING 21 /* SCR in target mode */ uint32_t device_flags; #define SWITCH_FOUND BIT_0 @@ -3036,21 +2979,10 @@ typedef struct scsi_qla_host { struct req_que *req; int fw_heartbeat_counter; int seconds_since_last_heartbeat; - struct fc_host_statistics fc_host_stat; - struct qla_statistics qla_stats; atomic_t vref_count; } scsi_qla_host_t; -#define SET_VP_IDX 1 -#define SET_AL_PA 2 -#define RESET_VP_IDX 3 -#define RESET_AL_PA 4 -struct qla_tgt_vp_map { - uint8_t idx; - scsi_qla_host_t *vha; -}; - /* * Macros to help code, maintain, etc. */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 9eacd2df111b..9f065804bd12 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -175,7 +175,6 @@ extern int qla2x00_vp_abort_isp(scsi_qla_host_t *); /* * Global Function Prototypes in qla_iocb.c source file. */ - extern uint16_t qla2x00_calc_iocbs_32(uint16_t); extern uint16_t qla2x00_calc_iocbs_64(uint16_t); extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); @@ -189,8 +188,6 @@ extern uint16_t qla24xx_calc_iocbs(scsi_qla_host_t *, uint16_t); extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t); extern int qla24xx_dif_start_scsi(srb_t *); -extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); -extern int qla2x00_issue_marker(scsi_qla_host_t *, int); /* * Global Function Prototypes in qla_mbx.c source file. @@ -241,9 +238,6 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *); extern int qla2x00_init_firmware(scsi_qla_host_t *, uint16_t); -extern int -qla2x00_get_node_name_list(scsi_qla_host_t *, void **, int *); - extern int qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t); @@ -389,8 +383,6 @@ extern int qla2x00_request_irqs(struct qla_hw_data *, struct rsp_que *); extern void qla2x00_free_irqs(scsi_qla_host_t *); extern int qla2x00_get_data_rate(scsi_qla_host_t *); -extern char *qla2x00_get_link_speed_str(struct qla_hw_data *); - /* * Global Function Prototypes in qla_sup.c source file. */ @@ -554,7 +546,6 @@ extern void qla2x00_sp_free(void *, void *); extern void qla2x00_sp_timeout(unsigned long); extern void qla2x00_bsg_job_done(void *, void *, int); extern void qla2x00_bsg_sp_free(void *, void *); -extern void qla2x00_start_iocbs(struct scsi_qla_host *, struct req_que *); /* Interrupt related */ extern irqreturn_t qla82xx_intr_handler(int, void *); diff --git a/trunk/drivers/scsi/qla2xxx/qla_gs.c b/trunk/drivers/scsi/qla2xxx/qla_gs.c index 05260d25fe46..3128f80441f5 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gs.c +++ b/trunk/drivers/scsi/qla2xxx/qla_gs.c @@ -5,7 +5,6 @@ * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" -#include "qla_target.h" static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); @@ -557,8 +556,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha) ct_req->req.rff_id.port_id[1] = vha->d_id.b.area; ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa; - qlt_rff_id(vha, ct_req); - + ct_req->req.rff_id.fc4_feature = BIT_1; ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */ /* Execute MS IOCB */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index ca5084743135..b9465643396b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -17,9 +17,6 @@ #include #endif -#include -#include "qla_target.h" - /* * QLogic ISP2x00 Hardware Support Function Prototypes. */ @@ -521,10 +518,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) return QLA_FUNCTION_FAILED; } } - - if (qla_ini_mode_enabled(vha)) - rval = qla2x00_init_rings(vha); - + rval = qla2x00_init_rings(vha); ha->flags.chip_reset_done = 1; if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) { @@ -1239,8 +1233,6 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) mq_size += ha->max_rsp_queues * (rsp->length * sizeof(response_t)); } - if (ha->tgt.atio_q_length) - mq_size += ha->tgt.atio_q_length * sizeof(request_t); /* Allocate memory for Fibre Channel Event Buffer. */ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) goto try_eft; @@ -1704,12 +1696,6 @@ qla24xx_config_rings(struct scsi_qla_host *vha) icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); - /* Setup ATIO queue dma pointers for target mode */ - icb->atio_q_inpointer = __constant_cpu_to_le16(0); - icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length); - icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); - icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); - if (ha->mqenable || IS_QLA83XX(ha)) { icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); icb->rid = __constant_cpu_to_le16(rid); @@ -1753,8 +1739,6 @@ qla24xx_config_rings(struct scsi_qla_host *vha) WRT_REG_DWORD(®->isp24.rsp_q_in, 0); WRT_REG_DWORD(®->isp24.rsp_q_out, 0); } - qlt_24xx_config_rings(vha, reg); - /* PCI posting */ RD_REG_DWORD(&ioreg->hccr); } @@ -1810,11 +1794,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha) spin_unlock(&ha->vport_slock); - ha->tgt.atio_ring_ptr = ha->tgt.atio_ring; - ha->tgt.atio_ring_index = 0; - /* Initialize ATIO queue entries */ - qlt_init_atio_q_entries(vha); - ha->isp_ops->config_rings(vha); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -2072,10 +2051,6 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) vha->d_id.b.area = area; vha->d_id.b.al_pa = al_pa; - spin_lock(&ha->vport_slock); - qlt_update_vp_map(vha, SET_AL_PA); - spin_unlock(&ha->vport_slock); - if (!vha->flags.init_done) ql_log(ql_log_info, vha, 0x2010, "Topology - %s, Host Loop address 0x%x.\n", @@ -2210,7 +2185,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) { /* Reset NVRAM data. */ ql_log(ql_log_warn, vha, 0x0064, - "Inconsistent NVRAM " + "Inconisistent NVRAM " "detected: checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); ql_log(ql_log_warn, vha, 0x0065, @@ -2295,7 +2270,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) if (IS_QLA23XX(ha)) { nv->firmware_options[0] |= BIT_2; nv->firmware_options[0] &= ~BIT_3; - nv->special_options[0] &= ~BIT_6; + nv->firmware_options[0] &= ~BIT_6; nv->add_firmware_options[1] |= BIT_5 | BIT_4; if (IS_QLA2300(ha)) { @@ -2492,21 +2467,14 @@ qla2x00_rport_del(void *data) { fc_port_t *fcport = data; struct fc_rport *rport; - scsi_qla_host_t *vha = fcport->vha; unsigned long flags; spin_lock_irqsave(fcport->vha->host->host_lock, flags); rport = fcport->drport ? fcport->drport: fcport->rport; fcport->drport = NULL; spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); - if (rport) { + if (rport) fc_remote_port_delete(rport); - /* - * Release the target mode FC NEXUS in qla_target.c code - * if target mod is enabled. - */ - qlt_fc_port_deleted(vha, fcport); - } } /** @@ -2527,11 +2495,11 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) /* Setup fcport template structure. */ fcport->vha = vha; + fcport->vp_idx = vha->vp_idx; fcport->port_type = FCT_UNKNOWN; fcport->loop_id = FC_NO_LOOP_ID; qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); fcport->supported_classes = FC_COS_UNSPECIFIED; - fcport->scan_state = QLA_FCPORT_SCAN_NONE; return fcport; } @@ -2758,6 +2726,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) new_fcport->d_id.b.area = area; new_fcport->d_id.b.al_pa = al_pa; new_fcport->loop_id = loop_id; + new_fcport->vp_idx = vha->vp_idx; rval2 = qla2x00_get_port_database(vha, new_fcport, 0); if (rval2 != QLA_SUCCESS) { ql_dbg(ql_dbg_disc, vha, 0x201a, @@ -2791,6 +2760,10 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) if (!found) { /* New device, add to fcports list. */ + if (vha->vp_idx) { + new_fcport->vha = vha; + new_fcport->vp_idx = vha->vp_idx; + } list_add_tail(&new_fcport->list, &vha->vp_fcports); /* Allocate a new replacement fcport. */ @@ -2827,6 +2800,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) static void qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) { +#define LS_UNKNOWN 2 + static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" }; char *link_speed; int rval; uint16_t mb[4]; @@ -2854,7 +2829,11 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) fcport->port_name[6], fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]); } else { - link_speed = qla2x00_get_link_speed_str(ha); + link_speed = link_speeds[LS_UNKNOWN]; + if (fcport->fp_speed < 5) + link_speed = link_speeds[fcport->fp_speed]; + else if (fcport->fp_speed == 0x13) + link_speed = link_speeds[5]; ql_dbg(ql_dbg_disc, vha, 0x2005, "iIDMA adjusted to %s GB/s " "on %02x%02x%02x%02x%02x%02x%02x%02x.\n", link_speed, @@ -2885,12 +2864,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) "Unable to allocate fc remote port.\n"); return; } - /* - * Create target mode FC NEXUS in qla_target.c if target mode is - * enabled.. - */ - qlt_fc_port_added(vha, fcport); - spin_lock_irqsave(fcport->vha->host->host_lock, flags); *((fc_port_t **)rport->dd_data) = fcport; spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); @@ -2948,7 +2921,7 @@ static int qla2x00_configure_fabric(scsi_qla_host_t *vha) { int rval; - fc_port_t *fcport; + fc_port_t *fcport, *fcptemp; uint16_t next_loopid; uint16_t mb[MAILBOX_REGISTER_COUNT]; uint16_t loop_id; @@ -2986,7 +2959,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) 0xfc, mb, BIT_1|BIT_0); if (rval != QLA_SUCCESS) { set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - break; + return rval; } if (mb[0] != MBS_COMMAND_COMPLETE) { ql_dbg(ql_dbg_disc, vha, 0x2042, @@ -3018,16 +2991,21 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) } } +#define QLA_FCPORT_SCAN 1 +#define QLA_FCPORT_FOUND 2 + + list_for_each_entry(fcport, &vha->vp_fcports, list) { + fcport->scan_state = QLA_FCPORT_SCAN; + } + rval = qla2x00_find_all_fabric_devs(vha, &new_fcports); if (rval != QLA_SUCCESS) break; - /* Add new ports to existing port list */ - list_splice_tail_init(&new_fcports, &vha->vp_fcports); - - /* Starting free loop ID. */ - next_loopid = ha->min_external_loopid; - + /* + * Logout all previous fabric devices marked lost, except + * FCP2 devices. + */ list_for_each_entry(fcport, &vha->vp_fcports, list) { if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) break; @@ -3035,8 +3013,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) continue; - /* Logout lost/gone fabric devices (non-FCP2) */ - if (fcport->scan_state != QLA_FCPORT_SCAN_FOUND && + if (fcport->scan_state == QLA_FCPORT_SCAN && atomic_read(&fcport->state) == FCS_ONLINE) { qla2x00_mark_device_lost(vha, fcport, ql2xplogiabsentdevice, 0); @@ -3049,30 +3026,78 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); + fcport->loop_id = FC_NO_LOOP_ID; } - continue; } - fcport->scan_state = QLA_FCPORT_SCAN_NONE; - - /* Login fabric devices that need a login */ - if ((fcport->flags & FCF_LOGIN_NEEDED) != 0 && - atomic_read(&vha->loop_down_timer) == 0) { - if (fcport->loop_id == FC_NO_LOOP_ID) { - fcport->loop_id = next_loopid; - rval = qla2x00_find_new_loop_id( - base_vha, fcport); - if (rval != QLA_SUCCESS) { - /* Ran out of IDs to use */ - continue; - } + } + + /* Starting free loop ID. */ + next_loopid = ha->min_external_loopid; + + /* + * Scan through our port list and login entries that need to be + * logged in. + */ + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (atomic_read(&vha->loop_down_timer) || + test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + break; + + if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || + (fcport->flags & FCF_LOGIN_NEEDED) == 0) + continue; + + if (fcport->loop_id == FC_NO_LOOP_ID) { + fcport->loop_id = next_loopid; + rval = qla2x00_find_new_loop_id( + base_vha, fcport); + if (rval != QLA_SUCCESS) { + /* Ran out of IDs to use */ + break; } } + /* Login and update database */ + qla2x00_fabric_dev_login(vha, fcport, &next_loopid); + } + + /* Exit if out of loop IDs. */ + if (rval != QLA_SUCCESS) { + break; + } + + /* + * Login and add the new devices to our port list. + */ + list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { + if (atomic_read(&vha->loop_down_timer) || + test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) + break; + + /* Find a new loop ID to use. */ + fcport->loop_id = next_loopid; + rval = qla2x00_find_new_loop_id(base_vha, fcport); + if (rval != QLA_SUCCESS) { + /* Ran out of IDs to use */ + break; + } /* Login and update database */ qla2x00_fabric_dev_login(vha, fcport, &next_loopid); + + if (vha->vp_idx) { + fcport->vha = vha; + fcport->vp_idx = vha->vp_idx; + } + list_move_tail(&fcport->list, &vha->vp_fcports); } } while (0); + /* Free all new device structures not processed. */ + list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { + list_del(&fcport->list); + kfree(fcport); + } + if (rval) { ql_dbg(ql_dbg_disc, vha, 0x2068, "Configure fabric error exit rval=%d.\n", rval); @@ -3262,7 +3287,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, WWN_SIZE)) continue; - fcport->scan_state = QLA_FCPORT_SCAN_FOUND; + fcport->scan_state = QLA_FCPORT_FOUND; found++; @@ -3570,12 +3595,6 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport, if (mb[10] & BIT_1) fcport->supported_classes |= FC_COS_CLASS3; - if (IS_FWI2_CAPABLE(ha)) { - if (mb[10] & BIT_7) - fcport->flags |= - FCF_CONF_COMP_SUPPORTED; - } - rval = QLA_SUCCESS; break; } else if (mb[0] == MBS_LOOP_ID_USED) { @@ -3822,7 +3841,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) vha->flags.online = 0; ha->flags.chip_reset_done = 0; clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - vha->qla_stats.total_isp_aborts++; + ha->qla_stats.total_isp_aborts++; ql_log(ql_log_info, vha, 0x00af, "Performing ISP error recovery - ha=%p.\n", ha); @@ -4047,7 +4066,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; struct rsp_que *rsp = ha->rsp_q_map[0]; - unsigned long flags; /* If firmware needs to be loaded */ if (qla2x00_isp_firmware(vha)) { @@ -4072,16 +4090,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); vha->flags.online = 1; - - /* - * Process any ATIO queue entries that came in - * while we weren't online. - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - if (qla_tgt_mode_enabled(vha)) - qlt_24xx_process_atio_queue(vha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - /* Wait at most MAX_TARGET RSCNs for a stable link. */ wait_time = 256; do { @@ -4271,7 +4279,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) nv->nvram_version < __constant_cpu_to_le16(ICB_VERSION)) { /* Reset NVRAM data. */ ql_log(ql_log_warn, vha, 0x006b, - "Inconsistent NVRAM detected: checksum=0x%x id=%c " + "Inconisistent NVRAM detected: checksum=0x%x id=%c " "version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); ql_log(ql_log_warn, vha, 0x006c, "Falling back to functioning (yet invalid -- WWPN) " @@ -4322,15 +4330,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) rval = 1; } - if (!qla_ini_mode_enabled(vha)) { - /* Don't enable full login after initial LIP */ - nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13); - /* Don't enable LIP full login for initiator */ - nv->host_p &= __constant_cpu_to_le32(~BIT_10); - } - - qlt_24xx_config_nvram_stage1(vha, nv); - /* Reset Initialization control block */ memset(icb, 0, ha->init_cb_size); @@ -4358,10 +4357,8 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name), "QLA2462"); - qlt_24xx_config_nvram_stage2(vha, icb); - + /* Use alternate WWN? */ if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { - /* Use alternate WWN? */ memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE); memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE); } @@ -5032,7 +5029,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) nv->nvram_version < __constant_cpu_to_le16(ICB_VERSION)) { /* Reset NVRAM data. */ ql_log(ql_log_info, vha, 0x0073, - "Inconsistent NVRAM detected: checksum=0x%x id=%c " + "Inconisistent NVRAM detected: checksum=0x%x id=%c " "version=0x%x.\n", chksum, nv->id[0], le16_to_cpu(nv->nvram_version)); ql_log(ql_log_info, vha, 0x0074, diff --git a/trunk/drivers/scsi/qla2xxx/qla_iocb.c b/trunk/drivers/scsi/qla2xxx/qla_iocb.c index 70dbf53d9e0f..eac950924497 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_iocb.c +++ b/trunk/drivers/scsi/qla2xxx/qla_iocb.c @@ -5,7 +5,6 @@ * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" -#include "qla_target.h" #include #include @@ -24,17 +23,18 @@ qla2x00_get_cmd_direction(srb_t *sp) { uint16_t cflags; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - struct scsi_qla_host *vha = sp->fcport->vha; cflags = 0; /* Set transfer direction */ if (cmd->sc_data_direction == DMA_TO_DEVICE) { cflags = CF_WRITE; - vha->qla_stats.output_bytes += scsi_bufflen(cmd); + sp->fcport->vha->hw->qla_stats.output_bytes += + scsi_bufflen(cmd); } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { cflags = CF_READ; - vha->qla_stats.input_bytes += scsi_bufflen(cmd); + sp->fcport->vha->hw->qla_stats.input_bytes += + scsi_bufflen(cmd); } return (cflags); } @@ -385,10 +385,9 @@ qla2x00_start_scsi(srb_t *sp) else req->cnt = req->length - (req->ring_index - cnt); - /* If still no head room then bail out */ - if (req->cnt < (req_cnt + 2)) - goto queuing_error; } + if (req->cnt < (req_cnt + 2)) + goto queuing_error; /* Build command packet */ req->current_outstanding_cmd = handle; @@ -471,7 +470,7 @@ qla2x00_start_scsi(srb_t *sp) /** * qla2x00_start_iocbs() - Execute the IOCB command */ -void +static void qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) { struct qla_hw_data *ha = vha->hw; @@ -572,29 +571,6 @@ qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, return (ret); } -/* - * qla2x00_issue_marker - * - * Issue marker - * Caller CAN have hardware lock held as specified by ha_locked parameter. - * Might release it, then reaquire. - */ -int qla2x00_issue_marker(scsi_qla_host_t *vha, int ha_locked) -{ - if (ha_locked) { - if (__qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0, - MK_SYNC_ALL) != QLA_SUCCESS) - return QLA_FUNCTION_FAILED; - } else { - if (qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0, - MK_SYNC_ALL) != QLA_SUCCESS) - return QLA_FUNCTION_FAILED; - } - vha->marker_needed = 0; - - return QLA_SUCCESS; -} - /** * qla24xx_calc_iocbs() - Determine number of Command Type 3 and * Continuation Type 1 IOCBs to allocate. @@ -653,11 +629,11 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, if (cmd->sc_data_direction == DMA_TO_DEVICE) { cmd_pkt->control_flags = __constant_cpu_to_le16(CF_WRITE_DATA); - vha->qla_stats.output_bytes += scsi_bufflen(cmd); + ha->qla_stats.output_bytes += scsi_bufflen(cmd); } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { cmd_pkt->control_flags = __constant_cpu_to_le16(CF_READ_DATA); - vha->qla_stats.input_bytes += scsi_bufflen(cmd); + ha->qla_stats.input_bytes += scsi_bufflen(cmd); } cur_seg = scsi_sglist(cmd); @@ -769,11 +745,13 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, if (cmd->sc_data_direction == DMA_TO_DEVICE) { cmd_pkt->task_mgmt_flags = __constant_cpu_to_le16(TMF_WRITE_DATA); - vha->qla_stats.output_bytes += scsi_bufflen(cmd); + sp->fcport->vha->hw->qla_stats.output_bytes += + scsi_bufflen(cmd); } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { cmd_pkt->task_mgmt_flags = __constant_cpu_to_le16(TMF_READ_DATA); - vha->qla_stats.input_bytes += scsi_bufflen(cmd); + sp->fcport->vha->hw->qla_stats.input_bytes += + scsi_bufflen(cmd); } /* One DSD is available in the Command Type 3 IOCB */ @@ -1267,7 +1245,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, return QLA_SUCCESS; } - cmd_pkt->vp_index = sp->fcport->vha->vp_idx; + cmd_pkt->vp_index = sp->fcport->vp_idx; /* Set transfer direction */ if (cmd->sc_data_direction == DMA_TO_DEVICE) { @@ -1524,9 +1502,9 @@ qla24xx_start_scsi(srb_t *sp) else req->cnt = req->length - (req->ring_index - cnt); - if (req->cnt < (req_cnt + 2)) - goto queuing_error; } + if (req->cnt < (req_cnt + 2)) + goto queuing_error; /* Build command packet. */ req->current_outstanding_cmd = handle; @@ -1549,7 +1527,7 @@ qla24xx_start_scsi(srb_t *sp) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->vp_index = sp->fcport->vha->vp_idx; + cmd_pkt->vp_index = sp->fcport->vp_idx; int_to_scsilun(cmd->device->lun, &cmd_pkt->lun); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); @@ -1739,10 +1717,11 @@ qla24xx_dif_start_scsi(srb_t *sp) else req->cnt = req->length - (req->ring_index - cnt); - if (req->cnt < (req_cnt + 2)) - goto queuing_error; } + if (req->cnt < (req_cnt + 2)) + goto queuing_error; + status |= QDSS_GOT_Q_SPACE; /* Build header part of command packet (excluding the OPCODE). */ @@ -1919,7 +1898,7 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) logio->port_id[0] = sp->fcport->d_id.b.al_pa; logio->port_id[1] = sp->fcport->d_id.b.area; logio->port_id[2] = sp->fcport->d_id.b.domain; - logio->vp_index = sp->fcport->vha->vp_idx; + logio->vp_index = sp->fcport->vp_idx; } static void @@ -1943,7 +1922,7 @@ qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx) mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | sp->fcport->d_id.b.al_pa); - mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); + mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); } static void @@ -1956,7 +1935,7 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio) logio->port_id[0] = sp->fcport->d_id.b.al_pa; logio->port_id[1] = sp->fcport->d_id.b.area; logio->port_id[2] = sp->fcport->d_id.b.domain; - logio->vp_index = sp->fcport->vha->vp_idx; + logio->vp_index = sp->fcport->vp_idx; } static void @@ -1973,7 +1952,7 @@ qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx) mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | sp->fcport->d_id.b.al_pa); - mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); + mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); /* Implicit: mbx->mbx10 = 0. */ } @@ -1983,7 +1962,7 @@ qla24xx_adisc_iocb(srb_t *sp, struct logio_entry_24xx *logio) logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; logio->control_flags = cpu_to_le16(LCF_COMMAND_ADISC); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); - logio->vp_index = sp->fcport->vha->vp_idx; + logio->vp_index = sp->fcport->vp_idx; } static void @@ -2004,7 +1983,7 @@ qla2x00_adisc_iocb(srb_t *sp, struct mbx_entry *mbx) mbx->mb3 = cpu_to_le16(LSW(ha->async_pd_dma)); mbx->mb6 = cpu_to_le16(MSW(MSD(ha->async_pd_dma))); mbx->mb7 = cpu_to_le16(LSW(MSD(ha->async_pd_dma))); - mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); + mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); } static void @@ -2030,7 +2009,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) tsk->port_id[0] = fcport->d_id.b.al_pa; tsk->port_id[1] = fcport->d_id.b.area; tsk->port_id[2] = fcport->d_id.b.domain; - tsk->vp_index = fcport->vha->vp_idx; + tsk->vp_index = fcport->vp_idx; if (flags == TCF_LUN_RESET) { int_to_scsilun(lun, &tsk->lun); @@ -2051,7 +2030,7 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) els_iocb->handle = sp->handle; els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); els_iocb->tx_dsd_count = __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt); - els_iocb->vp_index = sp->fcport->vha->vp_idx; + els_iocb->vp_index = sp->fcport->vp_idx; els_iocb->sof_type = EST_SOFI3; els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt); @@ -2181,7 +2160,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) ct_iocb->handle = sp->handle; ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); - ct_iocb->vp_index = sp->fcport->vha->vp_idx; + ct_iocb->vp_index = sp->fcport->vp_idx; ct_iocb->comp_status = __constant_cpu_to_le16(0); ct_iocb->cmd_dsd_count = @@ -2364,10 +2343,11 @@ qla82xx_start_scsi(srb_t *sp) else req->cnt = req->length - (req->ring_index - cnt); - if (req->cnt < (req_cnt + 2)) - goto queuing_error; } + if (req->cnt < (req_cnt + 2)) + goto queuing_error; + ctx = sp->u.scmd.ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); if (!ctx) { @@ -2382,7 +2362,7 @@ qla82xx_start_scsi(srb_t *sp) if (!ctx->fcp_cmnd) { ql_log(ql_log_fatal, vha, 0x3011, "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd); - goto queuing_error; + goto queuing_error_fcp_cmnd; } /* Initialize the DSD list and dma handle */ @@ -2420,7 +2400,7 @@ qla82xx_start_scsi(srb_t *sp) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->vp_index = sp->fcport->vha->vp_idx; + cmd_pkt->vp_index = sp->fcport->vp_idx; /* Build IOCB segments */ if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds)) @@ -2509,7 +2489,7 @@ qla82xx_start_scsi(srb_t *sp) cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->vp_index = sp->fcport->vha->vp_idx; + cmd_pkt->vp_index = sp->fcport->vp_idx; int_to_scsilun(cmd->device->lun, &cmd_pkt->lun); host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index 6f67a9d4998b..ce42288049b5 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -5,7 +5,6 @@ * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" -#include "qla_target.h" #include #include @@ -310,28 +309,6 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) "IDC failed to post ACK.\n"); } -#define LS_UNKNOWN 2 -char * -qla2x00_get_link_speed_str(struct qla_hw_data *ha) -{ - static char *link_speeds[] = {"1", "2", "?", "4", "8", "16", "10"}; - char *link_speed; - int fw_speed = ha->link_data_rate; - - if (IS_QLA2100(ha) || IS_QLA2200(ha)) - link_speed = link_speeds[0]; - else if (fw_speed == 0x13) - link_speed = link_speeds[6]; - else { - link_speed = link_speeds[LS_UNKNOWN]; - if (fw_speed < 6) - link_speed = - link_speeds[fw_speed]; - } - - return link_speed; -} - /** * qla2x00_async_event() - Process aynchronous events. * @ha: SCSI driver HA context @@ -340,6 +317,9 @@ qla2x00_get_link_speed_str(struct qla_hw_data *ha) void qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) { +#define LS_UNKNOWN 2 + static char *link_speeds[] = { "1", "2", "?", "4", "8", "16", "10" }; + char *link_speed; uint16_t handle_cnt; uint16_t cnt, mbx; uint32_t handles[5]; @@ -474,8 +454,8 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ ql_dbg(ql_dbg_async, vha, 0x5008, "Asynchronous WAKEUP_THRES.\n"); - break; + case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ ql_dbg(ql_dbg_async, vha, 0x5009, "LIP occurred (%x).\n", mb[1]); @@ -499,14 +479,20 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) break; case MBA_LOOP_UP: /* Loop Up Event */ - if (IS_QLA2100(ha) || IS_QLA2200(ha)) + if (IS_QLA2100(ha) || IS_QLA2200(ha)) { + link_speed = link_speeds[0]; ha->link_data_rate = PORT_SPEED_1GB; - else + } else { + link_speed = link_speeds[LS_UNKNOWN]; + if (mb[1] < 6) + link_speed = link_speeds[mb[1]]; + else if (mb[1] == 0x13) + link_speed = link_speeds[6]; ha->link_data_rate = mb[1]; + } ql_dbg(ql_dbg_async, vha, 0x500a, - "LOOP UP detected (%s Gbps).\n", - qla2x00_get_link_speed_str(ha)); + "LOOP UP detected (%s Gbps).\n", link_speed); vha->flags.management_server_logged_in = 0; qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate); @@ -652,8 +638,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ql_dbg(ql_dbg_async, vha, 0x5010, "Port unavailable %04x %04x %04x.\n", mb[1], mb[2], mb[3]); - ql_log(ql_log_warn, vha, 0x505e, - "Link is offline.\n"); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); @@ -686,17 +670,12 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", mb[1], mb[2], mb[3]); - - qlt_async_event(mb[0], vha, mb); break; } ql_dbg(ql_dbg_async, vha, 0x5012, "Port database changed %04x %04x %04x.\n", mb[1], mb[2], mb[3]); - ql_log(ql_log_warn, vha, 0x505f, - "Link is operational (%s Gbps).\n", - qla2x00_get_link_speed_str(ha)); /* * Mark all devices as missing so we will login again. @@ -705,13 +684,8 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) qla2x00_mark_all_devices_lost(vha, 1); - if (vha->vp_idx == 0 && !qla_ini_mode_enabled(vha)) - set_bit(SCR_PENDING, &vha->dpc_flags); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); - - qlt_async_event(mb[0], vha, mb); break; case MBA_RSCN_UPDATE: /* State Change Registration */ @@ -833,8 +807,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) mb[0], mb[1], mb[2], mb[3]); } - qlt_async_event(mb[0], vha, mb); - if (!vha->vp_idx && ha->num_vhosts) qla2x00_alert_all_vps(rsp, mb); } @@ -1200,9 +1172,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, } else if (iop[0] & BIT_5) fcport->port_type = FCT_INITIATOR; - if (iop[0] & BIT_7) - fcport->flags |= FCF_CONF_COMP_SUPPORTED; - if (logio->io_parameter[7] || logio->io_parameter[8]) fcport->supported_classes |= FC_COS_CLASS2; if (logio->io_parameter[9] || logio->io_parameter[10]) @@ -2017,9 +1986,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, if (pkt->entry_status != 0) { qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); - - (void)qlt_24xx_process_response_error(vha, pkt); - ((response_t *)pkt)->signature = RESPONSE_PROCESSED; wmb(); continue; @@ -2050,14 +2016,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, case ELS_IOCB_TYPE: qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); break; - case ABTS_RECV_24XX: - /* ensure that the ATIO queue is empty */ - qlt_24xx_process_atio_queue(vha); - case ABTS_RESP_24XX: - case CTIO_TYPE7: - case NOTIFY_ACK_TYPE: - qlt_response_pkt_all_vps(vha, (response_t *)pkt); - break; case MARKER_TYPE: /* Do nothing in this case, this check is to prevent it * from falling into default case @@ -2210,13 +2168,6 @@ qla24xx_intr_handler(int irq, void *dev_id) case 0x14: qla24xx_process_response_queue(vha, rsp); break; - case 0x1C: /* ATIO queue updated */ - qlt_24xx_process_atio_queue(vha); - break; - case 0x1D: /* ATIO and response queues updated */ - qlt_24xx_process_atio_queue(vha); - qla24xx_process_response_queue(vha, rsp); - break; default: ql_dbg(ql_dbg_async, vha, 0x504f, "Unrecognized interrupt type (%d).\n", stat * 0xff); @@ -2361,13 +2312,6 @@ qla24xx_msix_default(int irq, void *dev_id) case 0x14: qla24xx_process_response_queue(vha, rsp); break; - case 0x1C: /* ATIO queue updated */ - qlt_24xx_process_atio_queue(vha); - break; - case 0x1D: /* ATIO and response queues updated */ - qlt_24xx_process_atio_queue(vha); - qla24xx_process_response_queue(vha, rsp); - break; default: ql_dbg(ql_dbg_async, vha, 0x5051, "Unrecognized interrupt type (%d).\n", stat & 0xff); @@ -2620,15 +2564,7 @@ void qla2x00_free_irqs(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - struct rsp_que *rsp; - - /* - * We need to check that ha->rsp_q_map is valid in case we are called - * from a probe failure context. - */ - if (!ha->rsp_q_map || !ha->rsp_q_map[0]) - return; - rsp = ha->rsp_q_map[0]; + struct rsp_que *rsp = ha->rsp_q_map[0]; if (ha->flags.msix_enabled) qla24xx_disable_msix(ha); diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index d5ce92c0a8fc..b4a23394a7bd 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -5,7 +5,6 @@ * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" -#include "qla_target.h" #include #include @@ -271,8 +270,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ictrl = RD_REG_WORD(®->isp.ictrl); } ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, - "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " - "mb[0]=0x%x\n", command, ictrl, jiffies, mb0); + "MBX Command timeout for cmd %x.\n", command); + ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111a, + "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies); + ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111b, + "mb[0] = 0x%x.\n", mb0); ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019); /* @@ -318,7 +320,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) CRB_NIU_XG_PAUSE_CTL_P1); } ql_log(ql_log_info, base_vha, 0x101c, - "Mailbox cmd timeout occurred, cmd=0x%x, " + "Mailbox cmd timeout occured, cmd=0x%x, " "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP " "abort.\n", command, mcp->mb[0], ha->flags.eeh_busy); @@ -343,7 +345,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) CRB_NIU_XG_PAUSE_CTL_P1); } ql_log(ql_log_info, base_vha, 0x101e, - "Mailbox cmd timeout occurred, cmd=0x%x, " + "Mailbox cmd timeout occured, cmd=0x%x, " "mb[0]=0x%x. Scheduling ISP abort ", command, mcp->mb[0]); set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); @@ -388,8 +390,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__); if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) { mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; @@ -423,8 +424,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, ql_dbg(ql_dbg_mbx, vha, 0x1023, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__); } return rval; @@ -454,8 +454,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__); mcp->mb[0] = MBC_EXECUTE_FIRMWARE; mcp->out_mb = MBX_0; @@ -490,11 +489,10 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { if (IS_FWI2_CAPABLE(ha)) { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027, + ql_dbg(ql_dbg_mbx, vha, 0x1027, "Done exchanges=%x.\n", mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__); } } @@ -525,8 +523,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; mcp->out_mb = MBX_0; @@ -564,11 +561,11 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ha->fw_attributes_h = mcp->mb[15]; ha->fw_attributes_ext[0] = mcp->mb[16]; ha->fw_attributes_ext[1] = mcp->mb[17]; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139, + ql_dbg(ql_dbg_mbx, vha, 0x1139, "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n", __func__, mcp->mb[15], mcp->mb[6]); } else - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f, + ql_dbg(ql_dbg_mbx, vha, 0x112f, "%s: FwAttributes [Upper] invalid, MB6:%04x\n", __func__, mcp->mb[6]); } @@ -579,8 +576,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__); } return rval; } @@ -606,8 +602,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; mcp->out_mb = MBX_0; @@ -625,8 +620,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) fwopts[2] = mcp->mb[2]; fwopts[3] = mcp->mb[3]; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__); } return rval; @@ -654,8 +648,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__); mcp->mb[0] = MBC_SET_FIRMWARE_OPTION; mcp->mb[1] = fwopts[1]; @@ -683,8 +676,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts) "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__); } return rval; @@ -712,8 +704,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__); mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; mcp->mb[1] = 0xAAAA; @@ -743,8 +734,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__); } return rval; @@ -772,8 +762,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__); mcp->mb[0] = MBC_VERIFY_CHECKSUM; mcp->out_mb = MBX_0; @@ -798,8 +787,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr) "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ? (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__); } return rval; @@ -831,8 +819,7 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__); mcp->mb[0] = MBC_IOCB_COMMAND_A64; mcp->mb[1] = 0; @@ -855,8 +842,7 @@ qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer, /* Mask reserved bits. */ sts_entry->entry_status &= IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__); } return rval; @@ -898,8 +884,7 @@ qla2x00_abort_command(srb_t *sp) struct req_que *req = vha->req; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__); spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { @@ -930,8 +915,7 @@ qla2x00_abort_command(srb_t *sp) if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__); } return rval; @@ -950,8 +934,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag) l = l; vha = fcport->vha; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__); req = vha->hw->req_q_map[0]; rsp = req->rsp; @@ -972,8 +955,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag) mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f, - "Failed=%x.\n", rval); + ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval); } /* Issue marker IOCB. */ @@ -983,8 +965,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag) ql_dbg(ql_dbg_mbx, vha, 0x1040, "Failed to issue marker IOCB (%x).\n", rval2); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__); } return rval; @@ -1002,8 +983,7 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag) vha = fcport->vha; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__); req = vha->hw->req_q_map[0]; rsp = req->rsp; @@ -1032,8 +1012,7 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag) ql_dbg(ql_dbg_mbx, vha, 0x1044, "Failed to issue marker IOCB (%x).\n", rval2); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__); } return rval; @@ -1067,8 +1046,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; mcp->mb[9] = vha->vp_idx; @@ -1096,8 +1074,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, /*EMPTY*/ ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__); if (IS_CNA_CAPABLE(vha->hw)) { vha->fcoe_vlan_id = mcp->mb[9] & 0xfff; @@ -1138,8 +1115,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_RETRY_COUNT; mcp->out_mb = MBX_0; @@ -1162,7 +1138,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov, *tov = ratov; } - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b, + ql_dbg(ql_dbg_mbx, vha, 0x104b, "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov); } @@ -1194,8 +1170,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__); if (IS_QLA82XX(ha) && ql2xdbwr) qla82xx_wr_32(ha, ha->nxdb_wr_ptr, @@ -1238,100 +1213,9 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e, - "Done %s.\n", __func__); - } - - return rval; -} - -/* - * qla2x00_get_node_name_list - * Issue get node name list mailbox command, kmalloc() - * and return the resulting list. Caller must kfree() it! - * - * Input: - * ha = adapter state pointer. - * out_data = resulting list - * out_len = length of the resulting list - * - * Returns: - * qla2x00 local function return status code. - * - * Context: - * Kernel context. - */ -int -qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_port_24xx_data *list = NULL; - void *pmap; - mbx_cmd_t mc; - dma_addr_t pmap_dma; - ulong dma_size; - int rval, left; - - left = 1; - while (left > 0) { - dma_size = left * sizeof(*list); - pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size, - &pmap_dma, GFP_KERNEL); - if (!pmap) { - ql_log(ql_log_warn, vha, 0x113f, - "%s(%ld): DMA Alloc failed of %ld\n", - __func__, vha->host_no, dma_size); - rval = QLA_MEMORY_ALLOC_FAILED; - goto out; - } - - mc.mb[0] = MBC_PORT_NODE_NAME_LIST; - mc.mb[1] = BIT_1 | BIT_3; - mc.mb[2] = MSW(pmap_dma); - mc.mb[3] = LSW(pmap_dma); - mc.mb[6] = MSW(MSD(pmap_dma)); - mc.mb[7] = LSW(MSD(pmap_dma)); - mc.mb[8] = dma_size; - mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8; - mc.in_mb = MBX_0|MBX_1; - mc.tov = 30; - mc.flags = MBX_DMA_IN; - - rval = qla2x00_mailbox_command(vha, &mc); - if (rval != QLA_SUCCESS) { - if ((mc.mb[0] == MBS_COMMAND_ERROR) && - (mc.mb[1] == 0xA)) { - left += le16_to_cpu(mc.mb[2]) / - sizeof(struct qla_port_24xx_data); - goto restart; - } - goto out_free; - } - - left = 0; - - list = kzalloc(dma_size, GFP_KERNEL); - if (!list) { - ql_log(ql_log_warn, vha, 0x1140, - "%s(%ld): failed to allocate node names list " - "structure.\n", __func__, vha->host_no); - rval = QLA_MEMORY_ALLOC_FAILED; - goto out_free; - } - - memcpy(list, pmap, dma_size); -restart: - dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); + ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__); } - *out_data = list; - *out_len = dma_size; - -out: - return rval; - -out_free: - dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); return rval; } @@ -1362,8 +1246,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) dma_addr_t pd_dma; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__); pd24 = NULL; pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); @@ -1443,13 +1326,6 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) fcport->port_type = FCT_INITIATOR; else fcport->port_type = FCT_TARGET; - - /* Passback COS information. */ - fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ? - FC_COS_CLASS2 : FC_COS_CLASS3; - - if (pd24->prli_svc_param_word_3[0] & BIT_7) - fcport->flags |= FCF_CONF_COMP_SUPPORTED; } else { uint64_t zero = 0; @@ -1502,8 +1378,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__); } return rval; @@ -1532,8 +1407,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->out_mb = MBX_0; @@ -1559,8 +1433,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__); } return rval; @@ -1592,8 +1465,7 @@ qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_PORT_NAME; mcp->mb[9] = vha->vp_idx; @@ -1627,8 +1499,7 @@ qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name, name[7] = LSB(mcp->mb[7]); } - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__); } return rval; @@ -1656,8 +1527,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__); if (IS_CNA_CAPABLE(vha->hw)) { /* Logout across all FCFs. */ @@ -1694,8 +1564,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__); } return rval; @@ -1727,10 +1596,9 @@ qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e, + ql_dbg(ql_dbg_mbx, vha, 0x105e, "Retry cnt=%d ratov=%d total tov=%d.\n", vha->hw->retry_count, vha->hw->login_timeout, mcp->tov); @@ -1754,8 +1622,7 @@ qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address, rval, mcp->mb[0], mcp->mb[1]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__); } return rval; @@ -1774,8 +1641,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, struct req_que *req; struct rsp_que *rsp; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__); if (ha->flags.cpu_affinity_enabled) req = ha->req_q_map[0]; @@ -1849,8 +1715,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, break; } } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__); iop[0] = le32_to_cpu(lg->io_parameter[0]); @@ -1868,10 +1733,6 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, mb[10] |= BIT_0; /* Class 2. */ if (lg->io_parameter[9] || lg->io_parameter[10]) mb[10] |= BIT_1; /* Class 3. */ - if (lg->io_parameter[0] & __constant_cpu_to_le32(BIT_7)) - mb[10] |= BIT_7; /* Confirmed Completion - * Allowed - */ } dma_pool_free(ha->s_dma_pool, lg, lg_dma); @@ -1909,8 +1770,7 @@ qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__); mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; @@ -1958,8 +1818,7 @@ qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__); } return rval; @@ -1990,8 +1849,7 @@ qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__); if (IS_FWI2_CAPABLE(ha)) return qla24xx_login_fabric(vha, fcport->loop_id, @@ -2033,8 +1891,7 @@ qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport, rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__); } return (rval); @@ -2051,8 +1908,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, struct req_que *req; struct rsp_que *rsp; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__); lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); if (lg == NULL) { @@ -2096,8 +1952,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, le32_to_cpu(lg->io_parameter[1])); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__); } dma_pool_free(ha->s_dma_pool, lg, lg_dma); @@ -2129,8 +1984,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__); mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; mcp->out_mb = MBX_1|MBX_0; @@ -2153,8 +2007,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__); } return rval; @@ -2182,8 +2035,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__); mcp->mb[0] = MBC_LIP_FULL_LOGIN; mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0; @@ -2200,8 +2052,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__); } return rval; @@ -2227,8 +2078,7 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__); if (id_list == NULL) return QLA_FUNCTION_FAILED; @@ -2260,8 +2110,7 @@ qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma, ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval); } else { *entries = mcp->mb[1]; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__); } return rval; @@ -2289,8 +2138,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; mcp->out_mb = MBX_0; @@ -2306,7 +2154,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, ql_dbg(ql_dbg_mbx, vha, 0x107d, "Failed mb[0]=%x.\n", mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e, + ql_dbg(ql_dbg_mbx, vha, 0x107e, "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x " "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10], @@ -2353,8 +2201,7 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map) dma_addr_t pmap_dma; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__); pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma); if (pmap == NULL) { @@ -2377,7 +2224,7 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map) rval = qla2x00_mailbox_command(vha, mcp); if (rval == QLA_SUCCESS) { - ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081, + ql_dbg(ql_dbg_mbx, vha, 0x1081, "mb0/mb1=%x/%X FC/AL position map size (%x).\n", mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]); ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d, @@ -2391,8 +2238,7 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map) if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__); } return rval; @@ -2421,8 +2267,7 @@ qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id, uint32_t *siter, *diter, dwords; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_LINK_STATUS; mcp->mb[2] = MSW(stats_dma); @@ -2456,8 +2301,7 @@ qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id, rval = QLA_FUNCTION_FAILED; } else { /* Copy over data -- firmware data is LE. */ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__); dwords = offsetof(struct link_statistics, unused1) / 4; siter = diter = &stats->link_fail_cnt; while (dwords--) @@ -2480,8 +2324,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, mbx_cmd_t *mcp = &mc; uint32_t *siter, *diter, dwords; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; mcp->mb[2] = MSW(stats_dma); @@ -2503,8 +2346,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, "Failed mb[0]=%x.\n", mcp->mb[0]); rval = QLA_FUNCTION_FAILED; } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__); /* Copy over data -- firmware data is LE. */ dwords = sizeof(struct link_statistics) / 4; siter = diter = &stats->link_fail_cnt; @@ -2533,8 +2375,7 @@ qla24xx_abort_command(srb_t *sp) struct qla_hw_data *ha = vha->hw; struct req_que *req = vha->req; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__); spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { @@ -2563,7 +2404,7 @@ qla24xx_abort_command(srb_t *sp) abt->port_id[0] = fcport->d_id.b.al_pa; abt->port_id[1] = fcport->d_id.b.area; abt->port_id[2] = fcport->d_id.b.domain; - abt->vp_index = fcport->vha->vp_idx; + abt->vp_index = fcport->vp_idx; abt->req_que_no = cpu_to_le16(req->id); @@ -2582,8 +2423,7 @@ qla24xx_abort_command(srb_t *sp) le16_to_cpu(abt->nport_handle)); rval = QLA_FUNCTION_FAILED; } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__); } dma_pool_free(ha->s_dma_pool, abt, abt_dma); @@ -2615,8 +2455,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, ha = vha->hw; req = vha->req; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__); if (ha->flags.cpu_affinity_enabled) rsp = ha->rsp_q_map[tag + 1]; @@ -2639,7 +2478,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; tsk->p.tsk.port_id[1] = fcport->d_id.b.area; tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; - tsk->p.tsk.vp_index = fcport->vha->vp_idx; + tsk->p.tsk.vp_index = fcport->vp_idx; if (type == TCF_LUN_RESET) { int_to_scsilun(l, &tsk->p.tsk.lun); host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, @@ -2665,7 +2504,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, } else if (le16_to_cpu(sts->scsi_status) & SS_RESPONSE_INFO_LEN_VALID) { if (le32_to_cpu(sts->rsp_data_len) < 4) { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097, + ql_dbg(ql_dbg_mbx, vha, 0x1097, "Ignoring inconsistent data length -- not enough " "response info (%d).\n", le32_to_cpu(sts->rsp_data_len)); @@ -2684,8 +2523,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, ql_dbg(ql_dbg_mbx, vha, 0x1099, "Failed to issue marker IOCB (%x).\n", rval2); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__); } dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); @@ -2726,8 +2564,7 @@ qla2x00_system_error(scsi_qla_host_t *vha) if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__); mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; mcp->out_mb = MBX_0; @@ -2739,8 +2576,7 @@ qla2x00_system_error(scsi_qla_host_t *vha) if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__); } return rval; @@ -2760,8 +2596,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__); mcp->mb[0] = MBC_SERDES_PARAMS; mcp->mb[1] = BIT_0; @@ -2780,8 +2615,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { /*EMPTY*/ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__); } return rval; @@ -2797,8 +2631,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *vha) if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__); mcp->mb[0] = MBC_STOP_FIRMWARE; mcp->mb[1] = 0; @@ -2813,8 +2646,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *vha) if (mcp->mb[0] == MBS_INVALID_COMMAND) rval = QLA_INVALID_COMMAND; } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__); } return rval; @@ -2828,8 +2660,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -2855,8 +2686,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__); } return rval; @@ -2869,8 +2699,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -2890,8 +2719,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__); } return rval; @@ -2905,8 +2733,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__); if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) @@ -2937,8 +2764,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__); if (mb) memcpy(mb, mcp->mb, 8 * sizeof(*mb)); @@ -2956,8 +2782,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -2979,8 +2804,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__); if (wr) *wr = (uint64_t) mcp->mb[5] << 48 | @@ -3005,8 +2829,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__); if (!IS_IIDMA_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -3031,8 +2854,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__); if (port_speed) *port_speed = mcp->mb[3]; } @@ -3048,8 +2870,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__); if (!IS_IIDMA_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -3076,11 +2897,9 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, } if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_mbx, vha, 0x10b4, - "Failed=%x.\n", rval); + ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__); } return rval; @@ -3096,25 +2915,24 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, scsi_qla_host_t *vp; unsigned long flags; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__); if (rptid_entry->entry_status != 0) return; if (rptid_entry->format == 0) { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7, + ql_dbg(ql_dbg_mbx, vha, 0x10b7, "Format 0 : Number of VPs setup %d, number of " "VPs acquired %d.\n", MSB(le16_to_cpu(rptid_entry->vp_count)), LSB(le16_to_cpu(rptid_entry->vp_count))); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8, + ql_dbg(ql_dbg_mbx, vha, 0x10b8, "Primary port id %02x%02x%02x.\n", rptid_entry->port_id[2], rptid_entry->port_id[1], rptid_entry->port_id[0]); } else if (rptid_entry->format == 1) { vp_idx = LSB(stat); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9, + ql_dbg(ql_dbg_mbx, vha, 0x10b9, "Format 1: VP[%d] enabled - status %d - with " "port id %02x%02x%02x.\n", vp_idx, MSB(stat), rptid_entry->port_id[2], rptid_entry->port_id[1], @@ -3181,8 +2999,7 @@ qla24xx_modify_vp_config(scsi_qla_host_t *vha) /* This can be called by the parent */ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__); vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma); if (!vpmod) { @@ -3198,9 +3015,6 @@ qla24xx_modify_vp_config(scsi_qla_host_t *vha) vpmod->vp_count = 1; vpmod->vp_index1 = vha->vp_idx; vpmod->options_idx1 = BIT_3|BIT_4|BIT_5; - - qlt_modify_vp_config(vha, vpmod); - memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE); memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE); vpmod->entry_count = 1; @@ -3221,8 +3035,7 @@ qla24xx_modify_vp_config(scsi_qla_host_t *vha) rval = QLA_FUNCTION_FAILED; } else { /* EMPTY */ - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__); fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING); } dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma); @@ -3256,7 +3069,7 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) int vp_index = vha->vp_idx; struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1, + ql_dbg(ql_dbg_mbx, vha, 0x10c1, "Entered %s enabling index %d.\n", __func__, vp_index); if (vp_index == 0 || vp_index >= ha->max_npiv_vports) @@ -3299,8 +3112,7 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) le16_to_cpu(vce->comp_status)); rval = QLA_FUNCTION_FAILED; } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__); } dma_pool_free(ha->s_dma_pool, vce, vce_dma); @@ -3337,8 +3149,14 @@ qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__); + + /* + * This command is implicitly executed by firmware during login for the + * physical hosts + */ + if (vp_idx == 0) + return QLA_FUNCTION_FAILED; mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; mcp->mb[1] = format; @@ -3367,8 +3185,7 @@ qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__); if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) { mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; @@ -3402,8 +3219,7 @@ qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, ql_dbg(ql_dbg_mbx, vha, 0x1008, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__); } return rval; @@ -3428,8 +3244,7 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) unsigned long flags; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__); mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); if (mn == NULL) { @@ -3470,7 +3285,7 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) status[0] = le16_to_cpu(mn->p.rsp.comp_status); status[1] = status[0] == CS_VCS_CHIP_FAILURE ? le16_to_cpu(mn->p.rsp.failure_code) : 0; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce, + ql_dbg(ql_dbg_mbx, vha, 0x10ce, "cs=%x fc=%x.\n", status[0], status[1]); if (status[0] != CS_COMPLETE) { @@ -3484,7 +3299,7 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) retry = 1; } } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0, + ql_dbg(ql_dbg_mbx, vha, 0x10d0, "Firmware updated to %x.\n", le32_to_cpu(mn->p.rsp.fw_ver)); @@ -3501,11 +3316,9 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) dma_pool_free(ha->s_dma_pool, mn, mn_dma); if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_mbx, vha, 0x10d1, - "Failed=%x.\n", rval); + ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__); } return rval; @@ -3521,8 +3334,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) struct device_reg_25xxmq __iomem *reg; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__); mcp->mb[0] = MBC_INITIALIZE_MULTIQ; mcp->mb[1] = req->options; @@ -3576,8 +3388,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) ql_dbg(ql_dbg_mbx, vha, 0x10d4, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__); } return rval; @@ -3593,8 +3404,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) struct device_reg_25xxmq __iomem *reg; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__); mcp->mb[0] = MBC_INITIALIZE_MULTIQ; mcp->mb[1] = rsp->options; @@ -3646,8 +3456,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) ql_dbg(ql_dbg_mbx, vha, 0x10d7, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__); } return rval; @@ -3660,8 +3469,7 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__); mcp->mb[0] = MBC_IDC_ACK; memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); @@ -3675,8 +3483,7 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) ql_dbg(ql_dbg_mbx, vha, 0x10da, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__); } return rval; @@ -3689,8 +3496,7 @@ qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__); if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) return QLA_FUNCTION_FAILED; @@ -3708,8 +3514,7 @@ qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__); *sector_size = mcp->mb[1]; } @@ -3726,8 +3531,7 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__); mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE : @@ -3743,8 +3547,7 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__); } return rval; @@ -3760,8 +3563,7 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__); mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR; @@ -3780,8 +3582,7 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__); } return rval; @@ -3794,8 +3595,7 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__); mcp->mb[0] = MBC_RESTART_MPI_FW; mcp->out_mb = MBX_0; @@ -3809,8 +3609,7 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__); } return rval; @@ -3825,8 +3624,7 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; @@ -3856,8 +3654,7 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, ql_dbg(ql_dbg_mbx, vha, 0x10e9, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__); } return rval; @@ -3872,8 +3669,7 @@ qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; @@ -3903,8 +3699,7 @@ qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, ql_dbg(ql_dbg_mbx, vha, 0x10ec, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__); } return rval; @@ -3918,8 +3713,7 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__); if (!IS_CNA_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -3941,8 +3735,7 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__); *actual_size = mcp->mb[2] << 2; @@ -3959,8 +3752,7 @@ qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__); if (!IS_CNA_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -3983,8 +3775,7 @@ qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__); } return rval; @@ -3997,8 +3788,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -4015,8 +3805,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data) ql_dbg(ql_dbg_mbx, vha, 0x10f5, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__); *data = mcp->mb[3] << 16 | mcp->mb[2]; } @@ -4032,8 +3821,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, mbx_cmd_t *mcp = &mc; uint32_t iter_cnt = 0x1; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__); memset(mcp->mb, 0 , sizeof(mcp->mb)); mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; @@ -4077,8 +3865,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[18], mcp->mb[19]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__); } /* Copy mailbox information */ @@ -4095,8 +3882,7 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__); memset(mcp->mb, 0 , sizeof(mcp->mb)); mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; @@ -4140,8 +3926,7 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, mcp->mb[0], mcp->mb[1]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__); } /* Copy mailbox information */ @@ -4156,7 +3941,7 @@ qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd, + ql_dbg(ql_dbg_mbx, vha, 0x10fd, "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic); mcp->mb[0] = MBC_ISP84XX_RESET; @@ -4170,8 +3955,7 @@ qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic) if (rval != QLA_SUCCESS) ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval); else - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__); return rval; } @@ -4183,8 +3967,7 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(vha->hw)) return QLA_FUNCTION_FAILED; @@ -4203,8 +3986,7 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) ql_dbg(ql_dbg_mbx, vha, 0x1101, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__); } return rval; @@ -4221,8 +4003,7 @@ qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb) rval = QLA_SUCCESS; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__); clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); @@ -4265,8 +4046,7 @@ qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb) ql_dbg(ql_dbg_mbx, vha, 0x1104, "Failed=%x mb[0]=%x.\n", rval, mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__); } return rval; @@ -4280,8 +4060,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; @@ -4299,8 +4078,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x1107, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__); if (mcp->mb[1] != 0x7) ha->link_data_rate = mcp->mb[1]; } @@ -4316,8 +4094,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__); if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) return QLA_FUNCTION_FAILED; @@ -4336,8 +4113,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) /* Copy all bits to preserve original value */ memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4); - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__); } return rval; } @@ -4349,8 +4125,7 @@ qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__); mcp->mb[0] = MBC_SET_PORT_CONFIG; /* Copy all bits to preserve original setting */ @@ -4365,8 +4140,7 @@ qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb) ql_dbg(ql_dbg_mbx, vha, 0x110d, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__); return rval; } @@ -4381,8 +4155,7 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, mbx_cmd_t *mcp = &mc; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__); if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) return QLA_FUNCTION_FAILED; @@ -4410,8 +4183,7 @@ qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__); } return rval; @@ -4424,8 +4196,7 @@ qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac) uint8_t byte; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ca, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__); /* Integer part */ rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0); @@ -4445,8 +4216,7 @@ qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac) } *frac = (byte >> 6) * 25; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1018, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__); fail: return rval; } @@ -4459,8 +4229,7 @@ qla82xx_mbx_intr_enable(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__); if (!IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; @@ -4479,8 +4248,7 @@ qla82xx_mbx_intr_enable(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x1016, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__); } return rval; @@ -4494,8 +4262,7 @@ qla82xx_mbx_intr_disable(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__); if (!IS_QLA82XX(ha)) return QLA_FUNCTION_FAILED; @@ -4514,8 +4281,7 @@ qla82xx_mbx_intr_disable(scsi_qla_host_t *vha) ql_dbg(ql_dbg_mbx, vha, 0x100c, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__); } return rval; @@ -4529,8 +4295,7 @@ qla82xx_md_get_template_size(scsi_qla_host_t *vha) mbx_cmd_t *mcp = &mc; int rval = QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__); memset(mcp->mb, 0 , sizeof(mcp->mb)); mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); @@ -4553,8 +4318,7 @@ qla82xx_md_get_template_size(scsi_qla_host_t *vha) (mcp->mb[1] << 16) | mcp->mb[0], (mcp->mb[3] << 16) | mcp->mb[2]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__); ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]); if (!ha->md_template_size) { ql_dbg(ql_dbg_mbx, vha, 0x1122, @@ -4573,8 +4337,7 @@ qla82xx_md_get_template(scsi_qla_host_t *vha) mbx_cmd_t *mcp = &mc; int rval = QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__); ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); @@ -4609,8 +4372,7 @@ qla82xx_md_get_template(scsi_qla_host_t *vha) ((mcp->mb[1] << 16) | mcp->mb[0]), ((mcp->mb[3] << 16) | mcp->mb[2])); } else - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__); return rval; } @@ -4625,8 +4387,7 @@ qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__); memset(mcp, 0, sizeof(mbx_cmd_t)); mcp->mb[0] = MBC_SET_LED_CONFIG; @@ -4651,8 +4412,7 @@ qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) ql_dbg(ql_dbg_mbx, vha, 0x1134, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__); } return rval; @@ -4669,8 +4429,7 @@ qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__); memset(mcp, 0, sizeof(mbx_cmd_t)); mcp->mb[0] = MBC_GET_LED_CONFIG; @@ -4695,8 +4454,7 @@ qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) led_cfg[4] = mcp->mb[5]; led_cfg[5] = mcp->mb[6]; } - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__); } return rval; @@ -4713,7 +4471,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable) if (!IS_QLA82XX(ha)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127, + ql_dbg(ql_dbg_mbx, vha, 0x1127, "Entered %s.\n", __func__); memset(mcp, 0, sizeof(mbx_cmd_t)); @@ -4733,7 +4491,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable) ql_dbg(ql_dbg_mbx, vha, 0x1128, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129, + ql_dbg(ql_dbg_mbx, vha, 0x1129, "Done %s.\n", __func__); } @@ -4751,8 +4509,7 @@ qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) if (!IS_QLA83XX(ha)) return QLA_FUNCTION_FAILED; - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, - "Entered %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__); mcp->mb[0] = MBC_WRITE_REMOTE_REG; mcp->mb[1] = LSW(reg); @@ -4770,7 +4527,7 @@ qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) ql_dbg(ql_dbg_mbx, vha, 0x1131, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132, + ql_dbg(ql_dbg_mbx, vha, 0x1132, "Done %s.\n", __func__); } @@ -4786,14 +4543,13 @@ qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport) mbx_cmd_t *mcp = &mc; if (IS_QLA2100(ha) || IS_QLA2200(ha)) { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b, + ql_dbg(ql_dbg_mbx, vha, 0x113b, "Implicit LOGO Unsupported.\n"); return QLA_FUNCTION_FAILED; } - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c, - "Entering %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__); /* Perform Implicit LOGO. */ mcp->mb[0] = MBC_PORT_LOGOUT; @@ -4808,8 +4564,7 @@ qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport) ql_dbg(ql_dbg_mbx, vha, 0x113d, "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); else - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e, - "Done %s.\n", __func__); + ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__); return rval; } diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 3e8b32419e68..aa062a1b0ca4 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -6,7 +6,6 @@ */ #include "qla_def.h" #include "qla_gbl.h" -#include "qla_target.h" #include #include @@ -50,9 +49,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) spin_lock_irqsave(&ha->vport_slock, flags); list_add_tail(&vha->list, &ha->vp_list); - - qlt_update_vp_map(vha, SET_VP_IDX); - spin_unlock_irqrestore(&ha->vport_slock, flags); mutex_unlock(&ha->vport_lock); @@ -83,7 +79,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) spin_lock_irqsave(&ha->vport_slock, flags); } list_del(&vha->list); - qlt_update_vp_map(vha, RESET_VP_IDX); spin_unlock_irqrestore(&ha->vport_slock, flags); vp_id = vha->vp_idx; @@ -139,7 +134,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) list_for_each_entry(fcport, &vha->vp_fcports, list) { ql_dbg(ql_dbg_vport, vha, 0xa001, "Marking port dead, loop_id=0x%04x : %x.\n", - fcport->loop_id, fcport->vha->vp_idx); + fcport->loop_id, fcport->vp_idx); qla2x00_mark_device_lost(vha, fcport, 0, 0); qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); @@ -155,9 +150,6 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - /* Remove port id from vp target map */ - qlt_update_vp_map(vha, RESET_AL_PA); - qla2x00_mark_vp_devices_dead(vha); atomic_set(&vha->vp_state, VP_FAILED); vha->flags.management_server_logged_in = 0; @@ -303,8 +295,10 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) static int qla2x00_do_dpc_vp(scsi_qla_host_t *vha) { - ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x4012, - "Entering %s vp_flags: 0x%lx.\n", __func__, vha->vp_flags); + ql_dbg(ql_dbg_dpc, vha, 0x4012, + "Entering %s.\n", __func__); + ql_dbg(ql_dbg_dpc, vha, 0x4013, + "vp_flags: 0x%lx.\n", vha->vp_flags); qla2x00_do_work(vha); @@ -354,7 +348,7 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) } } - ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x401c, + ql_dbg(ql_dbg_dpc, vha, 0x401c, "Exiting %s.\n", __func__); return 0; } diff --git a/trunk/drivers/scsi/qla2xxx/qla_nx.c b/trunk/drivers/scsi/qla2xxx/qla_nx.c index caf627ba7fa8..de722a933438 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_nx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_nx.c @@ -1190,12 +1190,12 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) } /* Offset in flash = lower 16 bits - * Number of entries = upper 16 bits + * Number of enteries = upper 16 bits */ offset = n & 0xffffU; n = (n >> 16) & 0xffffU; - /* number of addr/value pair should not exceed 1024 entries */ + /* number of addr/value pair should not exceed 1024 enteries */ if (n >= 1024) { ql_log(ql_log_fatal, vha, 0x0071, "Card flash not initialized:n=0x%x.\n", n); @@ -2050,7 +2050,7 @@ qla82xx_intr_handler(int irq, void *dev_id) rsp = (struct rsp_que *) dev_id; if (!rsp) { - ql_log(ql_log_info, NULL, 0xb053, + ql_log(ql_log_info, NULL, 0xb054, "%s: NULL response queue pointer.\n", __func__); return IRQ_NONE; } @@ -2446,7 +2446,7 @@ qla82xx_load_fw(scsi_qla_host_t *vha) if (qla82xx_fw_load_from_flash(ha) == QLA_SUCCESS) { ql_log(ql_log_info, vha, 0x00a1, - "Firmware loaded successfully from flash.\n"); + "Firmware loaded successully from flash.\n"); return QLA_SUCCESS; } else { ql_log(ql_log_warn, vha, 0x0108, @@ -2461,7 +2461,7 @@ qla82xx_load_fw(scsi_qla_host_t *vha) blob = ha->hablob = qla2x00_request_firmware(vha); if (!blob) { ql_log(ql_log_fatal, vha, 0x00a3, - "Firmware image not present.\n"); + "Firmware image not preset.\n"); goto fw_load_failed; } @@ -2689,7 +2689,7 @@ qla82xx_write_flash_data(struct scsi_qla_host *vha, uint32_t *dwptr, if (!optrom) { ql_log(ql_log_warn, vha, 0xb01b, "Unable to allocate memory " - "for optrom burst write (%x KB).\n", + "for optron burst write (%x KB).\n", OPTROM_BURST_SIZE / 1024); } } @@ -2960,8 +2960,9 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha) * changing the state to DEV_READY */ ql_log(ql_log_info, vha, 0xb023, - "%s : QUIESCENT TIMEOUT DRV_ACTIVE:%d " - "DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME, + "%s : QUIESCENT TIMEOUT.\n", QLA2XXX_DRIVER_NAME); + ql_log(ql_log_info, vha, 0xb024, + "DRV_ACTIVE:%d DRV_STATE:%d.\n", drv_active, drv_state); qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY); @@ -3128,7 +3129,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha) if (ql2xmdenable) { if (qla82xx_md_collect(vha)) ql_log(ql_log_warn, vha, 0xb02c, - "Minidump not collected.\n"); + "Not able to collect minidump.\n"); } else ql_log(ql_log_warn, vha, 0xb04f, "Minidump disabled.\n"); @@ -3159,11 +3160,11 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha) "Firmware version differs " "Previous version: %d:%d:%d - " "New version: %d:%d:%d\n", - fw_major_version, fw_minor_version, - fw_subminor_version, ha->fw_major_version, ha->fw_minor_version, - ha->fw_subminor_version); + ha->fw_subminor_version, + fw_major_version, fw_minor_version, + fw_subminor_version); /* Release MiniDump resources */ qla82xx_md_free(vha); /* ALlocate MiniDump resources */ @@ -3324,30 +3325,6 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha) return rval; } -static int qla82xx_check_temp(scsi_qla_host_t *vha) -{ - uint32_t temp, temp_state, temp_val; - struct qla_hw_data *ha = vha->hw; - - temp = qla82xx_rd_32(ha, CRB_TEMP_STATE); - temp_state = qla82xx_get_temp_state(temp); - temp_val = qla82xx_get_temp_val(temp); - - if (temp_state == QLA82XX_TEMP_PANIC) { - ql_log(ql_log_warn, vha, 0x600e, - "Device temperature %d degrees C exceeds " - " maximum allowed. Hardware has been shut down.\n", - temp_val); - return 1; - } else if (temp_state == QLA82XX_TEMP_WARN) { - ql_log(ql_log_warn, vha, 0x600f, - "Device temperature %d degrees C exceeds " - "operating range. Immediate action needed.\n", - temp_val); - } - return 0; -} - void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; @@ -3370,20 +3347,18 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) /* don't poll if reset is going on */ if (!ha->flags.isp82xx_reset_hdlr_active) { dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - if (qla82xx_check_temp(vha)) { - set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); - ha->flags.isp82xx_fw_hung = 1; - qla82xx_clear_pending_mbx(vha); - } else if (dev_state == QLA82XX_DEV_NEED_RESET && + if (dev_state == QLA82XX_DEV_NEED_RESET && !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) { ql_log(ql_log_warn, vha, 0x6001, "Adapter reset needed.\n"); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { ql_log(ql_log_warn, vha, 0x6002, "Quiescent needed.\n"); set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); } else { if (qla82xx_check_fw_alive(vha)) { ql_dbg(ql_dbg_timer, vha, 0x6011, @@ -3423,6 +3398,7 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); } + qla2xxx_wake_dpc(vha); ha->flags.isp82xx_fw_hung = 1; ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n"); qla82xx_clear_pending_mbx(vha); @@ -4137,14 +4113,6 @@ qla82xx_md_collect(scsi_qla_host_t *vha) goto md_failed; } - if (ha->flags.isp82xx_no_md_cap) { - ql_log(ql_log_warn, vha, 0xb054, - "Forced reset from application, " - "ignore minidump capture\n"); - ha->flags.isp82xx_no_md_cap = 0; - goto md_failed; - } - if (qla82xx_validate_template_chksum(vha)) { ql_log(ql_log_info, vha, 0xb039, "Template checksum validation error\n"); diff --git a/trunk/drivers/scsi/qla2xxx/qla_nx.h b/trunk/drivers/scsi/qla2xxx/qla_nx.h index 6eb210e3cc63..4ac50e274661 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_nx.h +++ b/trunk/drivers/scsi/qla2xxx/qla_nx.h @@ -26,7 +26,6 @@ #define CRB_RCVPEG_STATE QLA82XX_REG(0x13c) #define BOOT_LOADER_DIMM_STATUS QLA82XX_REG(0x54) #define CRB_DMA_SHIFT QLA82XX_REG(0xcc) -#define CRB_TEMP_STATE QLA82XX_REG(0x1b4) #define QLA82XX_DMA_SHIFT_VALUE 0x55555555 #define QLA82XX_HW_H0_CH_HUB_ADR 0x05 @@ -562,6 +561,7 @@ #define QLA82XX_FW_VERSION_SUB (QLA82XX_CAM_RAM(0x158)) #define QLA82XX_PCIE_REG(reg) (QLA82XX_CRB_PCIE + (reg)) +#define PCIE_CHICKEN3 (0x120c8) #define PCIE_SETUP_FUNCTION (0x12040) #define PCIE_SETUP_FUNCTION2 (0x12048) @@ -1178,16 +1178,4 @@ static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, #define CRB_NIU_XG_PAUSE_CTL_P0 0x1 #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 -#define qla82xx_get_temp_val(x) ((x) >> 16) -#define qla82xx_get_temp_state(x) ((x) & 0xffff) -#define qla82xx_encode_temp(val, state) (((val) << 16) | (state)) - -/* - * Temperature control. - */ -enum { - QLA82XX_TEMP_NORMAL = 0x1, /* Normal operating range */ - QLA82XX_TEMP_WARN, /* Sound alert, temperature getting high */ - QLA82XX_TEMP_PANIC /* Fatal error, hardware has shut down. */ -}; #endif diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 6d1d873a20e2..c9c56a8427f3 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -13,13 +13,12 @@ #include #include #include + #include #include #include #include -#include "qla_target.h" - /* * Driver version */ @@ -41,12 +40,6 @@ static struct kmem_cache *ctx_cachep; */ int ql_errlev = ql_log_all; -int ql2xenableclass2; -module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); -MODULE_PARM_DESC(ql2xenableclass2, - "Specify if Class 2 operations are supported from the very " - "beginning. Default is 0 - class 2 not supported."); - int ql2xlogintimeout = 20; module_param(ql2xlogintimeout, int, S_IRUGO); MODULE_PARM_DESC(ql2xlogintimeout, @@ -262,8 +255,6 @@ struct scsi_host_template qla2xxx_driver_template = { .max_sectors = 0xFFFF, .shost_attrs = qla2x00_host_attrs, - - .supported_mode = MODE_INITIATOR, }; static struct scsi_transport_template *qla2xxx_transport_template = NULL; @@ -315,8 +306,7 @@ static void qla2x00_free_fw_dump(struct qla_hw_data *); static void qla2x00_mem_free(struct qla_hw_data *); /* -------------------------------------------------------------------------- */ -static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, - struct rsp_que *rsp) +static int qla2x00_alloc_queues(struct qla_hw_data *ha) { scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues, @@ -334,12 +324,6 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, "Unable to allocate memory for response queue ptrs.\n"); goto fail_rsp_map; } - /* - * Make sure we record at least the request and response queue zero in - * case we need to free them if part of the probe fails. - */ - ha->rsp_q_map[0] = rsp; - ha->req_q_map[0] = req; set_bit(0, ha->rsp_qid_map); set_bit(0, ha->req_qid_map); return 1; @@ -658,12 +642,12 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (ha->flags.eeh_busy) { if (ha->flags.pci_channel_io_perm_failure) { - ql_dbg(ql_dbg_aer, vha, 0x9010, + ql_dbg(ql_dbg_io, vha, 0x3001, "PCI Channel IO permanent failure, exiting " "cmd=%p.\n", cmd); cmd->result = DID_NO_CONNECT << 16; } else { - ql_dbg(ql_dbg_aer, vha, 0x9011, + ql_dbg(ql_dbg_io, vha, 0x3002, "EEH_Busy, Requeuing the cmd=%p.\n", cmd); cmd->result = DID_REQUEUE << 16; } @@ -673,7 +657,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) rval = fc_remote_port_chkready(rport); if (rval) { cmd->result = rval; - ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3003, + ql_dbg(ql_dbg_io, vha, 0x3003, "fc_remote_port_chkready failed for cmd=%p, rval=0x%x.\n", cmd, rval); goto qc24_fail_command; @@ -1152,7 +1136,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) ret = FAILED; ql_log(ql_log_info, vha, 0x8012, - "BUS RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun); + "BUS RESET ISSUED nexus=%ld:%d%d.\n", vha->host_no, id, lun); if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { ql_log(ql_log_fatal, vha, 0x8013, @@ -2196,7 +2180,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_dbg_pci(ql_dbg_init, pdev, 0x000a, "Memory allocated for ha=%p.\n", ha); ha->pdev = pdev; - ha->tgt.enable_class_2 = ql2xenableclass2; /* Clear our data area */ ha->bars = bars; @@ -2260,7 +2243,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->mbx_count = MAILBOX_REGISTER_COUNT; req_length = REQUEST_ENTRY_CNT_24XX; rsp_length = RESPONSE_ENTRY_CNT_2300; - ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; ha->max_loop_id = SNS_LAST_LOOP_ID_2300; ha->init_cb_size = sizeof(struct mid_init_cb_24xx); ha->gid_list_info_size = 8; @@ -2276,7 +2258,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->mbx_count = MAILBOX_REGISTER_COUNT; req_length = REQUEST_ENTRY_CNT_24XX; rsp_length = RESPONSE_ENTRY_CNT_2300; - ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; ha->max_loop_id = SNS_LAST_LOOP_ID_2300; ha->init_cb_size = sizeof(struct mid_init_cb_24xx); ha->gid_list_info_size = 8; @@ -2436,17 +2417,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->max_cmd_len, host->max_channel, host->max_lun, host->transportt, sht->vendor_id); -que_init: - /* Alloc arrays of request and response ring ptrs */ - if (!qla2x00_alloc_queues(ha, req, rsp)) { - ql_log(ql_log_fatal, base_vha, 0x003d, - "Failed to allocate memory for queue pointers..." - "aborting.\n"); - goto probe_init_failed; - } - - qlt_probe_one_stage1(base_vha, ha); - /* Set up the irqs */ ret = qla2x00_request_irqs(ha, rsp); if (ret) @@ -2454,10 +2424,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_save_state(pdev); - /* Assign back pointers */ + /* Alloc arrays of request and response ring ptrs */ +que_init: + if (!qla2x00_alloc_queues(ha)) { + ql_log(ql_log_fatal, base_vha, 0x003d, + "Failed to allocate memory for queue pointers.. aborting.\n"); + goto probe_init_failed; + } + + ha->rsp_q_map[0] = rsp; + ha->req_q_map[0] = req; rsp->req = req; req->rsp = rsp; - + set_bit(0, ha->req_qid_map); + set_bit(0, ha->rsp_qid_map); /* FWI2-capable only. */ req->req_q_in = &ha->iobase->isp24.req_q_in; req->req_q_out = &ha->iobase->isp24.req_q_out; @@ -2534,14 +2514,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_dbg(ql_dbg_init, base_vha, 0x00ee, "DPC thread started successfully.\n"); - /* - * If we're not coming up in initiator mode, we might sit for - * a while without waking up the dpc thread, which leads to a - * stuck process warning. So just kick the dpc once here and - * let the kthread start (and go back to sleep in qla2x00_do_dpc). - */ - qla2xxx_wake_dpc(base_vha); - skip_dpc: list_add_tail(&base_vha->list, &ha->vp_list); base_vha->host->irq = ha->pdev->irq; @@ -2587,11 +2559,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_dbg(ql_dbg_init, base_vha, 0x00f2, "Init done and hba is online.\n"); - if (qla_ini_mode_enabled(base_vha)) - scsi_scan_host(host); - else - ql_dbg(ql_dbg_init, base_vha, 0x0122, - "skipping scsi_scan_host() for non-initiator port\n"); + scsi_scan_host(host); qla2x00_alloc_sysfs_attr(base_vha); @@ -2609,17 +2577,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) base_vha->host_no, ha->isp_ops->fw_version_str(base_vha, fw_str)); - qlt_add_target(ha, base_vha); - return 0; probe_init_failed: qla2x00_free_req_que(ha, req); - ha->req_q_map[0] = NULL; - clear_bit(0, ha->req_qid_map); qla2x00_free_rsp_que(ha, rsp); - ha->rsp_q_map[0] = NULL; - clear_bit(0, ha->rsp_qid_map); ha->max_req_queues = ha->max_rsp_queues = 0; probe_failed: @@ -2658,22 +2620,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static void -qla2x00_stop_dpc_thread(scsi_qla_host_t *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct task_struct *t = ha->dpc_thread; - - if (ha->dpc_thread == NULL) - return; - /* - * qla2xxx_wake_dpc checks for ->dpc_thread - * so we need to zero it out. - */ - ha->dpc_thread = NULL; - kthread_stop(t); -} - static void qla2x00_shutdown(struct pci_dev *pdev) { @@ -2717,18 +2663,9 @@ qla2x00_remove_one(struct pci_dev *pdev) struct qla_hw_data *ha; unsigned long flags; - /* - * If the PCI device is disabled that means that probe failed and any - * resources should be have cleaned up on probe exit. - */ - if (!atomic_read(&pdev->enable_cnt)) - return; - base_vha = pci_get_drvdata(pdev); ha = base_vha->hw; - ha->flags.host_shutting_down = 1; - mutex_lock(&ha->vport_lock); while (ha->cur_vport_count) { struct Scsi_Host *scsi_host; @@ -2782,7 +2719,6 @@ qla2x00_remove_one(struct pci_dev *pdev) ha->dpc_thread = NULL; kthread_stop(t); } - qlt_remove_target(ha, base_vha); qla2x00_free_sysfs_attr(base_vha); @@ -2834,7 +2770,17 @@ qla2x00_free_device(scsi_qla_host_t *vha) if (vha->timer_active) qla2x00_stop_timer(vha); - qla2x00_stop_dpc_thread(vha); + /* Kill the kernel thread for this host */ + if (ha->dpc_thread) { + struct task_struct *t = ha->dpc_thread; + + /* + * qla2xxx_wake_dpc checks for ->dpc_thread + * so we need to zero it out. + */ + ha->dpc_thread = NULL; + kthread_stop(t); + } qla25xx_delete_queues(vha); @@ -2896,10 +2842,8 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, spin_unlock_irqrestore(vha->host->host_lock, flags); set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); qla2xxx_wake_dpc(base_vha); - } else { + } else fc_remote_port_delete(rport); - qlt_fc_port_deleted(vha, fcport); - } } /* @@ -2915,7 +2859,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, int do_login, int defer) { if (atomic_read(&fcport->state) == FCS_ONLINE && - vha->vp_idx == fcport->vha->vp_idx) { + vha->vp_idx == fcport->vp_idx) { qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); qla2x00_schedule_rport_del(vha, fcport, defer); } @@ -2964,7 +2908,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) fc_port_t *fcport; list_for_each_entry(fcport, &vha->vp_fcports, list) { - if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx) + if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx) continue; /* @@ -2977,7 +2921,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); if (defer) qla2x00_schedule_rport_del(vha, fcport, defer); - else if (vha->vp_idx == fcport->vha->vp_idx) + else if (vha->vp_idx == fcport->vp_idx) qla2x00_schedule_rport_del(vha, fcport, defer); } } @@ -3002,13 +2946,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, if (!ha->init_cb) goto fail; - if (qlt_mem_alloc(ha) < 0) - goto fail_free_init_cb; - ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL); if (!ha->gid_list) - goto fail_free_tgt_mem; + goto fail_free_init_cb; ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); if (!ha->srb_mempool) @@ -3226,8 +3167,6 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ha->gid_list_dma); ha->gid_list = NULL; ha->gid_list_dma = 0; -fail_free_tgt_mem: - qlt_mem_free(ha); fail_free_init_cb: dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, ha->init_cb_dma); @@ -3343,8 +3282,6 @@ qla2x00_mem_free(struct qla_hw_data *ha) if (ha->ctx_mempool) mempool_destroy(ha->ctx_mempool); - qlt_mem_free(ha); - if (ha->init_cb) dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, ha->init_cb_dma); @@ -3374,10 +3311,6 @@ qla2x00_mem_free(struct qla_hw_data *ha) ha->gid_list = NULL; ha->gid_list_dma = 0; - - ha->tgt.atio_ring = NULL; - ha->tgt.atio_dma = 0; - ha->tgt.tgt_vp_map = NULL; } struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, @@ -3738,9 +3671,10 @@ qla2x00_do_dpc(void *data) ha->dpc_active = 1; - ql_dbg(ql_dbg_dpc + ql_dbg_verbose, base_vha, 0x4001, - "DPC handler waking up, dpc_flags=0x%lx.\n", - base_vha->dpc_flags); + ql_dbg(ql_dbg_dpc, base_vha, 0x4001, + "DPC handler waking up.\n"); + ql_dbg(ql_dbg_dpc, base_vha, 0x4002, + "dpc_flags=0x%lx.\n", base_vha->dpc_flags); qla2x00_do_work(base_vha); @@ -3806,16 +3740,6 @@ qla2x00_do_dpc(void *data) clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); } - if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) { - int ret; - ret = qla2x00_send_change_request(base_vha, 0x3, 0); - if (ret != QLA_SUCCESS) - ql_log(ql_log_warn, base_vha, 0x121, - "Failed to enable receiving of RSCN " - "requests: 0x%x.\n", ret); - clear_bit(SCR_PENDING, &base_vha->dpc_flags); - } - if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) { ql_dbg(ql_dbg_dpc, base_vha, 0x4009, "Quiescence mode scheduled.\n"); @@ -4533,21 +4457,6 @@ qla2x00_module_init(void) return -ENOMEM; } - /* Initialize target kmem_cache and mem_pools */ - ret = qlt_init(); - if (ret < 0) { - kmem_cache_destroy(srb_cachep); - return ret; - } else if (ret > 0) { - /* - * If initiator mode is explictly disabled by qlt_init(), - * prevent scsi_transport_fc.c:fc_scsi_scan_rport() from - * performing scsi_scan_target() during LOOP UP event. - */ - qla2xxx_transport_functions.disable_target_scan = 1; - qla2xxx_transport_vport_functions.disable_target_scan = 1; - } - /* Derive version string. */ strcpy(qla2x00_version_str, QLA2XXX_VERSION); if (ql2xextended_error_logging) @@ -4559,7 +4468,6 @@ qla2x00_module_init(void) kmem_cache_destroy(srb_cachep); ql_log(ql_log_fatal, NULL, 0x0002, "fc_attach_transport failed...Failing load!.\n"); - qlt_exit(); return -ENODEV; } @@ -4573,7 +4481,6 @@ qla2x00_module_init(void) fc_attach_transport(&qla2xxx_transport_vport_functions); if (!qla2xxx_transport_vport_template) { kmem_cache_destroy(srb_cachep); - qlt_exit(); fc_release_transport(qla2xxx_transport_template); ql_log(ql_log_fatal, NULL, 0x0004, "fc_attach_transport vport failed...Failing load!.\n"); @@ -4585,7 +4492,6 @@ qla2x00_module_init(void) ret = pci_register_driver(&qla2xxx_pci_driver); if (ret) { kmem_cache_destroy(srb_cachep); - qlt_exit(); fc_release_transport(qla2xxx_transport_template); fc_release_transport(qla2xxx_transport_vport_template); ql_log(ql_log_fatal, NULL, 0x0006, @@ -4605,7 +4511,6 @@ qla2x00_module_exit(void) pci_unregister_driver(&qla2xxx_pci_driver); qla2x00_release_firmware(); kmem_cache_destroy(srb_cachep); - qlt_exit(); if (ctx_cachep) kmem_cache_destroy(ctx_cachep); fc_release_transport(qla2xxx_transport_template); diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.c b/trunk/drivers/scsi/qla2xxx/qla_target.c deleted file mode 100644 index 04f80ebf09eb..000000000000 --- a/trunk/drivers/scsi/qla2xxx/qla_target.c +++ /dev/null @@ -1,4973 +0,0 @@ -/* - * qla_target.c SCSI LLD infrastructure for QLogic 22xx/23xx/24xx/25xx - * - * based on qla2x00t.c code: - * - * Copyright (C) 2004 - 2010 Vladislav Bolkhovitin - * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2006 - 2010 ID7 Ltd. - * - * Forward port and refactoring to modern qla2xxx and target/configfs - * - * Copyright (C) 2010-2011 Nicholas A. Bellinger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 - * of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qla_def.h" -#include "qla_target.h" - -static char *qlini_mode = QLA2XXX_INI_MODE_STR_ENABLED; -module_param(qlini_mode, charp, S_IRUGO); -MODULE_PARM_DESC(qlini_mode, - "Determines when initiator mode will be enabled. Possible values: " - "\"exclusive\" - initiator mode will be enabled on load, " - "disabled on enabling target mode and then on disabling target mode " - "enabled back; " - "\"disabled\" - initiator mode will never be enabled; " - "\"enabled\" (default) - initiator mode will always stay enabled."); - -static int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE; - -/* - * From scsi/fc/fc_fcp.h - */ -enum fcp_resp_rsp_codes { - FCP_TMF_CMPL = 0, - FCP_DATA_LEN_INVALID = 1, - FCP_CMND_FIELDS_INVALID = 2, - FCP_DATA_PARAM_MISMATCH = 3, - FCP_TMF_REJECTED = 4, - FCP_TMF_FAILED = 5, - FCP_TMF_INVALID_LUN = 9, -}; - -/* - * fc_pri_ta from scsi/fc/fc_fcp.h - */ -#define FCP_PTA_SIMPLE 0 /* simple task attribute */ -#define FCP_PTA_HEADQ 1 /* head of queue task attribute */ -#define FCP_PTA_ORDERED 2 /* ordered task attribute */ -#define FCP_PTA_ACA 4 /* auto. contigent allegiance */ -#define FCP_PTA_MASK 7 /* mask for task attribute field */ -#define FCP_PRI_SHIFT 3 /* priority field starts in bit 3 */ -#define FCP_PRI_RESVD_MASK 0x80 /* reserved bits in priority field */ - -/* - * This driver calls qla2x00_alloc_iocbs() and qla2x00_issue_marker(), which - * must be called under HW lock and could unlock/lock it inside. - * It isn't an issue, since in the current implementation on the time when - * those functions are called: - * - * - Either context is IRQ and only IRQ handler can modify HW data, - * including rings related fields, - * - * - Or access to target mode variables from struct qla_tgt doesn't - * cross those functions boundaries, except tgt_stop, which - * additionally protected by irq_cmd_count. - */ -/* Predefs for callbacks handed to qla2xxx LLD */ -static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, - struct atio_from_isp *pkt); -static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); -static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, - int fn, void *iocb, int flags); -static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd - *cmd, struct atio_from_isp *atio, int ha_locked); -static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha, - struct qla_tgt_srr_imm *imm, int ha_lock); -/* - * Global Variables - */ -static struct kmem_cache *qla_tgt_cmd_cachep; -static struct kmem_cache *qla_tgt_mgmt_cmd_cachep; -static mempool_t *qla_tgt_mgmt_cmd_mempool; -static struct workqueue_struct *qla_tgt_wq; -static DEFINE_MUTEX(qla_tgt_mutex); -static LIST_HEAD(qla_tgt_glist); - -/* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */ -static struct qla_tgt_sess *qlt_find_sess_by_port_name( - struct qla_tgt *tgt, - const uint8_t *port_name) -{ - struct qla_tgt_sess *sess; - - list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { - if (!memcmp(sess->port_name, port_name, WWN_SIZE)) - return sess; - } - - return NULL; -} - -/* Might release hw lock, then reaquire!! */ -static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked) -{ - /* Send marker if required */ - if (unlikely(vha->marker_needed != 0)) { - int rc = qla2x00_issue_marker(vha, vha_locked); - if (rc != QLA_SUCCESS) { - ql_dbg(ql_dbg_tgt, vha, 0xe03d, - "qla_target(%d): issue_marker() failed\n", - vha->vp_idx); - } - return rc; - } - return QLA_SUCCESS; -} - -static inline -struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, - uint8_t *d_id) -{ - struct qla_hw_data *ha = vha->hw; - uint8_t vp_idx; - - if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0])) - return NULL; - - if (vha->d_id.b.al_pa == d_id[2]) - return vha; - - BUG_ON(ha->tgt.tgt_vp_map == NULL); - vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx; - if (likely(test_bit(vp_idx, ha->vp_idx_map))) - return ha->tgt.tgt_vp_map[vp_idx].vha; - - return NULL; -} - -static inline -struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha, - uint16_t vp_idx) -{ - struct qla_hw_data *ha = vha->hw; - - if (vha->vp_idx == vp_idx) - return vha; - - BUG_ON(ha->tgt.tgt_vp_map == NULL); - if (likely(test_bit(vp_idx, ha->vp_idx_map))) - return ha->tgt.tgt_vp_map[vp_idx].vha; - - return NULL; -} - -void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, - struct atio_from_isp *atio) -{ - switch (atio->u.raw.entry_type) { - case ATIO_TYPE7: - { - struct scsi_qla_host *host = qlt_find_host_by_d_id(vha, - atio->u.isp24.fcp_hdr.d_id); - if (unlikely(NULL == host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe03e, - "qla_target(%d): Received ATIO_TYPE7 " - "with unknown d_id %x:%x:%x\n", vha->vp_idx, - atio->u.isp24.fcp_hdr.d_id[0], - atio->u.isp24.fcp_hdr.d_id[1], - atio->u.isp24.fcp_hdr.d_id[2]); - break; - } - qlt_24xx_atio_pkt(host, atio); - break; - } - - case IMMED_NOTIFY_TYPE: - { - struct scsi_qla_host *host = vha; - struct imm_ntfy_from_isp *entry = - (struct imm_ntfy_from_isp *)atio; - - if ((entry->u.isp24.vp_index != 0xFF) && - (entry->u.isp24.nport_handle != 0xFFFF)) { - host = qlt_find_host_by_vp_idx(vha, - entry->u.isp24.vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe03f, - "qla_target(%d): Received " - "ATIO (IMMED_NOTIFY_TYPE) " - "with unknown vp_index %d\n", - vha->vp_idx, entry->u.isp24.vp_index); - break; - } - } - qlt_24xx_atio_pkt(host, atio); - break; - } - - default: - ql_dbg(ql_dbg_tgt, vha, 0xe040, - "qla_target(%d): Received unknown ATIO atio " - "type %x\n", vha->vp_idx, atio->u.raw.entry_type); - break; - } - - return; -} - -void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) -{ - switch (pkt->entry_type) { - case CTIO_TYPE7: - { - struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; - struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, - entry->vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe041, - "qla_target(%d): Response pkt (CTIO_TYPE7) " - "received, with unknown vp_index %d\n", - vha->vp_idx, entry->vp_index); - break; - } - qlt_response_pkt(host, pkt); - break; - } - - case IMMED_NOTIFY_TYPE: - { - struct scsi_qla_host *host = vha; - struct imm_ntfy_from_isp *entry = - (struct imm_ntfy_from_isp *)pkt; - - host = qlt_find_host_by_vp_idx(vha, entry->u.isp24.vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe042, - "qla_target(%d): Response pkt (IMMED_NOTIFY_TYPE) " - "received, with unknown vp_index %d\n", - vha->vp_idx, entry->u.isp24.vp_index); - break; - } - qlt_response_pkt(host, pkt); - break; - } - - case NOTIFY_ACK_TYPE: - { - struct scsi_qla_host *host = vha; - struct nack_to_isp *entry = (struct nack_to_isp *)pkt; - - if (0xFF != entry->u.isp24.vp_index) { - host = qlt_find_host_by_vp_idx(vha, - entry->u.isp24.vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe043, - "qla_target(%d): Response " - "pkt (NOTIFY_ACK_TYPE) " - "received, with unknown " - "vp_index %d\n", vha->vp_idx, - entry->u.isp24.vp_index); - break; - } - } - qlt_response_pkt(host, pkt); - break; - } - - case ABTS_RECV_24XX: - { - struct abts_recv_from_24xx *entry = - (struct abts_recv_from_24xx *)pkt; - struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, - entry->vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe044, - "qla_target(%d): Response pkt " - "(ABTS_RECV_24XX) received, with unknown " - "vp_index %d\n", vha->vp_idx, entry->vp_index); - break; - } - qlt_response_pkt(host, pkt); - break; - } - - case ABTS_RESP_24XX: - { - struct abts_resp_to_24xx *entry = - (struct abts_resp_to_24xx *)pkt; - struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, - entry->vp_index); - if (unlikely(!host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe045, - "qla_target(%d): Response pkt " - "(ABTS_RECV_24XX) received, with unknown " - "vp_index %d\n", vha->vp_idx, entry->vp_index); - break; - } - qlt_response_pkt(host, pkt); - break; - } - - default: - qlt_response_pkt(vha, pkt); - break; - } - -} - -static void qlt_free_session_done(struct work_struct *work) -{ - struct qla_tgt_sess *sess = container_of(work, struct qla_tgt_sess, - free_work); - struct qla_tgt *tgt = sess->tgt; - struct scsi_qla_host *vha = sess->vha; - struct qla_hw_data *ha = vha->hw; - - BUG_ON(!tgt); - /* - * Release the target session for FC Nexus from fabric module code. - */ - if (sess->se_sess != NULL) - ha->tgt.tgt_ops->free_session(sess); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, - "Unregistration of sess %p finished\n", sess); - - kfree(sess); - /* - * We need to protect against race, when tgt is freed before or - * inside wake_up() - */ - tgt->sess_count--; - if (tgt->sess_count == 0) - wake_up_all(&tgt->waitQ); -} - -/* ha->hardware_lock supposed to be held on entry */ -void qlt_unreg_sess(struct qla_tgt_sess *sess) -{ - struct scsi_qla_host *vha = sess->vha; - - vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); - - list_del(&sess->sess_list_entry); - if (sess->deleted) - list_del(&sess->del_list_entry); - - INIT_WORK(&sess->free_work, qlt_free_session_done); - schedule_work(&sess->free_work); -} -EXPORT_SYMBOL(qlt_unreg_sess); - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess = NULL; - uint32_t unpacked_lun, lun = 0; - uint16_t loop_id; - int res = 0; - struct imm_ntfy_from_isp *n = (struct imm_ntfy_from_isp *)iocb; - struct atio_from_isp *a = (struct atio_from_isp *)iocb; - - loop_id = le16_to_cpu(n->u.isp24.nport_handle); - if (loop_id == 0xFFFF) { -#if 0 /* FIXME: Re-enable Global event handling.. */ - /* Global event */ - atomic_inc(&ha->tgt.qla_tgt->tgt_global_resets_count); - qlt_clear_tgt_db(ha->tgt.qla_tgt, 1); - if (!list_empty(&ha->tgt.qla_tgt->sess_list)) { - sess = list_entry(ha->tgt.qla_tgt->sess_list.next, - typeof(*sess), sess_list_entry); - switch (mcmd) { - case QLA_TGT_NEXUS_LOSS_SESS: - mcmd = QLA_TGT_NEXUS_LOSS; - break; - case QLA_TGT_ABORT_ALL_SESS: - mcmd = QLA_TGT_ABORT_ALL; - break; - case QLA_TGT_NEXUS_LOSS: - case QLA_TGT_ABORT_ALL: - break; - default: - ql_dbg(ql_dbg_tgt, vha, 0xe046, - "qla_target(%d): Not allowed " - "command %x in %s", vha->vp_idx, - mcmd, __func__); - sess = NULL; - break; - } - } else - sess = NULL; -#endif - } else { - sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id); - } - - ql_dbg(ql_dbg_tgt, vha, 0xe000, - "Using sess for qla_tgt_reset: %p\n", sess); - if (!sess) { - res = -ESRCH; - return res; - } - - ql_dbg(ql_dbg_tgt, vha, 0xe047, - "scsi(%ld): resetting (session %p from port " - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, " - "mcmd %x, loop_id %d)\n", vha->host_no, sess, - sess->port_name[0], sess->port_name[1], - sess->port_name[2], sess->port_name[3], - sess->port_name[4], sess->port_name[5], - sess->port_name[6], sess->port_name[7], - mcmd, loop_id); - - lun = a->u.isp24.fcp_cmnd.lun; - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); - - return qlt_issue_task_mgmt(sess, unpacked_lun, mcmd, - iocb, QLA24XX_MGMT_SEND_NACK); -} - -/* ha->hardware_lock supposed to be held on entry */ -static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess, - bool immediate) -{ - struct qla_tgt *tgt = sess->tgt; - uint32_t dev_loss_tmo = tgt->ha->port_down_retry_count + 5; - - if (sess->deleted) - return; - - ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, - "Scheduling sess %p for deletion\n", sess); - list_add_tail(&sess->del_list_entry, &tgt->del_sess_list); - sess->deleted = 1; - - if (immediate) - dev_loss_tmo = 0; - - sess->expires = jiffies + dev_loss_tmo * HZ; - - ql_dbg(ql_dbg_tgt, sess->vha, 0xe048, - "qla_target(%d): session for port %02x:%02x:%02x:" - "%02x:%02x:%02x:%02x:%02x (loop ID %d) scheduled for " - "deletion in %u secs (expires: %lu) immed: %d\n", - sess->vha->vp_idx, - sess->port_name[0], sess->port_name[1], - sess->port_name[2], sess->port_name[3], - sess->port_name[4], sess->port_name[5], - sess->port_name[6], sess->port_name[7], - sess->loop_id, dev_loss_tmo, sess->expires, immediate); - - if (immediate) - schedule_delayed_work(&tgt->sess_del_work, 0); - else - schedule_delayed_work(&tgt->sess_del_work, - jiffies - sess->expires); -} - -/* ha->hardware_lock supposed to be held on entry */ -static void qlt_clear_tgt_db(struct qla_tgt *tgt, bool local_only) -{ - struct qla_tgt_sess *sess; - - list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) - qlt_schedule_sess_for_deletion(sess, true); - - /* At this point tgt could be already dead */ -} - -static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, - uint16_t *loop_id) -{ - struct qla_hw_data *ha = vha->hw; - dma_addr_t gid_list_dma; - struct gid_list_info *gid_list; - char *id_iter; - int res, rc, i; - uint16_t entries; - - gid_list = dma_alloc_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), - &gid_list_dma, GFP_KERNEL); - if (!gid_list) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf044, - "qla_target(%d): DMA Alloc failed of %u\n", - vha->vp_idx, qla2x00_gid_list_size(ha)); - return -ENOMEM; - } - - /* Get list of logged in devices */ - rc = qla2x00_get_id_list(vha, gid_list, gid_list_dma, &entries); - if (rc != QLA_SUCCESS) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, - "qla_target(%d): get_id_list() failed: %x\n", - vha->vp_idx, rc); - res = -1; - goto out_free_id_list; - } - - id_iter = (char *)gid_list; - res = -1; - for (i = 0; i < entries; i++) { - struct gid_list_info *gid = (struct gid_list_info *)id_iter; - if ((gid->al_pa == s_id[2]) && - (gid->area == s_id[1]) && - (gid->domain == s_id[0])) { - *loop_id = le16_to_cpu(gid->loop_id); - res = 0; - break; - } - id_iter += ha->gid_list_info_size; - } - -out_free_id_list: - dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), - gid_list, gid_list_dma); - return res; -} - -static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, - struct qla_tgt_sess *sess) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_port_24xx_data *pmap24; - bool res, found = false; - int rc, i; - uint16_t loop_id = 0xFFFF; /* to eliminate compiler's warning */ - uint16_t entries; - void *pmap; - int pmap_len; - fc_port_t *fcport; - int global_resets; - -retry: - global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); - - rc = qla2x00_get_node_name_list(vha, &pmap, &pmap_len); - if (rc != QLA_SUCCESS) { - res = false; - goto out; - } - - pmap24 = pmap; - entries = pmap_len/sizeof(*pmap24); - - for (i = 0; i < entries; ++i) { - if (!memcmp(sess->port_name, pmap24[i].port_name, WWN_SIZE)) { - loop_id = le16_to_cpu(pmap24[i].loop_id); - found = true; - break; - } - } - - kfree(pmap); - - if (!found) { - res = false; - goto out; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf046, - "qlt_check_fcport_exist(): loop_id %d", loop_id); - - fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); - if (fcport == NULL) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf047, - "qla_target(%d): Allocation of tmp FC port failed", - vha->vp_idx); - res = false; - goto out; - } - - fcport->loop_id = loop_id; - - rc = qla2x00_get_port_database(vha, fcport, 0); - if (rc != QLA_SUCCESS) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf048, - "qla_target(%d): Failed to retrieve fcport " - "information -- get_port_database() returned %x " - "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); - res = false; - goto out_free_fcport; - } - - if (global_resets != - atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002, - "qla_target(%d): global reset during session discovery" - " (counter was %d, new %d), retrying", - vha->vp_idx, global_resets, - atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); - goto retry; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, - "Updating sess %p s_id %x:%x:%x, loop_id %d) to d_id %x:%x:%x, " - "loop_id %d", sess, sess->s_id.b.domain, sess->s_id.b.al_pa, - sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, - fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); - - sess->s_id = fcport->d_id; - sess->loop_id = fcport->loop_id; - sess->conf_compl_supported = !!(fcport->flags & - FCF_CONF_COMP_SUPPORTED); - - res = true; - -out_free_fcport: - kfree(fcport); - -out: - return res; -} - -/* ha->hardware_lock supposed to be held on entry */ -static void qlt_undelete_sess(struct qla_tgt_sess *sess) -{ - BUG_ON(!sess->deleted); - - list_del(&sess->del_list_entry); - sess->deleted = 0; -} - -static void qlt_del_sess_work_fn(struct delayed_work *work) -{ - struct qla_tgt *tgt = container_of(work, struct qla_tgt, - sess_del_work); - struct scsi_qla_host *vha = tgt->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess; - unsigned long flags; - - spin_lock_irqsave(&ha->hardware_lock, flags); - while (!list_empty(&tgt->del_sess_list)) { - sess = list_entry(tgt->del_sess_list.next, typeof(*sess), - del_list_entry); - if (time_after_eq(jiffies, sess->expires)) { - bool cancel; - - qlt_undelete_sess(sess); - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - cancel = qlt_check_fcport_exist(vha, sess); - - if (cancel) { - if (sess->deleted) { - /* - * sess was again deleted while we were - * discovering it - */ - spin_lock_irqsave(&ha->hardware_lock, - flags); - continue; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf049, - "qla_target(%d): cancel deletion of " - "session for port %02x:%02x:%02x:%02x:%02x:" - "%02x:%02x:%02x (loop ID %d), because " - " it isn't deleted by firmware", - vha->vp_idx, sess->port_name[0], - sess->port_name[1], sess->port_name[2], - sess->port_name[3], sess->port_name[4], - sess->port_name[5], sess->port_name[6], - sess->port_name[7], sess->loop_id); - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, - "Timeout: sess %p about to be deleted\n", - sess); - ha->tgt.tgt_ops->shutdown_sess(sess); - ha->tgt.tgt_ops->put_sess(sess); - } - - spin_lock_irqsave(&ha->hardware_lock, flags); - } else { - schedule_delayed_work(&tgt->sess_del_work, - jiffies - sess->expires); - break; - } - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -/* - * Adds an extra ref to allow to drop hw lock after adding sess to the list. - * Caller must put it. - */ -static struct qla_tgt_sess *qlt_create_sess( - struct scsi_qla_host *vha, - fc_port_t *fcport, - bool local) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess; - unsigned long flags; - unsigned char be_sid[3]; - - /* Check to avoid double sessions */ - spin_lock_irqsave(&ha->hardware_lock, flags); - list_for_each_entry(sess, &ha->tgt.qla_tgt->sess_list, - sess_list_entry) { - if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005, - "Double sess %p found (s_id %x:%x:%x, " - "loop_id %d), updating to d_id %x:%x:%x, " - "loop_id %d", sess, sess->s_id.b.domain, - sess->s_id.b.al_pa, sess->s_id.b.area, - sess->loop_id, fcport->d_id.b.domain, - fcport->d_id.b.al_pa, fcport->d_id.b.area, - fcport->loop_id); - - if (sess->deleted) - qlt_undelete_sess(sess); - - kref_get(&sess->se_sess->sess_kref); - sess->s_id = fcport->d_id; - sess->loop_id = fcport->loop_id; - sess->conf_compl_supported = !!(fcport->flags & - FCF_CONF_COMP_SUPPORTED); - if (sess->local && !local) - sess->local = 0; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return sess; - } - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - sess = kzalloc(sizeof(*sess), GFP_KERNEL); - if (!sess) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04a, - "qla_target(%u): session allocation failed, " - "all commands from port %02x:%02x:%02x:%02x:" - "%02x:%02x:%02x:%02x will be refused", vha->vp_idx, - fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7]); - - return NULL; - } - sess->tgt = ha->tgt.qla_tgt; - sess->vha = vha; - sess->s_id = fcport->d_id; - sess->loop_id = fcport->loop_id; - sess->local = local; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006, - "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n", - sess, ha->tgt.qla_tgt); - - be_sid[0] = sess->s_id.b.domain; - be_sid[1] = sess->s_id.b.area; - be_sid[2] = sess->s_id.b.al_pa; - /* - * Determine if this fc_port->port_name is allowed to access - * target mode using explict NodeACLs+MappedLUNs, or using - * TPG demo mode. If this is successful a target mode FC nexus - * is created. - */ - if (ha->tgt.tgt_ops->check_initiator_node_acl(vha, - &fcport->port_name[0], sess, &be_sid[0], fcport->loop_id) < 0) { - kfree(sess); - return NULL; - } - /* - * Take an extra reference to ->sess_kref here to handle qla_tgt_sess - * access across ->hardware_lock reaquire. - */ - kref_get(&sess->se_sess->sess_kref); - - sess->conf_compl_supported = !!(fcport->flags & - FCF_CONF_COMP_SUPPORTED); - BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); - memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); - - spin_lock_irqsave(&ha->hardware_lock, flags); - list_add_tail(&sess->sess_list_entry, &ha->tgt.qla_tgt->sess_list); - ha->tgt.qla_tgt->sess_count++; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b, - "qla_target(%d): %ssession for wwn %02x:%02x:%02x:%02x:" - "%02x:%02x:%02x:%02x (loop_id %d, s_id %x:%x:%x, confirmed" - " completion %ssupported) added\n", - vha->vp_idx, local ? "local " : "", fcport->port_name[0], - fcport->port_name[1], fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], fcport->port_name[6], - fcport->port_name[7], fcport->loop_id, sess->s_id.b.domain, - sess->s_id.b.area, sess->s_id.b.al_pa, sess->conf_compl_supported ? - "" : "not "); - - return sess; -} - -/* - * Called from drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() - */ -void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_sess *sess; - unsigned long flags; - - if (!vha->hw->tgt.tgt_ops) - return; - - if (!tgt || (fcport->port_type != FCT_INITIATOR)) - return; - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (tgt->tgt_stop) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - return; - } - sess = qlt_find_sess_by_port_name(tgt, fcport->port_name); - if (!sess) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - mutex_lock(&ha->tgt.tgt_mutex); - sess = qlt_create_sess(vha, fcport, false); - mutex_unlock(&ha->tgt.tgt_mutex); - - spin_lock_irqsave(&ha->hardware_lock, flags); - } else { - kref_get(&sess->se_sess->sess_kref); - - if (sess->deleted) { - qlt_undelete_sess(sess); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04c, - "qla_target(%u): %ssession for port %02x:" - "%02x:%02x:%02x:%02x:%02x:%02x:%02x (loop ID %d) " - "reappeared\n", vha->vp_idx, sess->local ? "local " - : "", sess->port_name[0], sess->port_name[1], - sess->port_name[2], sess->port_name[3], - sess->port_name[4], sess->port_name[5], - sess->port_name[6], sess->port_name[7], - sess->loop_id); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, - "Reappeared sess %p\n", sess); - } - sess->s_id = fcport->d_id; - sess->loop_id = fcport->loop_id; - sess->conf_compl_supported = !!(fcport->flags & - FCF_CONF_COMP_SUPPORTED); - } - - if (sess && sess->local) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04d, - "qla_target(%u): local session for " - "port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " - "(loop ID %d) became global\n", vha->vp_idx, - fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7], - sess->loop_id); - sess->local = 0; - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - ha->tgt.tgt_ops->put_sess(sess); -} - -void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_sess *sess; - unsigned long flags; - - if (!vha->hw->tgt.tgt_ops) - return; - - if (!tgt || (fcport->port_type != FCT_INITIATOR)) - return; - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (tgt->tgt_stop) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - return; - } - sess = qlt_find_sess_by_port_name(tgt, fcport->port_name); - if (!sess) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - return; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); - - sess->local = 1; - qlt_schedule_sess_for_deletion(sess, false); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -static inline int test_tgt_sess_count(struct qla_tgt *tgt) -{ - struct qla_hw_data *ha = tgt->ha; - unsigned long flags; - int res; - /* - * We need to protect against race, when tgt is freed before or - * inside wake_up() - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - ql_dbg(ql_dbg_tgt, tgt->vha, 0xe002, - "tgt %p, empty(sess_list)=%d sess_count=%d\n", - tgt, list_empty(&tgt->sess_list), tgt->sess_count); - res = (tgt->sess_count == 0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return res; -} - -/* Called by tcm_qla2xxx configfs code */ -void qlt_stop_phase1(struct qla_tgt *tgt) -{ - struct scsi_qla_host *vha = tgt->vha; - struct qla_hw_data *ha = tgt->ha; - unsigned long flags; - - if (tgt->tgt_stop || tgt->tgt_stopped) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, - "Already in tgt->tgt_stop or tgt_stopped state\n"); - dump_stack(); - return; - } - - ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", - vha->host_no, vha); - /* - * Mutex needed to sync with qla_tgt_fc_port_[added,deleted]. - * Lock is needed, because we still can get an incoming packet. - */ - mutex_lock(&ha->tgt.tgt_mutex); - spin_lock_irqsave(&ha->hardware_lock, flags); - tgt->tgt_stop = 1; - qlt_clear_tgt_db(tgt, true); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - mutex_unlock(&ha->tgt.tgt_mutex); - - flush_delayed_work_sync(&tgt->sess_del_work); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf009, - "Waiting for sess works (tgt %p)", tgt); - spin_lock_irqsave(&tgt->sess_work_lock, flags); - while (!list_empty(&tgt->sess_works_list)) { - spin_unlock_irqrestore(&tgt->sess_work_lock, flags); - flush_scheduled_work(); - spin_lock_irqsave(&tgt->sess_work_lock, flags); - } - spin_unlock_irqrestore(&tgt->sess_work_lock, flags); - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00a, - "Waiting for tgt %p: list_empty(sess_list)=%d " - "sess_count=%d\n", tgt, list_empty(&tgt->sess_list), - tgt->sess_count); - - wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); - - /* Big hammer */ - if (!ha->flags.host_shutting_down && qla_tgt_mode_enabled(vha)) - qlt_disable_vha(vha); - - /* Wait for sessions to clear out (just in case) */ - wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); -} -EXPORT_SYMBOL(qlt_stop_phase1); - -/* Called by tcm_qla2xxx configfs code */ -void qlt_stop_phase2(struct qla_tgt *tgt) -{ - struct qla_hw_data *ha = tgt->ha; - unsigned long flags; - - if (tgt->tgt_stopped) { - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf04f, - "Already in tgt->tgt_stopped state\n"); - dump_stack(); - return; - } - - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00b, - "Waiting for %d IRQ commands to complete (tgt %p)", - tgt->irq_cmd_count, tgt); - - mutex_lock(&ha->tgt.tgt_mutex); - spin_lock_irqsave(&ha->hardware_lock, flags); - while (tgt->irq_cmd_count != 0) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - udelay(2); - spin_lock_irqsave(&ha->hardware_lock, flags); - } - tgt->tgt_stop = 0; - tgt->tgt_stopped = 1; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - mutex_unlock(&ha->tgt.tgt_mutex); - - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00c, "Stop of tgt %p finished", - tgt); -} -EXPORT_SYMBOL(qlt_stop_phase2); - -/* Called from qlt_remove_target() -> qla2x00_remove_one() */ -void qlt_release(struct qla_tgt *tgt) -{ - struct qla_hw_data *ha = tgt->ha; - - if ((ha->tgt.qla_tgt != NULL) && !tgt->tgt_stopped) - qlt_stop_phase2(tgt); - - ha->tgt.qla_tgt = NULL; - - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00d, - "Release of tgt %p finished\n", tgt); - - kfree(tgt); -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_sched_sess_work(struct qla_tgt *tgt, int type, - const void *param, unsigned int param_size) -{ - struct qla_tgt_sess_work_param *prm; - unsigned long flags; - - prm = kzalloc(sizeof(*prm), GFP_ATOMIC); - if (!prm) { - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf050, - "qla_target(%d): Unable to create session " - "work, command will be refused", 0); - return -ENOMEM; - } - - ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00e, - "Scheduling work (type %d, prm %p)" - " to find session for param %p (size %d, tgt %p)\n", - type, prm, param, param_size, tgt); - - prm->type = type; - memcpy(&prm->tm_iocb, param, param_size); - - spin_lock_irqsave(&tgt->sess_work_lock, flags); - list_add_tail(&prm->sess_works_list_entry, &tgt->sess_works_list); - spin_unlock_irqrestore(&tgt->sess_work_lock, flags); - - schedule_work(&tgt->sess_work); - - return 0; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_send_notify_ack(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *ntfy, - uint32_t add_flags, uint16_t resp_code, int resp_code_valid, - uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan) -{ - struct qla_hw_data *ha = vha->hw; - request_t *pkt; - struct nack_to_isp *nack; - - ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); - - /* Send marker if required */ - if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) - return; - - pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); - if (!pkt) { - ql_dbg(ql_dbg_tgt, vha, 0xe049, - "qla_target(%d): %s failed: unable to allocate " - "request packet\n", vha->vp_idx, __func__); - return; - } - - if (ha->tgt.qla_tgt != NULL) - ha->tgt.qla_tgt->notify_ack_expected++; - - pkt->entry_type = NOTIFY_ACK_TYPE; - pkt->entry_count = 1; - - nack = (struct nack_to_isp *)pkt; - nack->ox_id = ntfy->ox_id; - - nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle; - if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) { - nack->u.isp24.flags = ntfy->u.isp24.flags & - __constant_cpu_to_le32(NOTIFY24XX_FLAGS_PUREX_IOCB); - } - nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id; - nack->u.isp24.status = ntfy->u.isp24.status; - nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode; - nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address; - nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs; - nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui; - nack->u.isp24.srr_flags = cpu_to_le16(srr_flags); - nack->u.isp24.srr_reject_code = srr_reject_code; - nack->u.isp24.srr_reject_code_expl = srr_explan; - nack->u.isp24.vp_index = ntfy->u.isp24.vp_index; - - ql_dbg(ql_dbg_tgt, vha, 0xe005, - "qla_target(%d): Sending 24xx Notify Ack %d\n", - vha->vp_idx, nack->u.isp24.status); - - qla2x00_start_iocbs(vha, vha->req); -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, - struct abts_recv_from_24xx *abts, uint32_t status, - bool ids_reversed) -{ - struct qla_hw_data *ha = vha->hw; - struct abts_resp_to_24xx *resp; - uint32_t f_ctl; - uint8_t *p; - - ql_dbg(ql_dbg_tgt, vha, 0xe006, - "Sending task mgmt ABTS response (ha=%p, atio=%p, status=%x\n", - ha, abts, status); - - /* Send marker if required */ - if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) - return; - - resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); - if (!resp) { - ql_dbg(ql_dbg_tgt, vha, 0xe04a, - "qla_target(%d): %s failed: unable to allocate " - "request packet", vha->vp_idx, __func__); - return; - } - - resp->entry_type = ABTS_RESP_24XX; - resp->entry_count = 1; - resp->nport_handle = abts->nport_handle; - resp->vp_index = vha->vp_idx; - resp->sof_type = abts->sof_type; - resp->exchange_address = abts->exchange_address; - resp->fcp_hdr_le = abts->fcp_hdr_le; - f_ctl = __constant_cpu_to_le32(F_CTL_EXCH_CONTEXT_RESP | - F_CTL_LAST_SEQ | F_CTL_END_SEQ | - F_CTL_SEQ_INITIATIVE); - p = (uint8_t *)&f_ctl; - resp->fcp_hdr_le.f_ctl[0] = *p++; - resp->fcp_hdr_le.f_ctl[1] = *p++; - resp->fcp_hdr_le.f_ctl[2] = *p; - if (ids_reversed) { - resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.d_id[0]; - resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.d_id[1]; - resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.d_id[2]; - resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.s_id[0]; - resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.s_id[1]; - resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.s_id[2]; - } else { - resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0]; - resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1]; - resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2]; - resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0]; - resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1]; - resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2]; - } - resp->exchange_addr_to_abort = abts->exchange_addr_to_abort; - if (status == FCP_TMF_CMPL) { - resp->fcp_hdr_le.r_ctl = R_CTL_BASIC_LINK_SERV | R_CTL_B_ACC; - resp->payload.ba_acct.seq_id_valid = SEQ_ID_INVALID; - resp->payload.ba_acct.low_seq_cnt = 0x0000; - resp->payload.ba_acct.high_seq_cnt = 0xFFFF; - resp->payload.ba_acct.ox_id = abts->fcp_hdr_le.ox_id; - resp->payload.ba_acct.rx_id = abts->fcp_hdr_le.rx_id; - } else { - resp->fcp_hdr_le.r_ctl = R_CTL_BASIC_LINK_SERV | R_CTL_B_RJT; - resp->payload.ba_rjt.reason_code = - BA_RJT_REASON_CODE_UNABLE_TO_PERFORM; - /* Other bytes are zero */ - } - - ha->tgt.qla_tgt->abts_resp_expected++; - - qla2x00_start_iocbs(vha, vha->req); -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, - struct abts_resp_from_24xx_fw *entry) -{ - struct ctio7_to_24xx *ctio; - - ql_dbg(ql_dbg_tgt, vha, 0xe007, - "Sending retry TERM EXCH CTIO7 (ha=%p)\n", vha->hw); - /* Send marker if required */ - if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) - return; - - ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); - if (ctio == NULL) { - ql_dbg(ql_dbg_tgt, vha, 0xe04b, - "qla_target(%d): %s failed: unable to allocate " - "request packet\n", vha->vp_idx, __func__); - return; - } - - /* - * We've got on entrance firmware's response on by us generated - * ABTS response. So, in it ID fields are reversed. - */ - - ctio->entry_type = CTIO_TYPE7; - ctio->entry_count = 1; - ctio->nport_handle = entry->nport_handle; - ctio->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; - ctio->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); - ctio->vp_index = vha->vp_idx; - ctio->initiator_id[0] = entry->fcp_hdr_le.d_id[0]; - ctio->initiator_id[1] = entry->fcp_hdr_le.d_id[1]; - ctio->initiator_id[2] = entry->fcp_hdr_le.d_id[2]; - ctio->exchange_addr = entry->exchange_addr_to_abort; - ctio->u.status1.flags = - __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | - CTIO7_FLAGS_TERMINATE); - ctio->u.status1.ox_id = entry->fcp_hdr_le.ox_id; - - qla2x00_start_iocbs(vha, vha->req); - - qlt_24xx_send_abts_resp(vha, (struct abts_recv_from_24xx *)entry, - FCP_TMF_CMPL, true); -} - -/* ha->hardware_lock supposed to be held on entry */ -static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, - struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_mgmt_cmd *mcmd; - int rc; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f, - "qla_target(%d): task abort (tag=%d)\n", - vha->vp_idx, abts->exchange_addr_to_abort); - - mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); - if (mcmd == NULL) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf051, - "qla_target(%d): %s: Allocation of ABORT cmd failed", - vha->vp_idx, __func__); - return -ENOMEM; - } - memset(mcmd, 0, sizeof(*mcmd)); - - mcmd->sess = sess; - memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts)); - - rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, TMR_ABORT_TASK, - abts->exchange_addr_to_abort); - if (rc != 0) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052, - "qla_target(%d): tgt_ops->handle_tmr()" - " failed: %d", vha->vp_idx, rc); - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); - return -EFAULT; - } - - return 0; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, - struct abts_recv_from_24xx *abts) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess; - uint32_t tag = abts->exchange_addr_to_abort; - uint8_t s_id[3]; - int rc; - - if (le32_to_cpu(abts->fcp_hdr_le.parameter) & ABTS_PARAM_ABORT_SEQ) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053, - "qla_target(%d): ABTS: Abort Sequence not " - "supported\n", vha->vp_idx); - qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); - return; - } - - if (tag == ATIO_EXCHANGE_ADDRESS_UNKNOWN) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf010, - "qla_target(%d): ABTS: Unknown Exchange " - "Address received\n", vha->vp_idx); - qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); - return; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf011, - "qla_target(%d): task abort (s_id=%x:%x:%x, " - "tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id[2], - abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[0], tag, - le32_to_cpu(abts->fcp_hdr_le.parameter)); - - s_id[0] = abts->fcp_hdr_le.s_id[2]; - s_id[1] = abts->fcp_hdr_le.s_id[1]; - s_id[2] = abts->fcp_hdr_le.s_id[0]; - - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); - if (!sess) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, - "qla_target(%d): task abort for non-existant session\n", - vha->vp_idx); - rc = qlt_sched_sess_work(ha->tgt.qla_tgt, - QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts)); - if (rc != 0) { - qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, - false); - } - return; - } - - rc = __qlt_24xx_handle_abts(vha, abts, sess); - if (rc != 0) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054, - "qla_target(%d): __qlt_24xx_handle_abts() failed: %d\n", - vha->vp_idx, rc); - qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); - return; - } -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, - struct qla_tgt_mgmt_cmd *mcmd, uint32_t resp_code) -{ - struct atio_from_isp *atio = &mcmd->orig_iocb.atio; - struct ctio7_to_24xx *ctio; - - ql_dbg(ql_dbg_tgt, ha, 0xe008, - "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", - ha, atio, resp_code); - - /* Send marker if required */ - if (qlt_issue_marker(ha, 1) != QLA_SUCCESS) - return; - - ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(ha, NULL); - if (ctio == NULL) { - ql_dbg(ql_dbg_tgt, ha, 0xe04c, - "qla_target(%d): %s failed: unable to allocate " - "request packet\n", ha->vp_idx, __func__); - return; - } - - ctio->entry_type = CTIO_TYPE7; - ctio->entry_count = 1; - ctio->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; - ctio->nport_handle = mcmd->sess->loop_id; - ctio->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); - ctio->vp_index = ha->vp_idx; - ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; - ctio->exchange_addr = atio->u.isp24.exchange_addr; - ctio->u.status1.flags = (atio->u.isp24.attr << 9) | - __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | - CTIO7_FLAGS_SEND_STATUS); - ctio->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); - ctio->u.status1.scsi_status = - __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); - ctio->u.status1.response_len = __constant_cpu_to_le16(8); - ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code); - - qla2x00_start_iocbs(ha, ha->req); -} - -void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) -{ - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); -} -EXPORT_SYMBOL(qlt_free_mcmd); - -/* callback from target fabric module code */ -void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) -{ - struct scsi_qla_host *vha = mcmd->sess->vha; - struct qla_hw_data *ha = vha->hw; - unsigned long flags; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf013, - "TM response mcmd (%p) status %#x state %#x", - mcmd, mcmd->fc_tm_rsp, mcmd->flags); - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (mcmd->flags == QLA24XX_MGMT_SEND_NACK) - qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy, - 0, 0, 0, 0, 0, 0); - else { - if (mcmd->se_cmd.se_tmr_req->function == TMR_ABORT_TASK) - qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts, - mcmd->fc_tm_rsp, false); - else - qlt_24xx_send_task_mgmt_ctio(vha, mcmd, - mcmd->fc_tm_rsp); - } - /* - * Make the callback for ->free_mcmd() to queue_work() and invoke - * target_put_sess_cmd() to drop cmd_kref to 1. The final - * target_put_sess_cmd() call will be made from TFO->check_stop_free() - * -> tcm_qla2xxx_check_stop_free() to release the TMR associated se_cmd - * descriptor after TFO->queue_tm_rsp() -> tcm_qla2xxx_queue_tm_rsp() -> - * qlt_xmit_tm_rsp() returns here.. - */ - ha->tgt.tgt_ops->free_mcmd(mcmd); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} -EXPORT_SYMBOL(qlt_xmit_tm_rsp); - -/* No locks */ -static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm) -{ - struct qla_tgt_cmd *cmd = prm->cmd; - - BUG_ON(cmd->sg_cnt == 0); - - prm->sg = (struct scatterlist *)cmd->sg; - prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, cmd->sg, - cmd->sg_cnt, cmd->dma_data_direction); - if (unlikely(prm->seg_cnt == 0)) - goto out_err; - - prm->cmd->sg_mapped = 1; - - /* - * If greater than four sg entries then we need to allocate - * the continuation entries - */ - if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) - prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt - - prm->tgt->datasegs_per_cmd, prm->tgt->datasegs_per_cont); - - ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n", - prm->seg_cnt, prm->req_cnt); - return 0; - -out_err: - ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe04d, - "qla_target(%d): PCI mapping failed: sg_cnt=%d", - 0, prm->cmd->sg_cnt); - return -1; -} - -static inline void qlt_unmap_sg(struct scsi_qla_host *vha, - struct qla_tgt_cmd *cmd) -{ - struct qla_hw_data *ha = vha->hw; - - BUG_ON(!cmd->sg_mapped); - pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); - cmd->sg_mapped = 0; -} - -static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, - uint32_t req_cnt) -{ - struct qla_hw_data *ha = vha->hw; - device_reg_t __iomem *reg = ha->iobase; - uint32_t cnt; - - if (vha->req->cnt < (req_cnt + 2)) { - cnt = (uint16_t)RD_REG_DWORD(®->isp24.req_q_out); - - ql_dbg(ql_dbg_tgt, vha, 0xe00a, - "Request ring circled: cnt=%d, vha->->ring_index=%d, " - "vha->req->cnt=%d, req_cnt=%d\n", cnt, - vha->req->ring_index, vha->req->cnt, req_cnt); - if (vha->req->ring_index < cnt) - vha->req->cnt = cnt - vha->req->ring_index; - else - vha->req->cnt = vha->req->length - - (vha->req->ring_index - cnt); - } - - if (unlikely(vha->req->cnt < (req_cnt + 2))) { - ql_dbg(ql_dbg_tgt, vha, 0xe00b, - "qla_target(%d): There is no room in the " - "request ring: vha->req->ring_index=%d, vha->req->cnt=%d, " - "req_cnt=%d\n", vha->vp_idx, vha->req->ring_index, - vha->req->cnt, req_cnt); - return -EAGAIN; - } - vha->req->cnt -= req_cnt; - - return 0; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static inline void *qlt_get_req_pkt(struct scsi_qla_host *vha) -{ - /* Adjust ring index. */ - vha->req->ring_index++; - if (vha->req->ring_index == vha->req->length) { - vha->req->ring_index = 0; - vha->req->ring_ptr = vha->req->ring; - } else { - vha->req->ring_ptr++; - } - return (cont_entry_t *)vha->req->ring_ptr; -} - -/* ha->hardware_lock supposed to be held on entry */ -static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - uint32_t h; - - h = ha->tgt.current_handle; - /* always increment cmd handle */ - do { - ++h; - if (h > MAX_OUTSTANDING_COMMANDS) - h = 1; /* 0 is QLA_TGT_NULL_HANDLE */ - if (h == ha->tgt.current_handle) { - ql_dbg(ql_dbg_tgt, vha, 0xe04e, - "qla_target(%d): Ran out of " - "empty cmd slots in ha %p\n", vha->vp_idx, ha); - h = QLA_TGT_NULL_HANDLE; - break; - } - } while ((h == QLA_TGT_NULL_HANDLE) || - (h == QLA_TGT_SKIP_HANDLE) || - (ha->tgt.cmds[h-1] != NULL)); - - if (h != QLA_TGT_NULL_HANDLE) - ha->tgt.current_handle = h; - - return h; -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, - struct scsi_qla_host *vha) -{ - uint32_t h; - struct ctio7_to_24xx *pkt; - struct qla_hw_data *ha = vha->hw; - struct atio_from_isp *atio = &prm->cmd->atio; - - pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; - prm->pkt = pkt; - memset(pkt, 0, sizeof(*pkt)); - - pkt->entry_type = CTIO_TYPE7; - pkt->entry_count = (uint8_t)prm->req_cnt; - pkt->vp_index = vha->vp_idx; - - h = qlt_make_handle(vha); - if (unlikely(h == QLA_TGT_NULL_HANDLE)) { - /* - * CTIO type 7 from the firmware doesn't provide a way to - * know the initiator's LOOP ID, hence we can't find - * the session and, so, the command. - */ - return -EAGAIN; - } else - ha->tgt.cmds[h-1] = prm->cmd; - - pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; - pkt->nport_handle = prm->cmd->loop_id; - pkt->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); - pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; - pkt->exchange_addr = atio->u.isp24.exchange_addr; - pkt->u.status0.flags |= (atio->u.isp24.attr << 9); - pkt->u.status0.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); - pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); - - ql_dbg(ql_dbg_tgt, vha, 0xe00c, - "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n", - vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, - le16_to_cpu(pkt->u.status0.ox_id)); - return 0; -} - -/* - * ha->hardware_lock supposed to be held on entry. We have already made sure - * that there is sufficient amount of request entries to not drop it. - */ -static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm, - struct scsi_qla_host *vha) -{ - int cnt; - uint32_t *dword_ptr; - int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr; - - /* Build continuation packets */ - while (prm->seg_cnt > 0) { - cont_a64_entry_t *cont_pkt64 = - (cont_a64_entry_t *)qlt_get_req_pkt(vha); - - /* - * Make sure that from cont_pkt64 none of - * 64-bit specific fields used for 32-bit - * addressing. Cast to (cont_entry_t *) for - * that. - */ - - memset(cont_pkt64, 0, sizeof(*cont_pkt64)); - - cont_pkt64->entry_count = 1; - cont_pkt64->sys_define = 0; - - if (enable_64bit_addressing) { - cont_pkt64->entry_type = CONTINUE_A64_TYPE; - dword_ptr = - (uint32_t *)&cont_pkt64->dseg_0_address; - } else { - cont_pkt64->entry_type = CONTINUE_TYPE; - dword_ptr = - (uint32_t *)&((cont_entry_t *) - cont_pkt64)->dseg_0_address; - } - - /* Load continuation entry data segments */ - for (cnt = 0; - cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt; - cnt++, prm->seg_cnt--) { - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32 - (sg_dma_address(prm->sg))); - if (enable_64bit_addressing) { - *dword_ptr++ = - cpu_to_le32(pci_dma_hi32 - (sg_dma_address - (prm->sg))); - } - *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); - - ql_dbg(ql_dbg_tgt, vha, 0xe00d, - "S/G Segment Cont. phys_addr=%llx:%llx, len=%d\n", - (long long unsigned int) - pci_dma_hi32(sg_dma_address(prm->sg)), - (long long unsigned int) - pci_dma_lo32(sg_dma_address(prm->sg)), - (int)sg_dma_len(prm->sg)); - - prm->sg = sg_next(prm->sg); - } - } -} - -/* - * ha->hardware_lock supposed to be held on entry. We have already made sure - * that there is sufficient amount of request entries to not drop it. - */ -static void qlt_load_data_segments(struct qla_tgt_prm *prm, - struct scsi_qla_host *vha) -{ - int cnt; - uint32_t *dword_ptr; - int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr; - struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt; - - ql_dbg(ql_dbg_tgt, vha, 0xe00e, - "iocb->scsi_status=%x, iocb->flags=%x\n", - le16_to_cpu(pkt24->u.status0.scsi_status), - le16_to_cpu(pkt24->u.status0.flags)); - - pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen); - - /* Setup packet address segment pointer */ - dword_ptr = pkt24->u.status0.dseg_0_address; - - /* Set total data segment count */ - if (prm->seg_cnt) - pkt24->dseg_count = cpu_to_le16(prm->seg_cnt); - - if (prm->seg_cnt == 0) { - /* No data transfer */ - *dword_ptr++ = 0; - *dword_ptr = 0; - return; - } - - /* If scatter gather */ - ql_dbg(ql_dbg_tgt, vha, 0xe00f, "%s", "Building S/G data segments..."); - - /* Load command entry data segments */ - for (cnt = 0; - (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt; - cnt++, prm->seg_cnt--) { - *dword_ptr++ = - cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg))); - if (enable_64bit_addressing) { - *dword_ptr++ = - cpu_to_le32(pci_dma_hi32( - sg_dma_address(prm->sg))); - } - *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); - - ql_dbg(ql_dbg_tgt, vha, 0xe010, - "S/G Segment phys_addr=%llx:%llx, len=%d\n", - (long long unsigned int)pci_dma_hi32(sg_dma_address( - prm->sg)), - (long long unsigned int)pci_dma_lo32(sg_dma_address( - prm->sg)), - (int)sg_dma_len(prm->sg)); - - prm->sg = sg_next(prm->sg); - } - - qlt_load_cont_data_segments(prm, vha); -} - -static inline int qlt_has_data(struct qla_tgt_cmd *cmd) -{ - return cmd->bufflen > 0; -} - -/* - * Called without ha->hardware_lock held - */ -static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd, - struct qla_tgt_prm *prm, int xmit_type, uint8_t scsi_status, - uint32_t *full_req_cnt) -{ - struct qla_tgt *tgt = cmd->tgt; - struct scsi_qla_host *vha = tgt->vha; - struct qla_hw_data *ha = vha->hw; - struct se_cmd *se_cmd = &cmd->se_cmd; - - if (unlikely(cmd->aborted)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, - "qla_target(%d): terminating exchange " - "for aborted cmd=%p (se_cmd=%p, tag=%d)", vha->vp_idx, cmd, - se_cmd, cmd->tag); - - cmd->state = QLA_TGT_STATE_ABORTED; - - qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); - - /* !! At this point cmd could be already freed !! */ - return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED; - } - - ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u\n", - vha->vp_idx, cmd->tag); - - prm->cmd = cmd; - prm->tgt = tgt; - prm->rq_result = scsi_status; - prm->sense_buffer = &cmd->sense_buffer[0]; - prm->sense_buffer_len = TRANSPORT_SENSE_BUFFER; - prm->sg = NULL; - prm->seg_cnt = -1; - prm->req_cnt = 1; - prm->add_status_pkt = 0; - - ql_dbg(ql_dbg_tgt, vha, 0xe012, "rq_result=%x, xmit_type=%x\n", - prm->rq_result, xmit_type); - - /* Send marker if required */ - if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) - return -EFAULT; - - ql_dbg(ql_dbg_tgt, vha, 0xe013, "CTIO start: vha(%d)\n", vha->vp_idx); - - if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) { - if (qlt_pci_map_calc_cnt(prm) != 0) - return -EAGAIN; - } - - *full_req_cnt = prm->req_cnt; - - if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { - prm->residual = se_cmd->residual_count; - ql_dbg(ql_dbg_tgt, vha, 0xe014, - "Residual underflow: %d (tag %d, " - "op %x, bufflen %d, rq_result %x)\n", prm->residual, - cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, - cmd->bufflen, prm->rq_result); - prm->rq_result |= SS_RESIDUAL_UNDER; - } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { - prm->residual = se_cmd->residual_count; - ql_dbg(ql_dbg_tgt, vha, 0xe015, - "Residual overflow: %d (tag %d, " - "op %x, bufflen %d, rq_result %x)\n", prm->residual, - cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, - cmd->bufflen, prm->rq_result); - prm->rq_result |= SS_RESIDUAL_OVER; - } - - if (xmit_type & QLA_TGT_XMIT_STATUS) { - /* - * If QLA_TGT_XMIT_DATA is not set, add_status_pkt will be - * ignored in *xmit_response() below - */ - if (qlt_has_data(cmd)) { - if (QLA_TGT_SENSE_VALID(prm->sense_buffer) || - (IS_FWI2_CAPABLE(ha) && - (prm->rq_result != 0))) { - prm->add_status_pkt = 1; - (*full_req_cnt)++; - } - } - } - - ql_dbg(ql_dbg_tgt, vha, 0xe016, - "req_cnt=%d, full_req_cnt=%d, add_status_pkt=%d\n", - prm->req_cnt, *full_req_cnt, prm->add_status_pkt); - - return 0; -} - -static inline int qlt_need_explicit_conf(struct qla_hw_data *ha, - struct qla_tgt_cmd *cmd, int sending_sense) -{ - if (ha->tgt.enable_class_2) - return 0; - - if (sending_sense) - return cmd->conf_compl_supported; - else - return ha->tgt.enable_explicit_conf && - cmd->conf_compl_supported; -} - -#ifdef CONFIG_QLA_TGT_DEBUG_SRR -/* - * Original taken from the XFS code - */ -static unsigned long qlt_srr_random(void) -{ - static int Inited; - static unsigned long RandomValue; - static DEFINE_SPINLOCK(lock); - /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */ - register long rv; - register long lo; - register long hi; - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - if (!Inited) { - RandomValue = jiffies; - Inited = 1; - } - rv = RandomValue; - hi = rv / 127773; - lo = rv % 127773; - rv = 16807 * lo - 2836 * hi; - if (rv <= 0) - rv += 2147483647; - RandomValue = rv; - spin_unlock_irqrestore(&lock, flags); - return rv; -} - -static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type) -{ -#if 0 /* This is not a real status packets lost, so it won't lead to SRR */ - if ((*xmit_type & QLA_TGT_XMIT_STATUS) && (qlt_srr_random() % 200) - == 50) { - *xmit_type &= ~QLA_TGT_XMIT_STATUS; - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf015, - "Dropping cmd %p (tag %d) status", cmd, cmd->tag); - } -#endif - /* - * It's currently not possible to simulate SRRs for FCP_WRITE without - * a physical link layer failure, so don't even try here.. - */ - if (cmd->dma_data_direction != DMA_FROM_DEVICE) - return; - - if (qlt_has_data(cmd) && (cmd->sg_cnt > 1) && - ((qlt_srr_random() % 100) == 20)) { - int i, leave = 0; - unsigned int tot_len = 0; - - while (leave == 0) - leave = qlt_srr_random() % cmd->sg_cnt; - - for (i = 0; i < leave; i++) - tot_len += cmd->sg[i].length; - - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf016, - "Cutting cmd %p (tag %d) buffer" - " tail to len %d, sg_cnt %d (cmd->bufflen %d," - " cmd->sg_cnt %d)", cmd, cmd->tag, tot_len, leave, - cmd->bufflen, cmd->sg_cnt); - - cmd->bufflen = tot_len; - cmd->sg_cnt = leave; - } - - if (qlt_has_data(cmd) && ((qlt_srr_random() % 100) == 70)) { - unsigned int offset = qlt_srr_random() % cmd->bufflen; - - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf017, - "Cutting cmd %p (tag %d) buffer head " - "to offset %d (cmd->bufflen %d)", cmd, cmd->tag, offset, - cmd->bufflen); - if (offset == 0) - *xmit_type &= ~QLA_TGT_XMIT_DATA; - else if (qlt_set_data_offset(cmd, offset)) { - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf018, - "qlt_set_data_offset() failed (tag %d)", cmd->tag); - } - } -} -#else -static inline void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type) -{} -#endif - -static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio, - struct qla_tgt_prm *prm) -{ - prm->sense_buffer_len = min_t(uint32_t, prm->sense_buffer_len, - (uint32_t)sizeof(ctio->u.status1.sense_data)); - ctio->u.status0.flags |= - __constant_cpu_to_le16(CTIO7_FLAGS_SEND_STATUS); - if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 0)) { - ctio->u.status0.flags |= __constant_cpu_to_le16( - CTIO7_FLAGS_EXPLICIT_CONFORM | - CTIO7_FLAGS_CONFORM_REQ); - } - ctio->u.status0.residual = cpu_to_le32(prm->residual); - ctio->u.status0.scsi_status = cpu_to_le16(prm->rq_result); - if (QLA_TGT_SENSE_VALID(prm->sense_buffer)) { - int i; - - if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 1)) { - if (prm->cmd->se_cmd.scsi_status != 0) { - ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe017, - "Skipping EXPLICIT_CONFORM and " - "CTIO7_FLAGS_CONFORM_REQ for FCP READ w/ " - "non GOOD status\n"); - goto skip_explict_conf; - } - ctio->u.status1.flags |= __constant_cpu_to_le16( - CTIO7_FLAGS_EXPLICIT_CONFORM | - CTIO7_FLAGS_CONFORM_REQ); - } -skip_explict_conf: - ctio->u.status1.flags &= - ~__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); - ctio->u.status1.flags |= - __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1); - ctio->u.status1.scsi_status |= - __constant_cpu_to_le16(SS_SENSE_LEN_VALID); - ctio->u.status1.sense_length = - cpu_to_le16(prm->sense_buffer_len); - for (i = 0; i < prm->sense_buffer_len/4; i++) - ((uint32_t *)ctio->u.status1.sense_data)[i] = - cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]); -#if 0 - if (unlikely((prm->sense_buffer_len % 4) != 0)) { - static int q; - if (q < 10) { - ql_dbg(ql_dbg_tgt, vha, 0xe04f, - "qla_target(%d): %d bytes of sense " - "lost", prm->tgt->ha->vp_idx, - prm->sense_buffer_len % 4); - q++; - } - } -#endif - } else { - ctio->u.status1.flags &= - ~__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); - ctio->u.status1.flags |= - __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1); - ctio->u.status1.sense_length = 0; - memset(ctio->u.status1.sense_data, 0, - sizeof(ctio->u.status1.sense_data)); - } - - /* Sense with len > 24, is it possible ??? */ -} - -/* - * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * - * QLA_TGT_XMIT_STATUS for >= 24xx silicon - */ -int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, - uint8_t scsi_status) -{ - struct scsi_qla_host *vha = cmd->vha; - struct qla_hw_data *ha = vha->hw; - struct ctio7_to_24xx *pkt; - struct qla_tgt_prm prm; - uint32_t full_req_cnt = 0; - unsigned long flags = 0; - int res; - - memset(&prm, 0, sizeof(prm)); - qlt_check_srr_debug(cmd, &xmit_type); - - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018, - "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, " - "cmd->dma_data_direction=%d\n", (xmit_type & QLA_TGT_XMIT_STATUS) ? - 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction); - - res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, - &full_req_cnt); - if (unlikely(res != 0)) { - if (res == QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED) - return 0; - - return res; - } - - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* Does F/W have an IOCBs for this request */ - res = qlt_check_reserve_free_req(vha, full_req_cnt); - if (unlikely(res)) - goto out_unmap_unlock; - - res = qlt_24xx_build_ctio_pkt(&prm, vha); - if (unlikely(res != 0)) - goto out_unmap_unlock; - - - pkt = (struct ctio7_to_24xx *)prm.pkt; - - if (qlt_has_data(cmd) && (xmit_type & QLA_TGT_XMIT_DATA)) { - pkt->u.status0.flags |= - __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN | - CTIO7_FLAGS_STATUS_MODE_0); - - qlt_load_data_segments(&prm, vha); - - if (prm.add_status_pkt == 0) { - if (xmit_type & QLA_TGT_XMIT_STATUS) { - pkt->u.status0.scsi_status = - cpu_to_le16(prm.rq_result); - pkt->u.status0.residual = - cpu_to_le32(prm.residual); - pkt->u.status0.flags |= __constant_cpu_to_le16( - CTIO7_FLAGS_SEND_STATUS); - if (qlt_need_explicit_conf(ha, cmd, 0)) { - pkt->u.status0.flags |= - __constant_cpu_to_le16( - CTIO7_FLAGS_EXPLICIT_CONFORM | - CTIO7_FLAGS_CONFORM_REQ); - } - } - - } else { - /* - * We have already made sure that there is sufficient - * amount of request entries to not drop HW lock in - * req_pkt(). - */ - struct ctio7_to_24xx *ctio = - (struct ctio7_to_24xx *)qlt_get_req_pkt(vha); - - ql_dbg(ql_dbg_tgt, vha, 0xe019, - "Building additional status packet\n"); - - memcpy(ctio, pkt, sizeof(*ctio)); - ctio->entry_count = 1; - ctio->dseg_count = 0; - ctio->u.status1.flags &= ~__constant_cpu_to_le16( - CTIO7_FLAGS_DATA_IN); - - /* Real finish is ctio_m1's finish */ - pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK; - pkt->u.status0.flags |= __constant_cpu_to_le16( - CTIO7_FLAGS_DONT_RET_CTIO); - qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio, - &prm); - pr_debug("Status CTIO7: %p\n", ctio); - } - } else - qlt_24xx_init_ctio_to_isp(pkt, &prm); - - - cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ - - ql_dbg(ql_dbg_tgt, vha, 0xe01a, - "Xmitting CTIO7 response pkt for 24xx: %p scsi_status: 0x%02x\n", - pkt, scsi_status); - - qla2x00_start_iocbs(vha, vha->req); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return 0; - -out_unmap_unlock: - if (cmd->sg_mapped) - qlt_unmap_sg(vha, cmd); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return res; -} -EXPORT_SYMBOL(qlt_xmit_response); - -int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) -{ - struct ctio7_to_24xx *pkt; - struct scsi_qla_host *vha = cmd->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = cmd->tgt; - struct qla_tgt_prm prm; - unsigned long flags; - int res = 0; - - memset(&prm, 0, sizeof(prm)); - prm.cmd = cmd; - prm.tgt = tgt; - prm.sg = NULL; - prm.req_cnt = 1; - - /* Send marker if required */ - if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) - return -EIO; - - ql_dbg(ql_dbg_tgt, vha, 0xe01b, "CTIO_start: vha(%d)", - (int)vha->vp_idx); - - /* Calculate number of entries and segments required */ - if (qlt_pci_map_calc_cnt(&prm) != 0) - return -EAGAIN; - - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* Does F/W have an IOCBs for this request */ - res = qlt_check_reserve_free_req(vha, prm.req_cnt); - if (res != 0) - goto out_unlock_free_unmap; - - res = qlt_24xx_build_ctio_pkt(&prm, vha); - if (unlikely(res != 0)) - goto out_unlock_free_unmap; - pkt = (struct ctio7_to_24xx *)prm.pkt; - pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT | - CTIO7_FLAGS_STATUS_MODE_0); - qlt_load_data_segments(&prm, vha); - - cmd->state = QLA_TGT_STATE_NEED_DATA; - - qla2x00_start_iocbs(vha, vha->req); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return res; - -out_unlock_free_unmap: - if (cmd->sg_mapped) - qlt_unmap_sg(vha, cmd); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return res; -} -EXPORT_SYMBOL(qlt_rdy_to_xfer); - -/* If hardware_lock held on entry, might drop it, then reaquire */ -/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ -static int __qlt_send_term_exchange(struct scsi_qla_host *vha, - struct qla_tgt_cmd *cmd, - struct atio_from_isp *atio) -{ - struct ctio7_to_24xx *ctio24; - struct qla_hw_data *ha = vha->hw; - request_t *pkt; - int ret = 0; - - ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha); - - pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); - if (pkt == NULL) { - ql_dbg(ql_dbg_tgt, vha, 0xe050, - "qla_target(%d): %s failed: unable to allocate " - "request packet\n", vha->vp_idx, __func__); - return -ENOMEM; - } - - if (cmd != NULL) { - if (cmd->state < QLA_TGT_STATE_PROCESSED) { - ql_dbg(ql_dbg_tgt, vha, 0xe051, - "qla_target(%d): Terminating cmd %p with " - "incorrect state %d\n", vha->vp_idx, cmd, - cmd->state); - } else - ret = 1; - } - - pkt->entry_count = 1; - pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; - - ctio24 = (struct ctio7_to_24xx *)pkt; - ctio24->entry_type = CTIO_TYPE7; - ctio24->nport_handle = cmd ? cmd->loop_id : CTIO7_NHANDLE_UNRECOGNIZED; - ctio24->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); - ctio24->vp_index = vha->vp_idx; - ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; - ctio24->exchange_addr = atio->u.isp24.exchange_addr; - ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | - __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | - CTIO7_FLAGS_TERMINATE); - ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); - - /* Most likely, it isn't needed */ - ctio24->u.status1.residual = get_unaligned((uint32_t *) - &atio->u.isp24.fcp_cmnd.add_cdb[ - atio->u.isp24.fcp_cmnd.add_cdb_len]); - if (ctio24->u.status1.residual != 0) - ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER; - - qla2x00_start_iocbs(vha, vha->req); - return ret; -} - -static void qlt_send_term_exchange(struct scsi_qla_host *vha, - struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) -{ - unsigned long flags; - int rc; - - if (qlt_issue_marker(vha, ha_locked) < 0) - return; - - if (ha_locked) { - rc = __qlt_send_term_exchange(vha, cmd, atio); - goto done; - } - spin_lock_irqsave(&vha->hw->hardware_lock, flags); - rc = __qlt_send_term_exchange(vha, cmd, atio); - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); -done: - if (rc == 1) { - if (!ha_locked && !in_interrupt()) - msleep(250); /* just in case */ - - vha->hw->tgt.tgt_ops->free_cmd(cmd); - } -} - -void qlt_free_cmd(struct qla_tgt_cmd *cmd) -{ - BUG_ON(cmd->sg_mapped); - - if (unlikely(cmd->free_sg)) - kfree(cmd->sg); - kmem_cache_free(qla_tgt_cmd_cachep, cmd); -} -EXPORT_SYMBOL(qlt_free_cmd); - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_prepare_srr_ctio(struct scsi_qla_host *vha, - struct qla_tgt_cmd *cmd, void *ctio) -{ - struct qla_tgt_srr_ctio *sc; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_srr_imm *imm; - - tgt->ctio_srr_id++; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019, - "qla_target(%d): CTIO with SRR status received\n", vha->vp_idx); - - if (!ctio) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf055, - "qla_target(%d): SRR CTIO, but ctio is NULL\n", - vha->vp_idx); - return -EINVAL; - } - - sc = kzalloc(sizeof(*sc), GFP_ATOMIC); - if (sc != NULL) { - sc->cmd = cmd; - /* IRQ is already OFF */ - spin_lock(&tgt->srr_lock); - sc->srr_id = tgt->ctio_srr_id; - list_add_tail(&sc->srr_list_entry, - &tgt->srr_ctio_list); - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a, - "CTIO SRR %p added (id %d)\n", sc, sc->srr_id); - if (tgt->imm_srr_id == tgt->ctio_srr_id) { - int found = 0; - list_for_each_entry(imm, &tgt->srr_imm_list, - srr_list_entry) { - if (imm->srr_id == sc->srr_id) { - found = 1; - break; - } - } - if (found) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01b, - "Scheduling srr work\n"); - schedule_work(&tgt->srr_work); - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf056, - "qla_target(%d): imm_srr_id " - "== ctio_srr_id (%d), but there is no " - "corresponding SRR IMM, deleting CTIO " - "SRR %p\n", vha->vp_idx, - tgt->ctio_srr_id, sc); - list_del(&sc->srr_list_entry); - spin_unlock(&tgt->srr_lock); - - kfree(sc); - return -EINVAL; - } - } - spin_unlock(&tgt->srr_lock); - } else { - struct qla_tgt_srr_imm *ti; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf057, - "qla_target(%d): Unable to allocate SRR CTIO entry\n", - vha->vp_idx); - spin_lock(&tgt->srr_lock); - list_for_each_entry_safe(imm, ti, &tgt->srr_imm_list, - srr_list_entry) { - if (imm->srr_id == tgt->ctio_srr_id) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01c, - "IMM SRR %p deleted (id %d)\n", - imm, imm->srr_id); - list_del(&imm->srr_list_entry); - qlt_reject_free_srr_imm(vha, imm, 1); - } - } - spin_unlock(&tgt->srr_lock); - - return -ENOMEM; - } - - return 0; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, - struct qla_tgt_cmd *cmd, uint32_t status) -{ - int term = 0; - - if (ctio != NULL) { - struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; - term = !(c->flags & - __constant_cpu_to_le16(OF_TERM_EXCH)); - } else - term = 1; - - if (term) - qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); - - return term; -} - -/* ha->hardware_lock supposed to be held on entry */ -static inline struct qla_tgt_cmd *qlt_get_cmd(struct scsi_qla_host *vha, - uint32_t handle) -{ - struct qla_hw_data *ha = vha->hw; - - handle--; - if (ha->tgt.cmds[handle] != NULL) { - struct qla_tgt_cmd *cmd = ha->tgt.cmds[handle]; - ha->tgt.cmds[handle] = NULL; - return cmd; - } else - return NULL; -} - -/* ha->hardware_lock supposed to be held on entry */ -static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha, - uint32_t handle, void *ctio) -{ - struct qla_tgt_cmd *cmd = NULL; - - /* Clear out internal marks */ - handle &= ~(CTIO_COMPLETION_HANDLE_MARK | - CTIO_INTERMEDIATE_HANDLE_MARK); - - if (handle != QLA_TGT_NULL_HANDLE) { - if (unlikely(handle == QLA_TGT_SKIP_HANDLE)) { - ql_dbg(ql_dbg_tgt, vha, 0xe01d, "%s", - "SKIP_HANDLE CTIO\n"); - return NULL; - } - /* handle-1 is actually used */ - if (unlikely(handle > MAX_OUTSTANDING_COMMANDS)) { - ql_dbg(ql_dbg_tgt, vha, 0xe052, - "qla_target(%d): Wrong handle %x received\n", - vha->vp_idx, handle); - return NULL; - } - cmd = qlt_get_cmd(vha, handle); - if (unlikely(cmd == NULL)) { - ql_dbg(ql_dbg_tgt, vha, 0xe053, - "qla_target(%d): Suspicious: unable to " - "find the command with handle %x\n", vha->vp_idx, - handle); - return NULL; - } - } else if (ctio != NULL) { - /* We can't get loop ID from CTIO7 */ - ql_dbg(ql_dbg_tgt, vha, 0xe054, - "qla_target(%d): Wrong CTIO received: QLA24xx doesn't " - "support NULL handles\n", vha->vp_idx); - return NULL; - } - - return cmd; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, - uint32_t status, void *ctio) -{ - struct qla_hw_data *ha = vha->hw; - struct se_cmd *se_cmd; - struct target_core_fabric_ops *tfo; - struct qla_tgt_cmd *cmd; - - ql_dbg(ql_dbg_tgt, vha, 0xe01e, - "qla_target(%d): handle(ctio %p status %#x) <- %08x\n", - vha->vp_idx, ctio, status, handle); - - if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { - /* That could happen only in case of an error/reset/abort */ - if (status != CTIO_SUCCESS) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01d, - "Intermediate CTIO received" - " (status %x)\n", status); - } - return; - } - - cmd = qlt_ctio_to_cmd(vha, handle, ctio); - if (cmd == NULL) { - if (status != CTIO_SUCCESS) - qlt_term_ctio_exchange(vha, ctio, NULL, status); - return; - } - se_cmd = &cmd->se_cmd; - tfo = se_cmd->se_tfo; - - if (cmd->sg_mapped) - qlt_unmap_sg(vha, cmd); - - if (unlikely(status != CTIO_SUCCESS)) { - switch (status & 0xFFFF) { - case CTIO_LIP_RESET: - case CTIO_TARGET_RESET: - case CTIO_ABORTED: - case CTIO_TIMEOUT: - case CTIO_INVALID_RX_ID: - /* They are OK */ - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf058, - "qla_target(%d): CTIO with " - "status %#x received, state %x, se_cmd %p, " - "(LIP_RESET=e, ABORTED=2, TARGET_RESET=17, " - "TIMEOUT=b, INVALID_RX_ID=8)\n", vha->vp_idx, - status, cmd->state, se_cmd); - break; - - case CTIO_PORT_LOGGED_OUT: - case CTIO_PORT_UNAVAILABLE: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059, - "qla_target(%d): CTIO with PORT LOGGED " - "OUT (29) or PORT UNAVAILABLE (28) status %x " - "received (state %x, se_cmd %p)\n", vha->vp_idx, - status, cmd->state, se_cmd); - break; - - case CTIO_SRR_RECEIVED: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a, - "qla_target(%d): CTIO with SRR_RECEIVED" - " status %x received (state %x, se_cmd %p)\n", - vha->vp_idx, status, cmd->state, se_cmd); - if (qlt_prepare_srr_ctio(vha, cmd, ctio) != 0) - break; - else - return; - - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, - "qla_target(%d): CTIO with error status " - "0x%x received (state %x, se_cmd %p\n", - vha->vp_idx, status, cmd->state, se_cmd); - break; - } - - if (cmd->state != QLA_TGT_STATE_NEED_DATA) - if (qlt_term_ctio_exchange(vha, ctio, cmd, status)) - return; - } - - if (cmd->state == QLA_TGT_STATE_PROCESSED) { - ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd); - } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { - int rx_status = 0; - - cmd->state = QLA_TGT_STATE_DATA_IN; - - if (unlikely(status != CTIO_SUCCESS)) - rx_status = -EIO; - else - cmd->write_data_transferred = 1; - - ql_dbg(ql_dbg_tgt, vha, 0xe020, - "Data received, context %x, rx_status %d\n", - 0x0, rx_status); - - ha->tgt.tgt_ops->handle_data(cmd); - return; - } else if (cmd->state == QLA_TGT_STATE_ABORTED) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e, - "Aborted command %p (tag %d) finished\n", cmd, cmd->tag); - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c, - "qla_target(%d): A command in state (%d) should " - "not return a CTIO complete\n", vha->vp_idx, cmd->state); - } - - if (unlikely(status != CTIO_SUCCESS)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n"); - dump_stack(); - } - - ha->tgt.tgt_ops->free_cmd(cmd); -} - -/* ha->hardware_lock supposed to be held on entry */ -/* called via callback from qla2xxx */ -void qlt_ctio_completion(struct scsi_qla_host *vha, uint32_t handle) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - - if (likely(tgt == NULL)) { - ql_dbg(ql_dbg_tgt, vha, 0xe021, - "CTIO, but target mode not enabled" - " (ha %d %p handle %#x)", vha->vp_idx, ha, handle); - return; - } - - tgt->irq_cmd_count++; - qlt_do_ctio_completion(vha, handle, CTIO_SUCCESS, NULL); - tgt->irq_cmd_count--; -} - -static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha, - uint8_t task_codes) -{ - int fcp_task_attr; - - switch (task_codes) { - case ATIO_SIMPLE_QUEUE: - fcp_task_attr = MSG_SIMPLE_TAG; - break; - case ATIO_HEAD_OF_QUEUE: - fcp_task_attr = MSG_HEAD_TAG; - break; - case ATIO_ORDERED_QUEUE: - fcp_task_attr = MSG_ORDERED_TAG; - break; - case ATIO_ACA_QUEUE: - fcp_task_attr = MSG_ACA_TAG; - break; - case ATIO_UNTAGGED: - fcp_task_attr = MSG_SIMPLE_TAG; - break; - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05d, - "qla_target: unknown task code %x, use ORDERED instead\n", - task_codes); - fcp_task_attr = MSG_ORDERED_TAG; - break; - } - - return fcp_task_attr; -} - -static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *, - uint8_t *); -/* - * Process context for I/O path into tcm_qla2xxx code - */ -static void qlt_do_work(struct work_struct *work) -{ - struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); - scsi_qla_host_t *vha = cmd->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_sess *sess = NULL; - struct atio_from_isp *atio = &cmd->atio; - unsigned char *cdb; - unsigned long flags; - uint32_t data_length; - int ret, fcp_task_attr, data_dir, bidi = 0; - - if (tgt->tgt_stop) - goto out_term; - - spin_lock_irqsave(&ha->hardware_lock, flags); - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - atio->u.isp24.fcp_hdr.s_id); - if (sess) { - if (unlikely(sess->tearing_down)) { - sess = NULL; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - goto out_term; - } else { - /* - * Do the extra kref_get() before dropping - * qla_hw_data->hardware_lock. - */ - kref_get(&sess->se_sess->sess_kref); - } - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (unlikely(!sess)) { - uint8_t *s_id = atio->u.isp24.fcp_hdr.s_id; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022, - "qla_target(%d): Unable to find wwn login" - " (s_id %x:%x:%x), trying to create it manually\n", - vha->vp_idx, s_id[0], s_id[1], s_id[2]); - - if (atio->u.raw.entry_count > 1) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023, - "Dropping multy entry cmd %p\n", cmd); - goto out_term; - } - - mutex_lock(&ha->tgt.tgt_mutex); - sess = qlt_make_local_sess(vha, s_id); - /* sess has an extra creation ref. */ - mutex_unlock(&ha->tgt.tgt_mutex); - - if (!sess) - goto out_term; - } - - cmd->sess = sess; - cmd->loop_id = sess->loop_id; - cmd->conf_compl_supported = sess->conf_compl_supported; - - cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; - cmd->tag = atio->u.isp24.exchange_addr; - cmd->unpacked_lun = scsilun_to_int( - (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun); - - if (atio->u.isp24.fcp_cmnd.rddata && - atio->u.isp24.fcp_cmnd.wrdata) { - bidi = 1; - data_dir = DMA_TO_DEVICE; - } else if (atio->u.isp24.fcp_cmnd.rddata) - data_dir = DMA_FROM_DEVICE; - else if (atio->u.isp24.fcp_cmnd.wrdata) - data_dir = DMA_TO_DEVICE; - else - data_dir = DMA_NONE; - - fcp_task_attr = qlt_get_fcp_task_attr(vha, - atio->u.isp24.fcp_cmnd.task_attr); - data_length = be32_to_cpu(get_unaligned((uint32_t *) - &atio->u.isp24.fcp_cmnd.add_cdb[ - atio->u.isp24.fcp_cmnd.add_cdb_len])); - - ql_dbg(ql_dbg_tgt, vha, 0xe022, - "qla_target: START qla command: %p lun: 0x%04x (tag %d)\n", - cmd, cmd->unpacked_lun, cmd->tag); - - ret = vha->hw->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length, - fcp_task_attr, data_dir, bidi); - if (ret != 0) - goto out_term; - /* - * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( - */ - ha->tgt.tgt_ops->put_sess(sess); - return; - -out_term: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd); - /* - * cmd has not sent to target yet, so pass NULL as the second argument - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (sess) - ha->tgt.tgt_ops->put_sess(sess); -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, - struct atio_from_isp *atio) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_cmd *cmd; - - if (unlikely(tgt->tgt_stop)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021, - "New command while device %p is shutting down\n", tgt); - return -EFAULT; - } - - cmd = kmem_cache_zalloc(qla_tgt_cmd_cachep, GFP_ATOMIC); - if (!cmd) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05e, - "qla_target(%d): Allocation of cmd failed\n", vha->vp_idx); - return -ENOMEM; - } - - INIT_LIST_HEAD(&cmd->cmd_list); - - memcpy(&cmd->atio, atio, sizeof(*atio)); - cmd->state = QLA_TGT_STATE_NEW; - cmd->tgt = ha->tgt.qla_tgt; - cmd->vha = vha; - - INIT_WORK(&cmd->work, qlt_do_work); - queue_work(qla_tgt_wq, &cmd->work); - return 0; - -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, - int fn, void *iocb, int flags) -{ - struct scsi_qla_host *vha = sess->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_mgmt_cmd *mcmd; - int res; - uint8_t tmr_func; - - mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); - if (!mcmd) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10009, - "qla_target(%d): Allocation of management " - "command failed, some commands and their data could " - "leak\n", vha->vp_idx); - return -ENOMEM; - } - memset(mcmd, 0, sizeof(*mcmd)); - mcmd->sess = sess; - - if (iocb) { - memcpy(&mcmd->orig_iocb.imm_ntfy, iocb, - sizeof(mcmd->orig_iocb.imm_ntfy)); - } - mcmd->tmr_func = fn; - mcmd->flags = flags; - - switch (fn) { - case QLA_TGT_CLEAR_ACA: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10000, - "qla_target(%d): CLEAR_ACA received\n", sess->vha->vp_idx); - tmr_func = TMR_CLEAR_ACA; - break; - - case QLA_TGT_TARGET_RESET: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10001, - "qla_target(%d): TARGET_RESET received\n", - sess->vha->vp_idx); - tmr_func = TMR_TARGET_WARM_RESET; - break; - - case QLA_TGT_LUN_RESET: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10002, - "qla_target(%d): LUN_RESET received\n", sess->vha->vp_idx); - tmr_func = TMR_LUN_RESET; - break; - - case QLA_TGT_CLEAR_TS: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10003, - "qla_target(%d): CLEAR_TS received\n", sess->vha->vp_idx); - tmr_func = TMR_CLEAR_TASK_SET; - break; - - case QLA_TGT_ABORT_TS: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10004, - "qla_target(%d): ABORT_TS received\n", sess->vha->vp_idx); - tmr_func = TMR_ABORT_TASK_SET; - break; -#if 0 - case QLA_TGT_ABORT_ALL: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10005, - "qla_target(%d): Doing ABORT_ALL_TASKS\n", - sess->vha->vp_idx); - tmr_func = 0; - break; - - case QLA_TGT_ABORT_ALL_SESS: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10006, - "qla_target(%d): Doing ABORT_ALL_TASKS_SESS\n", - sess->vha->vp_idx); - tmr_func = 0; - break; - - case QLA_TGT_NEXUS_LOSS_SESS: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10007, - "qla_target(%d): Doing NEXUS_LOSS_SESS\n", - sess->vha->vp_idx); - tmr_func = 0; - break; - - case QLA_TGT_NEXUS_LOSS: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x10008, - "qla_target(%d): Doing NEXUS_LOSS\n", sess->vha->vp_idx); - tmr_func = 0; - break; -#endif - default: - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000a, - "qla_target(%d): Unknown task mgmt fn 0x%x\n", - sess->vha->vp_idx, fn); - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); - return -ENOSYS; - } - - res = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, tmr_func, 0); - if (res != 0) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000b, - "qla_target(%d): tgt.tgt_ops->handle_tmr() failed: %d\n", - sess->vha->vp_idx, res); - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); - return -EFAULT; - } - - return 0; -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb) -{ - struct atio_from_isp *a = (struct atio_from_isp *)iocb; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt; - struct qla_tgt_sess *sess; - uint32_t lun, unpacked_lun; - int lun_size, fn; - - tgt = ha->tgt.qla_tgt; - - lun = a->u.isp24.fcp_cmnd.lun; - lun_size = sizeof(a->u.isp24.fcp_cmnd.lun); - fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - a->u.isp24.fcp_hdr.s_id); - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); - - if (!sess) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024, - "qla_target(%d): task mgmt fn 0x%x for " - "non-existant session\n", vha->vp_idx, fn); - return qlt_sched_sess_work(tgt, QLA_TGT_SESS_WORK_TM, iocb, - sizeof(struct atio_from_isp)); - } - - return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); -} - -/* ha->hardware_lock supposed to be held on entry */ -static int __qlt_abort_task(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *iocb, struct qla_tgt_sess *sess) -{ - struct atio_from_isp *a = (struct atio_from_isp *)iocb; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_mgmt_cmd *mcmd; - uint32_t lun, unpacked_lun; - int rc; - - mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); - if (mcmd == NULL) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05f, - "qla_target(%d): %s: Allocation of ABORT cmd failed\n", - vha->vp_idx, __func__); - return -ENOMEM; - } - memset(mcmd, 0, sizeof(*mcmd)); - - mcmd->sess = sess; - memcpy(&mcmd->orig_iocb.imm_ntfy, iocb, - sizeof(mcmd->orig_iocb.imm_ntfy)); - - lun = a->u.isp24.fcp_cmnd.lun; - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); - - rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, TMR_ABORT_TASK, - le16_to_cpu(iocb->u.isp2x.seq_id)); - if (rc != 0) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf060, - "qla_target(%d): tgt_ops->handle_tmr() failed: %d\n", - vha->vp_idx, rc); - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); - return -EFAULT; - } - - return 0; -} - -/* ha->hardware_lock supposed to be held on entry */ -static int qlt_abort_task(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *iocb) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess; - int loop_id; - - loop_id = GET_TARGET_ID(ha, (struct atio_from_isp *)iocb); - - sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id); - if (sess == NULL) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025, - "qla_target(%d): task abort for unexisting " - "session\n", vha->vp_idx); - return qlt_sched_sess_work(ha->tgt.qla_tgt, - QLA_TGT_SESS_WORK_ABORT, iocb, sizeof(*iocb)); - } - - return __qlt_abort_task(vha, iocb, sess); -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static int qlt_24xx_handle_els(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *iocb) -{ - struct qla_hw_data *ha = vha->hw; - int res = 0; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026, - "qla_target(%d): Port ID: 0x%02x:%02x:%02x" - " ELS opcode: 0x%02x\n", vha->vp_idx, iocb->u.isp24.port_id[0], - iocb->u.isp24.port_id[1], iocb->u.isp24.port_id[2], - iocb->u.isp24.status_subcode); - - switch (iocb->u.isp24.status_subcode) { - case ELS_PLOGI: - case ELS_FLOGI: - case ELS_PRLI: - case ELS_LOGO: - case ELS_PRLO: - res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS); - break; - case ELS_PDISC: - case ELS_ADISC: - { - struct qla_tgt *tgt = ha->tgt.qla_tgt; - if (tgt->link_reinit_iocb_pending) { - qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, - 0, 0, 0, 0, 0, 0); - tgt->link_reinit_iocb_pending = 0; - } - res = 1; /* send notify ack */ - break; - } - - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf061, - "qla_target(%d): Unsupported ELS command %x " - "received\n", vha->vp_idx, iocb->u.isp24.status_subcode); - res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS); - break; - } - - return res; -} - -static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset) -{ - struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL; - size_t first_offset = 0, rem_offset = offset, tmp = 0; - int i, sg_srr_cnt, bufflen = 0; - - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe023, - "Entering qla_tgt_set_data_offset: cmd: %p, cmd->sg: %p, " - "cmd->sg_cnt: %u, direction: %d\n", - cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); - - /* - * FIXME: Reject non zero SRR relative offset until we can test - * this code properly. - */ - pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset); - return -1; - - if (!cmd->sg || !cmd->sg_cnt) { - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055, - "Missing cmd->sg or zero cmd->sg_cnt in" - " qla_tgt_set_data_offset\n"); - return -EINVAL; - } - /* - * Walk the current cmd->sg list until we locate the new sg_srr_start - */ - for_each_sg(cmd->sg, sg, cmd->sg_cnt, i) { - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe024, - "sg[%d]: %p page: %p, length: %d, offset: %d\n", - i, sg, sg_page(sg), sg->length, sg->offset); - - if ((sg->length + tmp) > offset) { - first_offset = rem_offset; - sg_srr_start = sg; - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe025, - "Found matching sg[%d], using %p as sg_srr_start, " - "and using first_offset: %zu\n", i, sg, - first_offset); - break; - } - tmp += sg->length; - rem_offset -= sg->length; - } - - if (!sg_srr_start) { - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe056, - "Unable to locate sg_srr_start for offset: %u\n", offset); - return -EINVAL; - } - sg_srr_cnt = (cmd->sg_cnt - i); - - sg_srr = kzalloc(sizeof(struct scatterlist) * sg_srr_cnt, GFP_KERNEL); - if (!sg_srr) { - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe057, - "Unable to allocate sgp\n"); - return -ENOMEM; - } - sg_init_table(sg_srr, sg_srr_cnt); - sgp = &sg_srr[0]; - /* - * Walk the remaining list for sg_srr_start, mapping to the newly - * allocated sg_srr taking first_offset into account. - */ - for_each_sg(sg_srr_start, sg, sg_srr_cnt, i) { - if (first_offset) { - sg_set_page(sgp, sg_page(sg), - (sg->length - first_offset), first_offset); - first_offset = 0; - } else { - sg_set_page(sgp, sg_page(sg), sg->length, 0); - } - bufflen += sgp->length; - - sgp = sg_next(sgp); - if (!sgp) - break; - } - - cmd->sg = sg_srr; - cmd->sg_cnt = sg_srr_cnt; - cmd->bufflen = bufflen; - cmd->offset += offset; - cmd->free_sg = 1; - - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe026, "New cmd->sg: %p\n", cmd->sg); - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe027, "New cmd->sg_cnt: %u\n", - cmd->sg_cnt); - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe028, "New cmd->bufflen: %u\n", - cmd->bufflen); - ql_dbg(ql_dbg_tgt, cmd->vha, 0xe029, "New cmd->offset: %u\n", - cmd->offset); - - if (cmd->sg_cnt < 0) - BUG(); - - if (cmd->bufflen < 0) - BUG(); - - return 0; -} - -static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd, - uint32_t srr_rel_offs, int *xmit_type) -{ - int res = 0, rel_offs; - - rel_offs = srr_rel_offs - cmd->offset; - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf027, "srr_rel_offs=%d, rel_offs=%d", - srr_rel_offs, rel_offs); - - *xmit_type = QLA_TGT_XMIT_ALL; - - if (rel_offs < 0) { - ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf062, - "qla_target(%d): SRR rel_offs (%d) < 0", - cmd->vha->vp_idx, rel_offs); - res = -1; - } else if (rel_offs == cmd->bufflen) - *xmit_type = QLA_TGT_XMIT_STATUS; - else if (rel_offs > 0) - res = qlt_set_data_offset(cmd, rel_offs); - - return res; -} - -/* No locks, thread context */ -static void qlt_handle_srr(struct scsi_qla_host *vha, - struct qla_tgt_srr_ctio *sctio, struct qla_tgt_srr_imm *imm) -{ - struct imm_ntfy_from_isp *ntfy = - (struct imm_ntfy_from_isp *)&imm->imm_ntfy; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_cmd *cmd = sctio->cmd; - struct se_cmd *se_cmd = &cmd->se_cmd; - unsigned long flags; - int xmit_type = 0, resp = 0; - uint32_t offset; - uint16_t srr_ui; - - offset = le32_to_cpu(ntfy->u.isp24.srr_rel_offs); - srr_ui = ntfy->u.isp24.srr_ui; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf028, "SRR cmd %p, srr_ui %x\n", - cmd, srr_ui); - - switch (srr_ui) { - case SRR_IU_STATUS: - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_notify_ack(vha, ntfy, - 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - xmit_type = QLA_TGT_XMIT_STATUS; - resp = 1; - break; - case SRR_IU_DATA_IN: - if (!cmd->sg || !cmd->sg_cnt) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf063, - "Unable to process SRR_IU_DATA_IN due to" - " missing cmd->sg, state: %d\n", cmd->state); - dump_stack(); - goto out_reject; - } - if (se_cmd->scsi_status != 0) { - ql_dbg(ql_dbg_tgt, vha, 0xe02a, - "Rejecting SRR_IU_DATA_IN with non GOOD " - "scsi_status\n"); - goto out_reject; - } - cmd->bufflen = se_cmd->data_length; - - if (qlt_has_data(cmd)) { - if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0) - goto out_reject; - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_notify_ack(vha, ntfy, - 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - resp = 1; - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf064, - "qla_target(%d): SRR for in data for cmd " - "without them (tag %d, SCSI status %d), " - "reject", vha->vp_idx, cmd->tag, - cmd->se_cmd.scsi_status); - goto out_reject; - } - break; - case SRR_IU_DATA_OUT: - if (!cmd->sg || !cmd->sg_cnt) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf065, - "Unable to process SRR_IU_DATA_OUT due to" - " missing cmd->sg\n"); - dump_stack(); - goto out_reject; - } - if (se_cmd->scsi_status != 0) { - ql_dbg(ql_dbg_tgt, vha, 0xe02b, - "Rejecting SRR_IU_DATA_OUT" - " with non GOOD scsi_status\n"); - goto out_reject; - } - cmd->bufflen = se_cmd->data_length; - - if (qlt_has_data(cmd)) { - if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0) - goto out_reject; - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_notify_ack(vha, ntfy, - 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (xmit_type & QLA_TGT_XMIT_DATA) - qlt_rdy_to_xfer(cmd); - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066, - "qla_target(%d): SRR for out data for cmd " - "without them (tag %d, SCSI status %d), " - "reject", vha->vp_idx, cmd->tag, - cmd->se_cmd.scsi_status); - goto out_reject; - } - break; - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf067, - "qla_target(%d): Unknown srr_ui value %x", - vha->vp_idx, srr_ui); - goto out_reject; - } - - /* Transmit response in case of status and data-in cases */ - if (resp) - qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); - - return; - -out_reject: - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_notify_ack(vha, ntfy, 0, 0, 0, - NOTIFY_ACK_SRR_FLAGS_REJECT, - NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, - NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); - if (cmd->state == QLA_TGT_STATE_NEED_DATA) { - cmd->state = QLA_TGT_STATE_DATA_IN; - dump_stack(); - } else - qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); - spin_unlock_irqrestore(&ha->hardware_lock, flags); -} - -static void qlt_reject_free_srr_imm(struct scsi_qla_host *vha, - struct qla_tgt_srr_imm *imm, int ha_locked) -{ - struct qla_hw_data *ha = vha->hw; - unsigned long flags = 0; - - if (!ha_locked) - spin_lock_irqsave(&ha->hardware_lock, flags); - - qlt_send_notify_ack(vha, (void *)&imm->imm_ntfy, 0, 0, 0, - NOTIFY_ACK_SRR_FLAGS_REJECT, - NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, - NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); - - if (!ha_locked) - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - kfree(imm); -} - -static void qlt_handle_srr_work(struct work_struct *work) -{ - struct qla_tgt *tgt = container_of(work, struct qla_tgt, srr_work); - struct scsi_qla_host *vha = tgt->vha; - struct qla_tgt_srr_ctio *sctio; - unsigned long flags; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf029, "Entering SRR work (tgt %p)\n", - tgt); - -restart: - spin_lock_irqsave(&tgt->srr_lock, flags); - list_for_each_entry(sctio, &tgt->srr_ctio_list, srr_list_entry) { - struct qla_tgt_srr_imm *imm, *i, *ti; - struct qla_tgt_cmd *cmd; - struct se_cmd *se_cmd; - - imm = NULL; - list_for_each_entry_safe(i, ti, &tgt->srr_imm_list, - srr_list_entry) { - if (i->srr_id == sctio->srr_id) { - list_del(&i->srr_list_entry); - if (imm) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf068, - "qla_target(%d): There must be " - "only one IMM SRR per CTIO SRR " - "(IMM SRR %p, id %d, CTIO %p\n", - vha->vp_idx, i, i->srr_id, sctio); - qlt_reject_free_srr_imm(tgt->vha, i, 0); - } else - imm = i; - } - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02a, - "IMM SRR %p, CTIO SRR %p (id %d)\n", imm, sctio, - sctio->srr_id); - - if (imm == NULL) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02b, - "Not found matching IMM for SRR CTIO (id %d)\n", - sctio->srr_id); - continue; - } else - list_del(&sctio->srr_list_entry); - - spin_unlock_irqrestore(&tgt->srr_lock, flags); - - cmd = sctio->cmd; - /* - * Reset qla_tgt_cmd SRR values and SGL pointer+count to follow - * tcm_qla2xxx_write_pending() and tcm_qla2xxx_queue_data_in() - * logic.. - */ - cmd->offset = 0; - if (cmd->free_sg) { - kfree(cmd->sg); - cmd->sg = NULL; - cmd->free_sg = 0; - } - se_cmd = &cmd->se_cmd; - - cmd->sg_cnt = se_cmd->t_data_nents; - cmd->sg = se_cmd->t_data_sg; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, - "SRR cmd %p (se_cmd %p, tag %d, op %x), " - "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, - se_cmd->t_task_cdb[0], cmd->sg_cnt, cmd->offset); - - qlt_handle_srr(vha, sctio, imm); - - kfree(imm); - kfree(sctio); - goto restart; - } - spin_unlock_irqrestore(&tgt->srr_lock, flags); -} - -/* ha->hardware_lock supposed to be held on entry */ -static void qlt_prepare_srr_imm(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *iocb) -{ - struct qla_tgt_srr_imm *imm; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - struct qla_tgt_srr_ctio *sctio; - - tgt->imm_srr_id++; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02d, "qla_target(%d): SRR received\n", - vha->vp_idx); - - imm = kzalloc(sizeof(*imm), GFP_ATOMIC); - if (imm != NULL) { - memcpy(&imm->imm_ntfy, iocb, sizeof(imm->imm_ntfy)); - - /* IRQ is already OFF */ - spin_lock(&tgt->srr_lock); - imm->srr_id = tgt->imm_srr_id; - list_add_tail(&imm->srr_list_entry, - &tgt->srr_imm_list); - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02e, - "IMM NTFY SRR %p added (id %d, ui %x)\n", - imm, imm->srr_id, iocb->u.isp24.srr_ui); - if (tgt->imm_srr_id == tgt->ctio_srr_id) { - int found = 0; - list_for_each_entry(sctio, &tgt->srr_ctio_list, - srr_list_entry) { - if (sctio->srr_id == imm->srr_id) { - found = 1; - break; - } - } - if (found) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02f, "%s", - "Scheduling srr work\n"); - schedule_work(&tgt->srr_work); - } else { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf030, - "qla_target(%d): imm_srr_id " - "== ctio_srr_id (%d), but there is no " - "corresponding SRR CTIO, deleting IMM " - "SRR %p\n", vha->vp_idx, tgt->ctio_srr_id, - imm); - list_del(&imm->srr_list_entry); - - kfree(imm); - - spin_unlock(&tgt->srr_lock); - goto out_reject; - } - } - spin_unlock(&tgt->srr_lock); - } else { - struct qla_tgt_srr_ctio *ts; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf069, - "qla_target(%d): Unable to allocate SRR IMM " - "entry, SRR request will be rejected\n", vha->vp_idx); - - /* IRQ is already OFF */ - spin_lock(&tgt->srr_lock); - list_for_each_entry_safe(sctio, ts, &tgt->srr_ctio_list, - srr_list_entry) { - if (sctio->srr_id == tgt->imm_srr_id) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf031, - "CTIO SRR %p deleted (id %d)\n", - sctio, sctio->srr_id); - list_del(&sctio->srr_list_entry); - qlt_send_term_exchange(vha, sctio->cmd, - &sctio->cmd->atio, 1); - kfree(sctio); - } - } - spin_unlock(&tgt->srr_lock); - goto out_reject; - } - - return; - -out_reject: - qlt_send_notify_ack(vha, iocb, 0, 0, 0, - NOTIFY_ACK_SRR_FLAGS_REJECT, - NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, - NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -static void qlt_handle_imm_notify(struct scsi_qla_host *vha, - struct imm_ntfy_from_isp *iocb) -{ - struct qla_hw_data *ha = vha->hw; - uint32_t add_flags = 0; - int send_notify_ack = 1; - uint16_t status; - - status = le16_to_cpu(iocb->u.isp2x.status); - switch (status) { - case IMM_NTFY_LIP_RESET: - { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf032, - "qla_target(%d): LIP reset (loop %#x), subcode %x\n", - vha->vp_idx, le16_to_cpu(iocb->u.isp24.nport_handle), - iocb->u.isp24.status_subcode); - - if (qlt_reset(vha, iocb, QLA_TGT_ABORT_ALL) == 0) - send_notify_ack = 0; - break; - } - - case IMM_NTFY_LIP_LINK_REINIT: - { - struct qla_tgt *tgt = ha->tgt.qla_tgt; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, - "qla_target(%d): LINK REINIT (loop %#x, " - "subcode %x)\n", vha->vp_idx, - le16_to_cpu(iocb->u.isp24.nport_handle), - iocb->u.isp24.status_subcode); - if (tgt->link_reinit_iocb_pending) { - qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, - 0, 0, 0, 0, 0, 0); - } - memcpy(&tgt->link_reinit_iocb, iocb, sizeof(*iocb)); - tgt->link_reinit_iocb_pending = 1; - /* - * QLogic requires to wait after LINK REINIT for possible - * PDISC or ADISC ELS commands - */ - send_notify_ack = 0; - break; - } - - case IMM_NTFY_PORT_LOGOUT: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf034, - "qla_target(%d): Port logout (loop " - "%#x, subcode %x)\n", vha->vp_idx, - le16_to_cpu(iocb->u.isp24.nport_handle), - iocb->u.isp24.status_subcode); - - if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS) == 0) - send_notify_ack = 0; - /* The sessions will be cleared in the callback, if needed */ - break; - - case IMM_NTFY_GLBL_TPRLO: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf035, - "qla_target(%d): Global TPRLO (%x)\n", vha->vp_idx, status); - if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS) == 0) - send_notify_ack = 0; - /* The sessions will be cleared in the callback, if needed */ - break; - - case IMM_NTFY_PORT_CONFIG: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf036, - "qla_target(%d): Port config changed (%x)\n", vha->vp_idx, - status); - if (qlt_reset(vha, iocb, QLA_TGT_ABORT_ALL) == 0) - send_notify_ack = 0; - /* The sessions will be cleared in the callback, if needed */ - break; - - case IMM_NTFY_GLBL_LOGO: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06a, - "qla_target(%d): Link failure detected\n", - vha->vp_idx); - /* I_T nexus loss */ - if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS) == 0) - send_notify_ack = 0; - break; - - case IMM_NTFY_IOCB_OVERFLOW: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06b, - "qla_target(%d): Cannot provide requested " - "capability (IOCB overflowed the immediate notify " - "resource count)\n", vha->vp_idx); - break; - - case IMM_NTFY_ABORT_TASK: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf037, - "qla_target(%d): Abort Task (S %08x I %#x -> " - "L %#x)\n", vha->vp_idx, - le16_to_cpu(iocb->u.isp2x.seq_id), - GET_TARGET_ID(ha, (struct atio_from_isp *)iocb), - le16_to_cpu(iocb->u.isp2x.lun)); - if (qlt_abort_task(vha, iocb) == 0) - send_notify_ack = 0; - break; - - case IMM_NTFY_RESOURCE: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06c, - "qla_target(%d): Out of resources, host %ld\n", - vha->vp_idx, vha->host_no); - break; - - case IMM_NTFY_MSG_RX: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf038, - "qla_target(%d): Immediate notify task %x\n", - vha->vp_idx, iocb->u.isp2x.task_flags); - if (qlt_handle_task_mgmt(vha, iocb) == 0) - send_notify_ack = 0; - break; - - case IMM_NTFY_ELS: - if (qlt_24xx_handle_els(vha, iocb) == 0) - send_notify_ack = 0; - break; - - case IMM_NTFY_SRR: - qlt_prepare_srr_imm(vha, iocb); - send_notify_ack = 0; - break; - - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06d, - "qla_target(%d): Received unknown immediate " - "notify status %x\n", vha->vp_idx, status); - break; - } - - if (send_notify_ack) - qlt_send_notify_ack(vha, iocb, add_flags, 0, 0, 0, 0, 0); -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - * This function sends busy to ISP 2xxx or 24xx. - */ -static void qlt_send_busy(struct scsi_qla_host *vha, - struct atio_from_isp *atio, uint16_t status) -{ - struct ctio7_to_24xx *ctio24; - struct qla_hw_data *ha = vha->hw; - request_t *pkt; - struct qla_tgt_sess *sess = NULL; - - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - atio->u.isp24.fcp_hdr.s_id); - if (!sess) { - qlt_send_term_exchange(vha, NULL, atio, 1); - return; - } - /* Sending marker isn't necessary, since we called from ISR */ - - pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); - if (!pkt) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06e, - "qla_target(%d): %s failed: unable to allocate " - "request packet", vha->vp_idx, __func__); - return; - } - - pkt->entry_count = 1; - pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; - - ctio24 = (struct ctio7_to_24xx *)pkt; - ctio24->entry_type = CTIO_TYPE7; - ctio24->nport_handle = sess->loop_id; - ctio24->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); - ctio24->vp_index = vha->vp_idx; - ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; - ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; - ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; - ctio24->exchange_addr = atio->u.isp24.exchange_addr; - ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | - __constant_cpu_to_le16( - CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS | - CTIO7_FLAGS_DONT_RET_CTIO); - /* - * CTIO from fw w/o se_cmd doesn't provide enough info to retry it, - * if the explicit conformation is used. - */ - ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); - ctio24->u.status1.scsi_status = cpu_to_le16(status); - ctio24->u.status1.residual = get_unaligned((uint32_t *) - &atio->u.isp24.fcp_cmnd.add_cdb[ - atio->u.isp24.fcp_cmnd.add_cdb_len]); - if (ctio24->u.status1.residual != 0) - ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER; - - qla2x00_start_iocbs(vha, vha->req); -} - -/* ha->hardware_lock supposed to be held on entry */ -/* called via callback from qla2xxx */ -static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, - struct atio_from_isp *atio) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - int rc; - - if (unlikely(tgt == NULL)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf039, - "ATIO pkt, but no tgt (ha %p)", ha); - return; - } - ql_dbg(ql_dbg_tgt, vha, 0xe02c, - "qla_target(%d): ATIO pkt %p: type %02x count %02x", - vha->vp_idx, atio, atio->u.raw.entry_type, - atio->u.raw.entry_count); - /* - * In tgt_stop mode we also should allow all requests to pass. - * Otherwise, some commands can stuck. - */ - - tgt->irq_cmd_count++; - - switch (atio->u.raw.entry_type) { - case ATIO_TYPE7: - ql_dbg(ql_dbg_tgt, vha, 0xe02d, - "ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, " - "add_cdb_len %d, data_length %04x, s_id %x:%x:%x\n", - vha->vp_idx, atio->u.isp24.fcp_cmnd.lun, - atio->u.isp24.fcp_cmnd.rddata, - atio->u.isp24.fcp_cmnd.wrdata, - atio->u.isp24.fcp_cmnd.add_cdb_len, - be32_to_cpu(get_unaligned((uint32_t *) - &atio->u.isp24.fcp_cmnd.add_cdb[ - atio->u.isp24.fcp_cmnd.add_cdb_len])), - atio->u.isp24.fcp_hdr.s_id[0], - atio->u.isp24.fcp_hdr.s_id[1], - atio->u.isp24.fcp_hdr.s_id[2]); - - if (unlikely(atio->u.isp24.exchange_addr == - ATIO_EXCHANGE_ADDRESS_UNKNOWN)) { - ql_dbg(ql_dbg_tgt, vha, 0xe058, - "qla_target(%d): ATIO_TYPE7 " - "received with UNKNOWN exchange address, " - "sending QUEUE_FULL\n", vha->vp_idx); - qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL); - break; - } - if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) - rc = qlt_handle_cmd_for_atio(vha, atio); - else - rc = qlt_handle_task_mgmt(vha, atio); - if (unlikely(rc != 0)) { - if (rc == -ESRCH) { -#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ - qlt_send_busy(vha, atio, SAM_STAT_BUSY); -#else - qlt_send_term_exchange(vha, NULL, atio, 1); -#endif - } else { - if (tgt->tgt_stop) { - ql_dbg(ql_dbg_tgt, vha, 0xe059, - "qla_target: Unable to send " - "command to target for req, " - "ignoring.\n"); - } else { - ql_dbg(ql_dbg_tgt, vha, 0xe05a, - "qla_target(%d): Unable to send " - "command to target, sending BUSY " - "status.\n", vha->vp_idx); - qlt_send_busy(vha, atio, SAM_STAT_BUSY); - } - } - } - break; - - case IMMED_NOTIFY_TYPE: - { - if (unlikely(atio->u.isp2x.entry_status != 0)) { - ql_dbg(ql_dbg_tgt, vha, 0xe05b, - "qla_target(%d): Received ATIO packet %x " - "with error status %x\n", vha->vp_idx, - atio->u.raw.entry_type, - atio->u.isp2x.entry_status); - break; - } - ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO"); - qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio); - break; - } - - default: - ql_dbg(ql_dbg_tgt, vha, 0xe05c, - "qla_target(%d): Received unknown ATIO atio " - "type %x\n", vha->vp_idx, atio->u.raw.entry_type); - break; - } - - tgt->irq_cmd_count--; -} - -/* ha->hardware_lock supposed to be held on entry */ -/* called via callback from qla2xxx */ -static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - - if (unlikely(tgt == NULL)) { - ql_dbg(ql_dbg_tgt, vha, 0xe05d, - "qla_target(%d): Response pkt %x received, but no " - "tgt (ha %p)\n", vha->vp_idx, pkt->entry_type, ha); - return; - } - - ql_dbg(ql_dbg_tgt, vha, 0xe02f, - "qla_target(%d): response pkt %p: T %02x C %02x S %02x " - "handle %#x\n", vha->vp_idx, pkt, pkt->entry_type, - pkt->entry_count, pkt->entry_status, pkt->handle); - - /* - * In tgt_stop mode we also should allow all requests to pass. - * Otherwise, some commands can stuck. - */ - - tgt->irq_cmd_count++; - - switch (pkt->entry_type) { - case CTIO_TYPE7: - { - struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; - ql_dbg(ql_dbg_tgt, vha, 0xe030, "CTIO_TYPE7: instance %d\n", - vha->vp_idx); - qlt_do_ctio_completion(vha, entry->handle, - le16_to_cpu(entry->status)|(pkt->entry_status << 16), - entry); - break; - } - - case ACCEPT_TGT_IO_TYPE: - { - struct atio_from_isp *atio = (struct atio_from_isp *)pkt; - int rc; - ql_dbg(ql_dbg_tgt, vha, 0xe031, - "ACCEPT_TGT_IO instance %d status %04x " - "lun %04x read/write %d data_length %04x " - "target_id %02x rx_id %04x\n ", vha->vp_idx, - le16_to_cpu(atio->u.isp2x.status), - le16_to_cpu(atio->u.isp2x.lun), - atio->u.isp2x.execution_codes, - le32_to_cpu(atio->u.isp2x.data_length), GET_TARGET_ID(ha, - atio), atio->u.isp2x.rx_id); - if (atio->u.isp2x.status != - __constant_cpu_to_le16(ATIO_CDB_VALID)) { - ql_dbg(ql_dbg_tgt, vha, 0xe05e, - "qla_target(%d): ATIO with error " - "status %x received\n", vha->vp_idx, - le16_to_cpu(atio->u.isp2x.status)); - break; - } - ql_dbg(ql_dbg_tgt, vha, 0xe032, - "FCP CDB: 0x%02x, sizeof(cdb): %lu", - atio->u.isp2x.cdb[0], (unsigned long - int)sizeof(atio->u.isp2x.cdb)); - - rc = qlt_handle_cmd_for_atio(vha, atio); - if (unlikely(rc != 0)) { - if (rc == -ESRCH) { -#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ - qlt_send_busy(vha, atio, 0); -#else - qlt_send_term_exchange(vha, NULL, atio, 1); -#endif - } else { - if (tgt->tgt_stop) { - ql_dbg(ql_dbg_tgt, vha, 0xe05f, - "qla_target: Unable to send " - "command to target, sending TERM " - "EXCHANGE for rsp\n"); - qlt_send_term_exchange(vha, NULL, - atio, 1); - } else { - ql_dbg(ql_dbg_tgt, vha, 0xe060, - "qla_target(%d): Unable to send " - "command to target, sending BUSY " - "status\n", vha->vp_idx); - qlt_send_busy(vha, atio, 0); - } - } - } - } - break; - - case CONTINUE_TGT_IO_TYPE: - { - struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; - ql_dbg(ql_dbg_tgt, vha, 0xe033, - "CONTINUE_TGT_IO: instance %d\n", vha->vp_idx); - qlt_do_ctio_completion(vha, entry->handle, - le16_to_cpu(entry->status)|(pkt->entry_status << 16), - entry); - break; - } - - case CTIO_A64_TYPE: - { - struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; - ql_dbg(ql_dbg_tgt, vha, 0xe034, "CTIO_A64: instance %d\n", - vha->vp_idx); - qlt_do_ctio_completion(vha, entry->handle, - le16_to_cpu(entry->status)|(pkt->entry_status << 16), - entry); - break; - } - - case IMMED_NOTIFY_TYPE: - ql_dbg(ql_dbg_tgt, vha, 0xe035, "%s", "IMMED_NOTIFY\n"); - qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)pkt); - break; - - case NOTIFY_ACK_TYPE: - if (tgt->notify_ack_expected > 0) { - struct nack_to_isp *entry = (struct nack_to_isp *)pkt; - ql_dbg(ql_dbg_tgt, vha, 0xe036, - "NOTIFY_ACK seq %08x status %x\n", - le16_to_cpu(entry->u.isp2x.seq_id), - le16_to_cpu(entry->u.isp2x.status)); - tgt->notify_ack_expected--; - if (entry->u.isp2x.status != - __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) { - ql_dbg(ql_dbg_tgt, vha, 0xe061, - "qla_target(%d): NOTIFY_ACK " - "failed %x\n", vha->vp_idx, - le16_to_cpu(entry->u.isp2x.status)); - } - } else { - ql_dbg(ql_dbg_tgt, vha, 0xe062, - "qla_target(%d): Unexpected NOTIFY_ACK received\n", - vha->vp_idx); - } - break; - - case ABTS_RECV_24XX: - ql_dbg(ql_dbg_tgt, vha, 0xe037, - "ABTS_RECV_24XX: instance %d\n", vha->vp_idx); - qlt_24xx_handle_abts(vha, (struct abts_recv_from_24xx *)pkt); - break; - - case ABTS_RESP_24XX: - if (tgt->abts_resp_expected > 0) { - struct abts_resp_from_24xx_fw *entry = - (struct abts_resp_from_24xx_fw *)pkt; - ql_dbg(ql_dbg_tgt, vha, 0xe038, - "ABTS_RESP_24XX: compl_status %x\n", - entry->compl_status); - tgt->abts_resp_expected--; - if (le16_to_cpu(entry->compl_status) != - ABTS_RESP_COMPL_SUCCESS) { - if ((entry->error_subcode1 == 0x1E) && - (entry->error_subcode2 == 0)) { - /* - * We've got a race here: aborted - * exchange not terminated, i.e. - * response for the aborted command was - * sent between the abort request was - * received and processed. - * Unfortunately, the firmware has a - * silly requirement that all aborted - * exchanges must be explicitely - * terminated, otherwise it refuses to - * send responses for the abort - * requests. So, we have to - * (re)terminate the exchange and retry - * the abort response. - */ - qlt_24xx_retry_term_exchange(vha, - entry); - } else - ql_dbg(ql_dbg_tgt, vha, 0xe063, - "qla_target(%d): ABTS_RESP_24XX " - "failed %x (subcode %x:%x)", - vha->vp_idx, entry->compl_status, - entry->error_subcode1, - entry->error_subcode2); - } - } else { - ql_dbg(ql_dbg_tgt, vha, 0xe064, - "qla_target(%d): Unexpected ABTS_RESP_24XX " - "received\n", vha->vp_idx); - } - break; - - default: - ql_dbg(ql_dbg_tgt, vha, 0xe065, - "qla_target(%d): Received unknown response pkt " - "type %x\n", vha->vp_idx, pkt->entry_type); - break; - } - - tgt->irq_cmd_count--; -} - -/* - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire - */ -void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, - uint16_t *mailbox) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - int reason_code; - - ql_dbg(ql_dbg_tgt, vha, 0xe039, - "scsi(%ld): ha state %d init_done %d oper_mode %d topo %d\n", - vha->host_no, atomic_read(&vha->loop_state), vha->flags.init_done, - ha->operating_mode, ha->current_topology); - - if (!ha->tgt.tgt_ops) - return; - - if (unlikely(tgt == NULL)) { - ql_dbg(ql_dbg_tgt, vha, 0xe03a, - "ASYNC EVENT %#x, but no tgt (ha %p)\n", code, ha); - return; - } - - if (((code == MBA_POINT_TO_POINT) || (code == MBA_CHG_IN_CONNECTION)) && - IS_QLA2100(ha)) - return; - /* - * In tgt_stop mode we also should allow all requests to pass. - * Otherwise, some commands can stuck. - */ - - tgt->irq_cmd_count++; - - switch (code) { - case MBA_RESET: /* Reset */ - case MBA_SYSTEM_ERR: /* System Error */ - case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ - case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03a, - "qla_target(%d): System error async event %#x " - "occured", vha->vp_idx, code); - break; - case MBA_WAKEUP_THRES: /* Request Queue Wake-up. */ - set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - break; - - case MBA_LOOP_UP: - { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03b, - "qla_target(%d): Async LOOP_UP occured " - "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); - if (tgt->link_reinit_iocb_pending) { - qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb, - 0, 0, 0, 0, 0, 0); - tgt->link_reinit_iocb_pending = 0; - } - break; - } - - case MBA_LIP_OCCURRED: - case MBA_LOOP_DOWN: - case MBA_LIP_RESET: - case MBA_RSCN_UPDATE: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03c, - "qla_target(%d): Async event %#x occured " - "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); - break; - - case MBA_PORT_UPDATE: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03d, - "qla_target(%d): Port update async event %#x " - "occured: updating the ports database (m[1]=%x, m[2]=%x, " - "m[3]=%x, m[4]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); - reason_code = le16_to_cpu(mailbox[2]); - if (reason_code == 0x4) - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03e, - "Async MB 2: Got PLOGI Complete\n"); - else if (reason_code == 0x7) - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03f, - "Async MB 2: Port Logged Out\n"); - break; - - default: - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040, - "qla_target(%d): Async event %#x occured: " - "ignore (m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, - code, le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); - break; - } - - tgt->irq_cmd_count--; -} - -static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, - uint16_t loop_id) -{ - fc_port_t *fcport; - int rc; - - fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); - if (!fcport) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f, - "qla_target(%d): Allocation of tmp FC port failed", - vha->vp_idx); - return NULL; - } - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf041, "loop_id %d", loop_id); - - fcport->loop_id = loop_id; - - rc = qla2x00_get_port_database(vha, fcport, 0); - if (rc != QLA_SUCCESS) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070, - "qla_target(%d): Failed to retrieve fcport " - "information -- get_port_database() returned %x " - "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); - kfree(fcport); - return NULL; - } - - return fcport; -} - -/* Must be called under tgt_mutex */ -static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha, - uint8_t *s_id) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess = NULL; - fc_port_t *fcport = NULL; - int rc, global_resets; - uint16_t loop_id = 0; - -retry: - global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); - - rc = qla24xx_get_loop_id(vha, s_id, &loop_id); - if (rc != 0) { - if ((s_id[0] == 0xFF) && - (s_id[1] == 0xFC)) { - /* - * This is Domain Controller, so it should be - * OK to drop SCSI commands from it. - */ - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf042, - "Unable to find initiator with S_ID %x:%x:%x", - s_id[0], s_id[1], s_id[2]); - } else - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf071, - "qla_target(%d): Unable to find " - "initiator with S_ID %x:%x:%x", - vha->vp_idx, s_id[0], s_id[1], - s_id[2]); - return NULL; - } - - fcport = qlt_get_port_database(vha, loop_id); - if (!fcport) - return NULL; - - if (global_resets != - atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf043, - "qla_target(%d): global reset during session discovery " - "(counter was %d, new %d), retrying", vha->vp_idx, - global_resets, - atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); - goto retry; - } - - sess = qlt_create_sess(vha, fcport, true); - - kfree(fcport); - return sess; -} - -static void qlt_abort_work(struct qla_tgt *tgt, - struct qla_tgt_sess_work_param *prm) -{ - struct scsi_qla_host *vha = tgt->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess = NULL; - unsigned long flags; - uint32_t be_s_id; - uint8_t s_id[3]; - int rc; - - spin_lock_irqsave(&ha->hardware_lock, flags); - - if (tgt->tgt_stop) - goto out_term; - - s_id[0] = prm->abts.fcp_hdr_le.s_id[2]; - s_id[1] = prm->abts.fcp_hdr_le.s_id[1]; - s_id[2] = prm->abts.fcp_hdr_le.s_id[0]; - - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, - (unsigned char *)&be_s_id); - if (!sess) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - mutex_lock(&ha->tgt.tgt_mutex); - sess = qlt_make_local_sess(vha, s_id); - /* sess has got an extra creation ref */ - mutex_unlock(&ha->tgt.tgt_mutex); - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (!sess) - goto out_term; - } else { - kref_get(&sess->se_sess->sess_kref); - } - - if (tgt->tgt_stop) - goto out_term; - - rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); - if (rc != 0) - goto out_term; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - ha->tgt.tgt_ops->put_sess(sess); - return; - -out_term: - qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (sess) - ha->tgt.tgt_ops->put_sess(sess); -} - -static void qlt_tmr_work(struct qla_tgt *tgt, - struct qla_tgt_sess_work_param *prm) -{ - struct atio_from_isp *a = &prm->tm_iocb2; - struct scsi_qla_host *vha = tgt->vha; - struct qla_hw_data *ha = vha->hw; - struct qla_tgt_sess *sess = NULL; - unsigned long flags; - uint8_t *s_id = NULL; /* to hide compiler warnings */ - int rc; - uint32_t lun, unpacked_lun; - int lun_size, fn; - void *iocb; - - spin_lock_irqsave(&ha->hardware_lock, flags); - - if (tgt->tgt_stop) - goto out_term; - - s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); - if (!sess) { - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - mutex_lock(&ha->tgt.tgt_mutex); - sess = qlt_make_local_sess(vha, s_id); - /* sess has got an extra creation ref */ - mutex_unlock(&ha->tgt.tgt_mutex); - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (!sess) - goto out_term; - } else { - kref_get(&sess->se_sess->sess_kref); - } - - iocb = a; - lun = a->u.isp24.fcp_cmnd.lun; - lun_size = sizeof(lun); - fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); - - rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); - if (rc != 0) - goto out_term; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - ha->tgt.tgt_ops->put_sess(sess); - return; - -out_term: - qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (sess) - ha->tgt.tgt_ops->put_sess(sess); -} - -static void qlt_sess_work_fn(struct work_struct *work) -{ - struct qla_tgt *tgt = container_of(work, struct qla_tgt, sess_work); - struct scsi_qla_host *vha = tgt->vha; - unsigned long flags; - - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf000, "Sess work (tgt %p)", tgt); - - spin_lock_irqsave(&tgt->sess_work_lock, flags); - while (!list_empty(&tgt->sess_works_list)) { - struct qla_tgt_sess_work_param *prm = list_entry( - tgt->sess_works_list.next, typeof(*prm), - sess_works_list_entry); - - /* - * This work can be scheduled on several CPUs at time, so we - * must delete the entry to eliminate double processing - */ - list_del(&prm->sess_works_list_entry); - - spin_unlock_irqrestore(&tgt->sess_work_lock, flags); - - switch (prm->type) { - case QLA_TGT_SESS_WORK_ABORT: - qlt_abort_work(tgt, prm); - break; - case QLA_TGT_SESS_WORK_TM: - qlt_tmr_work(tgt, prm); - break; - default: - BUG_ON(1); - break; - } - - spin_lock_irqsave(&tgt->sess_work_lock, flags); - - kfree(prm); - } - spin_unlock_irqrestore(&tgt->sess_work_lock, flags); -} - -/* Must be called under tgt_host_action_mutex */ -int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) -{ - struct qla_tgt *tgt; - - if (!QLA_TGT_MODE_ENABLED()) - return 0; - - ql_dbg(ql_dbg_tgt, base_vha, 0xe03b, - "Registering target for host %ld(%p)", base_vha->host_no, ha); - - BUG_ON((ha->tgt.qla_tgt != NULL) || (ha->tgt.tgt_ops != NULL)); - - tgt = kzalloc(sizeof(struct qla_tgt), GFP_KERNEL); - if (!tgt) { - ql_dbg(ql_dbg_tgt, base_vha, 0xe066, - "Unable to allocate struct qla_tgt\n"); - return -ENOMEM; - } - - if (!(base_vha->host->hostt->supported_mode & MODE_TARGET)) - base_vha->host->hostt->supported_mode |= MODE_TARGET; - - tgt->ha = ha; - tgt->vha = base_vha; - init_waitqueue_head(&tgt->waitQ); - INIT_LIST_HEAD(&tgt->sess_list); - INIT_LIST_HEAD(&tgt->del_sess_list); - INIT_DELAYED_WORK(&tgt->sess_del_work, - (void (*)(struct work_struct *))qlt_del_sess_work_fn); - spin_lock_init(&tgt->sess_work_lock); - INIT_WORK(&tgt->sess_work, qlt_sess_work_fn); - INIT_LIST_HEAD(&tgt->sess_works_list); - spin_lock_init(&tgt->srr_lock); - INIT_LIST_HEAD(&tgt->srr_ctio_list); - INIT_LIST_HEAD(&tgt->srr_imm_list); - INIT_WORK(&tgt->srr_work, qlt_handle_srr_work); - atomic_set(&tgt->tgt_global_resets_count, 0); - - ha->tgt.qla_tgt = tgt; - - ql_dbg(ql_dbg_tgt, base_vha, 0xe067, - "qla_target(%d): using 64 Bit PCI addressing", - base_vha->vp_idx); - tgt->tgt_enable_64bit_addr = 1; - /* 3 is reserved */ - tgt->sg_tablesize = QLA_TGT_MAX_SG_24XX(base_vha->req->length - 3); - tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; - tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; - - mutex_lock(&qla_tgt_mutex); - list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); - mutex_unlock(&qla_tgt_mutex); - - return 0; -} - -/* Must be called under tgt_host_action_mutex */ -int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) -{ - if (!ha->tgt.qla_tgt) - return 0; - - mutex_lock(&qla_tgt_mutex); - list_del(&ha->tgt.qla_tgt->tgt_list_entry); - mutex_unlock(&qla_tgt_mutex); - - ql_dbg(ql_dbg_tgt, vha, 0xe03c, "Unregistering target for host %ld(%p)", - vha->host_no, ha); - qlt_release(ha->tgt.qla_tgt); - - return 0; -} - -static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, - unsigned char *b) -{ - int i; - - pr_debug("qla2xxx HW vha->node_name: "); - for (i = 0; i < WWN_SIZE; i++) - pr_debug("%02x ", vha->node_name[i]); - pr_debug("\n"); - pr_debug("qla2xxx HW vha->port_name: "); - for (i = 0; i < WWN_SIZE; i++) - pr_debug("%02x ", vha->port_name[i]); - pr_debug("\n"); - - pr_debug("qla2xxx passed configfs WWPN: "); - put_unaligned_be64(wwpn, b); - for (i = 0; i < WWN_SIZE; i++) - pr_debug("%02x ", b[i]); - pr_debug("\n"); -} - -/** - * qla_tgt_lport_register - register lport with external module - * - * @qla_tgt_ops: Pointer for tcm_qla2xxx qla_tgt_ops - * @wwpn: Passwd FC target WWPN - * @callback: lport initialization callback for tcm_qla2xxx code - * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data - */ -int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn, - int (*callback)(struct scsi_qla_host *), void *target_lport_ptr) -{ - struct qla_tgt *tgt; - struct scsi_qla_host *vha; - struct qla_hw_data *ha; - struct Scsi_Host *host; - unsigned long flags; - int rc; - u8 b[WWN_SIZE]; - - mutex_lock(&qla_tgt_mutex); - list_for_each_entry(tgt, &qla_tgt_glist, tgt_list_entry) { - vha = tgt->vha; - ha = vha->hw; - - host = vha->host; - if (!host) - continue; - - if (ha->tgt.tgt_ops != NULL) - continue; - - if (!(host->hostt->supported_mode & MODE_TARGET)) - continue; - - spin_lock_irqsave(&ha->hardware_lock, flags); - if (host->active_mode & MODE_TARGET) { - pr_debug("MODE_TARGET already active on qla2xxx(%d)\n", - host->host_no); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - continue; - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (!scsi_host_get(host)) { - ql_dbg(ql_dbg_tgt, vha, 0xe068, - "Unable to scsi_host_get() for" - " qla2xxx scsi_host\n"); - continue; - } - qlt_lport_dump(vha, wwpn, b); - - if (memcmp(vha->port_name, b, WWN_SIZE)) { - scsi_host_put(host); - continue; - } - /* - * Setup passed parameters ahead of invoking callback - */ - ha->tgt.tgt_ops = qla_tgt_ops; - ha->tgt.target_lport_ptr = target_lport_ptr; - rc = (*callback)(vha); - if (rc != 0) { - ha->tgt.tgt_ops = NULL; - ha->tgt.target_lport_ptr = NULL; - } - mutex_unlock(&qla_tgt_mutex); - return rc; - } - mutex_unlock(&qla_tgt_mutex); - - return -ENODEV; -} -EXPORT_SYMBOL(qlt_lport_register); - -/** - * qla_tgt_lport_deregister - Degister lport - * - * @vha: Registered scsi_qla_host pointer - */ -void qlt_lport_deregister(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct Scsi_Host *sh = vha->host; - /* - * Clear the target_lport_ptr qla_target_template pointer in qla_hw_data - */ - ha->tgt.target_lport_ptr = NULL; - ha->tgt.tgt_ops = NULL; - /* - * Release the Scsi_Host reference for the underlying qla2xxx host - */ - scsi_host_put(sh); -} -EXPORT_SYMBOL(qlt_lport_deregister); - -/* Must be called under HW lock */ -void qlt_set_mode(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - - switch (ql2x_ini_mode) { - case QLA2XXX_INI_MODE_DISABLED: - case QLA2XXX_INI_MODE_EXCLUSIVE: - vha->host->active_mode = MODE_TARGET; - break; - case QLA2XXX_INI_MODE_ENABLED: - vha->host->active_mode |= MODE_TARGET; - break; - default: - break; - } - - if (ha->tgt.ini_mode_force_reverse) - qla_reverse_ini_mode(vha); -} - -/* Must be called under HW lock */ -void qlt_clear_mode(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - - switch (ql2x_ini_mode) { - case QLA2XXX_INI_MODE_DISABLED: - vha->host->active_mode = MODE_UNKNOWN; - break; - case QLA2XXX_INI_MODE_EXCLUSIVE: - vha->host->active_mode = MODE_INITIATOR; - break; - case QLA2XXX_INI_MODE_ENABLED: - vha->host->active_mode &= ~MODE_TARGET; - break; - default: - break; - } - - if (ha->tgt.ini_mode_force_reverse) - qla_reverse_ini_mode(vha); -} - -/* - * qla_tgt_enable_vha - NO LOCK HELD - * - * host_reset, bring up w/ Target Mode Enabled - */ -void -qlt_enable_vha(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - unsigned long flags; - - if (!tgt) { - ql_dbg(ql_dbg_tgt, vha, 0xe069, - "Unable to locate qla_tgt pointer from" - " struct qla_hw_data\n"); - dump_stack(); - return; - } - - spin_lock_irqsave(&ha->hardware_lock, flags); - tgt->tgt_stopped = 0; - qlt_set_mode(vha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - qla2xxx_wake_dpc(vha); - qla2x00_wait_for_hba_online(vha); -} -EXPORT_SYMBOL(qlt_enable_vha); - -/* - * qla_tgt_disable_vha - NO LOCK HELD - * - * Disable Target Mode and reset the adapter - */ -void -qlt_disable_vha(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct qla_tgt *tgt = ha->tgt.qla_tgt; - unsigned long flags; - - if (!tgt) { - ql_dbg(ql_dbg_tgt, vha, 0xe06a, - "Unable to locate qla_tgt pointer from" - " struct qla_hw_data\n"); - dump_stack(); - return; - } - - spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_clear_mode(vha); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - qla2xxx_wake_dpc(vha); - qla2x00_wait_for_hba_online(vha); -} - -/* - * Called from qla_init.c:qla24xx_vport_create() contex to setup - * the target mode specific struct scsi_qla_host and struct qla_hw_data - * members. - */ -void -qlt_vport_create(struct scsi_qla_host *vha, struct qla_hw_data *ha) -{ - if (!qla_tgt_mode_enabled(vha)) - return; - - mutex_init(&ha->tgt.tgt_mutex); - mutex_init(&ha->tgt.tgt_host_action_mutex); - - qlt_clear_mode(vha); - - /* - * NOTE: Currently the value is kept the same for <24xx and - * >=24xx ISPs. If it is necessary to change it, - * the check should be added for specific ISPs, - * assigning the value appropriately. - */ - ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; -} - -void -qlt_rff_id(struct scsi_qla_host *vha, struct ct_sns_req *ct_req) -{ - /* - * FC-4 Feature bit 0 indicates target functionality to the name server. - */ - if (qla_tgt_mode_enabled(vha)) { - if (qla_ini_mode_enabled(vha)) - ct_req->req.rff_id.fc4_feature = BIT_0 | BIT_1; - else - ct_req->req.rff_id.fc4_feature = BIT_0; - } else if (qla_ini_mode_enabled(vha)) { - ct_req->req.rff_id.fc4_feature = BIT_1; - } -} - -/* - * qlt_init_atio_q_entries() - Initializes ATIO queue entries. - * @ha: HA context - * - * Beginning of ATIO ring has initialization control block already built - * by nvram config routine. - * - * Returns 0 on success. - */ -void -qlt_init_atio_q_entries(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - uint16_t cnt; - struct atio_from_isp *pkt = (struct atio_from_isp *)ha->tgt.atio_ring; - - if (!qla_tgt_mode_enabled(vha)) - return; - - for (cnt = 0; cnt < ha->tgt.atio_q_length; cnt++) { - pkt->u.raw.signature = ATIO_PROCESSED; - pkt++; - } - -} - -/* - * qlt_24xx_process_atio_queue() - Process ATIO queue entries. - * @ha: SCSI driver HA context - */ -void -qlt_24xx_process_atio_queue(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - struct atio_from_isp *pkt; - int cnt, i; - - if (!vha->flags.online) - return; - - while (ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) { - pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; - cnt = pkt->u.raw.entry_count; - - qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt); - - for (i = 0; i < cnt; i++) { - ha->tgt.atio_ring_index++; - if (ha->tgt.atio_ring_index == ha->tgt.atio_q_length) { - ha->tgt.atio_ring_index = 0; - ha->tgt.atio_ring_ptr = ha->tgt.atio_ring; - } else - ha->tgt.atio_ring_ptr++; - - pkt->u.raw.signature = ATIO_PROCESSED; - pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; - } - wmb(); - } - - /* Adjust ring index */ - WRT_REG_DWORD(®->atio_q_out, ha->tgt.atio_ring_index); -} - -void -qlt_24xx_config_rings(struct scsi_qla_host *vha, device_reg_t __iomem *reg) -{ - struct qla_hw_data *ha = vha->hw; - -/* FIXME: atio_q in/out for ha->mqenable=1..? */ - if (ha->mqenable) { -#if 0 - WRT_REG_DWORD(®->isp25mq.atio_q_in, 0); - WRT_REG_DWORD(®->isp25mq.atio_q_out, 0); - RD_REG_DWORD(®->isp25mq.atio_q_out); -#endif - } else { - /* Setup APTIO registers for target mode */ - WRT_REG_DWORD(®->isp24.atio_q_in, 0); - WRT_REG_DWORD(®->isp24.atio_q_out, 0); - RD_REG_DWORD(®->isp24.atio_q_out); - } -} - -void -qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv) -{ - struct qla_hw_data *ha = vha->hw; - - if (qla_tgt_mode_enabled(vha)) { - if (!ha->tgt.saved_set) { - /* We save only once */ - ha->tgt.saved_exchange_count = nv->exchange_count; - ha->tgt.saved_firmware_options_1 = - nv->firmware_options_1; - ha->tgt.saved_firmware_options_2 = - nv->firmware_options_2; - ha->tgt.saved_firmware_options_3 = - nv->firmware_options_3; - ha->tgt.saved_set = 1; - } - - nv->exchange_count = __constant_cpu_to_le16(0xFFFF); - - /* Enable target mode */ - nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_4); - - /* Disable ini mode, if requested */ - if (!qla_ini_mode_enabled(vha)) - nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_5); - - /* Disable Full Login after LIP */ - nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13); - /* Enable initial LIP */ - nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_9); - /* Enable FC tapes support */ - nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); - /* Disable Full Login after LIP */ - nv->host_p &= __constant_cpu_to_le32(~BIT_10); - /* Enable target PRLI control */ - nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_14); - } else { - if (ha->tgt.saved_set) { - nv->exchange_count = ha->tgt.saved_exchange_count; - nv->firmware_options_1 = - ha->tgt.saved_firmware_options_1; - nv->firmware_options_2 = - ha->tgt.saved_firmware_options_2; - nv->firmware_options_3 = - ha->tgt.saved_firmware_options_3; - } - return; - } - - /* out-of-order frames reassembly */ - nv->firmware_options_3 |= BIT_6|BIT_9; - - if (ha->tgt.enable_class_2) { - if (vha->flags.init_done) - fc_host_supported_classes(vha->host) = - FC_COS_CLASS2 | FC_COS_CLASS3; - - nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_8); - } else { - if (vha->flags.init_done) - fc_host_supported_classes(vha->host) = FC_COS_CLASS3; - - nv->firmware_options_2 &= ~__constant_cpu_to_le32(BIT_8); - } -} - -void -qlt_24xx_config_nvram_stage2(struct scsi_qla_host *vha, - struct init_cb_24xx *icb) -{ - struct qla_hw_data *ha = vha->hw; - - if (ha->tgt.node_name_set) { - memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE); - icb->firmware_options_1 |= __constant_cpu_to_le32(BIT_14); - } -} - -int -qlt_24xx_process_response_error(struct scsi_qla_host *vha, - struct sts_entry_24xx *pkt) -{ - switch (pkt->entry_type) { - case ABTS_RECV_24XX: - case ABTS_RESP_24XX: - case CTIO_TYPE7: - case NOTIFY_ACK_TYPE: - return 1; - default: - return 0; - } -} - -void -qlt_modify_vp_config(struct scsi_qla_host *vha, - struct vp_config_entry_24xx *vpmod) -{ - if (qla_tgt_mode_enabled(vha)) - vpmod->options_idx1 &= ~BIT_5; - /* Disable ini mode, if requested */ - if (!qla_ini_mode_enabled(vha)) - vpmod->options_idx1 &= ~BIT_4; -} - -void -qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) -{ - if (!QLA_TGT_MODE_ENABLED()) - return; - - mutex_init(&ha->tgt.tgt_mutex); - mutex_init(&ha->tgt.tgt_host_action_mutex); - qlt_clear_mode(base_vha); -} - -int -qlt_mem_alloc(struct qla_hw_data *ha) -{ - if (!QLA_TGT_MODE_ENABLED()) - return 0; - - ha->tgt.tgt_vp_map = kzalloc(sizeof(struct qla_tgt_vp_map) * - MAX_MULTI_ID_FABRIC, GFP_KERNEL); - if (!ha->tgt.tgt_vp_map) - return -ENOMEM; - - ha->tgt.atio_ring = dma_alloc_coherent(&ha->pdev->dev, - (ha->tgt.atio_q_length + 1) * sizeof(struct atio_from_isp), - &ha->tgt.atio_dma, GFP_KERNEL); - if (!ha->tgt.atio_ring) { - kfree(ha->tgt.tgt_vp_map); - return -ENOMEM; - } - return 0; -} - -void -qlt_mem_free(struct qla_hw_data *ha) -{ - if (!QLA_TGT_MODE_ENABLED()) - return; - - if (ha->tgt.atio_ring) { - dma_free_coherent(&ha->pdev->dev, (ha->tgt.atio_q_length + 1) * - sizeof(struct atio_from_isp), ha->tgt.atio_ring, - ha->tgt.atio_dma); - } - kfree(ha->tgt.tgt_vp_map); -} - -/* vport_slock to be held by the caller */ -void -qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) -{ - if (!QLA_TGT_MODE_ENABLED()) - return; - - switch (cmd) { - case SET_VP_IDX: - vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; - break; - case SET_AL_PA: - vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx; - break; - case RESET_VP_IDX: - vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; - break; - case RESET_AL_PA: - vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0; - break; - } -} - -static int __init qlt_parse_ini_mode(void) -{ - if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0) - ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE; - else if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_DISABLED) == 0) - ql2x_ini_mode = QLA2XXX_INI_MODE_DISABLED; - else if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_ENABLED) == 0) - ql2x_ini_mode = QLA2XXX_INI_MODE_ENABLED; - else - return false; - - return true; -} - -int __init qlt_init(void) -{ - int ret; - - if (!qlt_parse_ini_mode()) { - ql_log(ql_log_fatal, NULL, 0xe06b, - "qlt_parse_ini_mode() failed\n"); - return -EINVAL; - } - - if (!QLA_TGT_MODE_ENABLED()) - return 0; - - qla_tgt_cmd_cachep = kmem_cache_create("qla_tgt_cmd_cachep", - sizeof(struct qla_tgt_cmd), __alignof__(struct qla_tgt_cmd), 0, - NULL); - if (!qla_tgt_cmd_cachep) { - ql_log(ql_log_fatal, NULL, 0xe06c, - "kmem_cache_create for qla_tgt_cmd_cachep failed\n"); - return -ENOMEM; - } - - qla_tgt_mgmt_cmd_cachep = kmem_cache_create("qla_tgt_mgmt_cmd_cachep", - sizeof(struct qla_tgt_mgmt_cmd), __alignof__(struct - qla_tgt_mgmt_cmd), 0, NULL); - if (!qla_tgt_mgmt_cmd_cachep) { - ql_log(ql_log_fatal, NULL, 0xe06d, - "kmem_cache_create for qla_tgt_mgmt_cmd_cachep failed\n"); - ret = -ENOMEM; - goto out; - } - - qla_tgt_mgmt_cmd_mempool = mempool_create(25, mempool_alloc_slab, - mempool_free_slab, qla_tgt_mgmt_cmd_cachep); - if (!qla_tgt_mgmt_cmd_mempool) { - ql_log(ql_log_fatal, NULL, 0xe06e, - "mempool_create for qla_tgt_mgmt_cmd_mempool failed\n"); - ret = -ENOMEM; - goto out_mgmt_cmd_cachep; - } - - qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0); - if (!qla_tgt_wq) { - ql_log(ql_log_fatal, NULL, 0xe06f, - "alloc_workqueue for qla_tgt_wq failed\n"); - ret = -ENOMEM; - goto out_cmd_mempool; - } - /* - * Return 1 to signal that initiator-mode is being disabled - */ - return (ql2x_ini_mode == QLA2XXX_INI_MODE_DISABLED) ? 1 : 0; - -out_cmd_mempool: - mempool_destroy(qla_tgt_mgmt_cmd_mempool); -out_mgmt_cmd_cachep: - kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep); -out: - kmem_cache_destroy(qla_tgt_cmd_cachep); - return ret; -} - -void qlt_exit(void) -{ - if (!QLA_TGT_MODE_ENABLED()) - return; - - destroy_workqueue(qla_tgt_wq); - mempool_destroy(qla_tgt_mgmt_cmd_mempool); - kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep); - kmem_cache_destroy(qla_tgt_cmd_cachep); -} diff --git a/trunk/drivers/scsi/qla2xxx/qla_target.h b/trunk/drivers/scsi/qla2xxx/qla_target.h deleted file mode 100644 index 9ec19bc2f0fe..000000000000 --- a/trunk/drivers/scsi/qla2xxx/qla_target.h +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * Copyright (C) 2004 - 2010 Vladislav Bolkhovitin - * Copyright (C) 2004 - 2005 Leonid Stoljar - * Copyright (C) 2006 Nathaniel Clark - * Copyright (C) 2007 - 2010 ID7 Ltd. - * - * Forward port and refactoring to modern qla2xxx and target/configfs - * - * Copyright (C) 2010-2011 Nicholas A. Bellinger - * - * Additional file for the target driver support. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -/* - * This is the global def file that is useful for including from the - * target portion. - */ - -#ifndef __QLA_TARGET_H -#define __QLA_TARGET_H - -#include "qla_def.h" - -/* - * Must be changed on any change in any initiator visible interfaces or - * data in the target add-on - */ -#define QLA2XXX_TARGET_MAGIC 269 - -/* - * Must be changed on any change in any target visible interfaces or - * data in the initiator - */ -#define QLA2XXX_INITIATOR_MAGIC 57222 - -#define QLA2XXX_INI_MODE_STR_EXCLUSIVE "exclusive" -#define QLA2XXX_INI_MODE_STR_DISABLED "disabled" -#define QLA2XXX_INI_MODE_STR_ENABLED "enabled" - -#define QLA2XXX_INI_MODE_EXCLUSIVE 0 -#define QLA2XXX_INI_MODE_DISABLED 1 -#define QLA2XXX_INI_MODE_ENABLED 2 - -#define QLA2XXX_COMMAND_COUNT_INIT 250 -#define QLA2XXX_IMMED_NOTIFY_COUNT_INIT 250 - -/* - * Used to mark which completion handles (for RIO Status's) are for CTIO's - * vs. regular (non-target) info. This is checked for in - * qla2x00_process_response_queue() to see if a handle coming back in a - * multi-complete should come to the tgt driver or be handled there by qla2xxx - */ -#define CTIO_COMPLETION_HANDLE_MARK BIT_29 -#if (CTIO_COMPLETION_HANDLE_MARK <= MAX_OUTSTANDING_COMMANDS) -#error "CTIO_COMPLETION_HANDLE_MARK not larger than MAX_OUTSTANDING_COMMANDS" -#endif -#define HANDLE_IS_CTIO_COMP(h) (h & CTIO_COMPLETION_HANDLE_MARK) - -/* Used to mark CTIO as intermediate */ -#define CTIO_INTERMEDIATE_HANDLE_MARK BIT_30 - -#ifndef OF_SS_MODE_0 -/* - * ISP target entries - Flags bit definitions. - */ -#define OF_SS_MODE_0 0 -#define OF_SS_MODE_1 1 -#define OF_SS_MODE_2 2 -#define OF_SS_MODE_3 3 - -#define OF_EXPL_CONF BIT_5 /* Explicit Confirmation Requested */ -#define OF_DATA_IN BIT_6 /* Data in to initiator */ - /* (data from target to initiator) */ -#define OF_DATA_OUT BIT_7 /* Data out from initiator */ - /* (data from initiator to target) */ -#define OF_NO_DATA (BIT_7 | BIT_6) -#define OF_INC_RC BIT_8 /* Increment command resource count */ -#define OF_FAST_POST BIT_9 /* Enable mailbox fast posting. */ -#define OF_CONF_REQ BIT_13 /* Confirmation Requested */ -#define OF_TERM_EXCH BIT_14 /* Terminate exchange */ -#define OF_SSTS BIT_15 /* Send SCSI status */ -#endif - -#ifndef QLA_TGT_DATASEGS_PER_CMD32 -#define QLA_TGT_DATASEGS_PER_CMD32 3 -#define QLA_TGT_DATASEGS_PER_CONT32 7 -#define QLA_TGT_MAX_SG32(ql) \ - (((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD32 + \ - QLA_TGT_DATASEGS_PER_CONT32*((ql) - 1)) : 0) - -#define QLA_TGT_DATASEGS_PER_CMD64 2 -#define QLA_TGT_DATASEGS_PER_CONT64 5 -#define QLA_TGT_MAX_SG64(ql) \ - (((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD64 + \ - QLA_TGT_DATASEGS_PER_CONT64*((ql) - 1)) : 0) -#endif - -#ifndef QLA_TGT_DATASEGS_PER_CMD_24XX -#define QLA_TGT_DATASEGS_PER_CMD_24XX 1 -#define QLA_TGT_DATASEGS_PER_CONT_24XX 5 -#define QLA_TGT_MAX_SG_24XX(ql) \ - (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ - QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) -#endif -#endif - -#define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ - ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ - : (uint16_t)(iocb)->u.isp2x.target.id.standard) - -#ifndef IMMED_NOTIFY_TYPE -#define IMMED_NOTIFY_TYPE 0x0D /* Immediate notify entry. */ -/* - * ISP queue - immediate notify entry structure definition. - * This is sent by the ISP to the Target driver. - * This IOCB would have report of events sent by the - * initiator, that needs to be handled by the target - * driver immediately. - */ -struct imm_ntfy_from_isp { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - union { - struct { - uint32_t sys_define_2; /* System defined. */ - target_id_t target; - uint16_t lun; - uint8_t target_id; - uint8_t reserved_1; - uint16_t status_modifier; - uint16_t status; - uint16_t task_flags; - uint16_t seq_id; - uint16_t srr_rx_id; - uint32_t srr_rel_offs; - uint16_t srr_ui; -#define SRR_IU_DATA_IN 0x1 -#define SRR_IU_DATA_OUT 0x5 -#define SRR_IU_STATUS 0x7 - uint16_t srr_ox_id; - uint8_t reserved_2[28]; - } isp2x; - struct { - uint32_t reserved; - uint16_t nport_handle; - uint16_t reserved_2; - uint16_t flags; -#define NOTIFY24XX_FLAGS_GLOBAL_TPRLO BIT_1 -#define NOTIFY24XX_FLAGS_PUREX_IOCB BIT_0 - uint16_t srr_rx_id; - uint16_t status; - uint8_t status_subcode; - uint8_t reserved_3; - uint32_t exchange_address; - uint32_t srr_rel_offs; - uint16_t srr_ui; - uint16_t srr_ox_id; - uint8_t reserved_4[19]; - uint8_t vp_index; - uint32_t reserved_5; - uint8_t port_id[3]; - uint8_t reserved_6; - } isp24; - } u; - uint16_t reserved_7; - uint16_t ox_id; -} __packed; -#endif - -#ifndef NOTIFY_ACK_TYPE -#define NOTIFY_ACK_TYPE 0x0E /* Notify acknowledge entry. */ -/* - * ISP queue - notify acknowledge entry structure definition. - * This is sent to the ISP from the target driver. - */ -struct nack_to_isp { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - union { - struct { - uint32_t sys_define_2; /* System defined. */ - target_id_t target; - uint8_t target_id; - uint8_t reserved_1; - uint16_t flags; - uint16_t resp_code; - uint16_t status; - uint16_t task_flags; - uint16_t seq_id; - uint16_t srr_rx_id; - uint32_t srr_rel_offs; - uint16_t srr_ui; - uint16_t srr_flags; - uint16_t srr_reject_code; - uint8_t srr_reject_vendor_uniq; - uint8_t srr_reject_code_expl; - uint8_t reserved_2[24]; - } isp2x; - struct { - uint32_t handle; - uint16_t nport_handle; - uint16_t reserved_1; - uint16_t flags; - uint16_t srr_rx_id; - uint16_t status; - uint8_t status_subcode; - uint8_t reserved_3; - uint32_t exchange_address; - uint32_t srr_rel_offs; - uint16_t srr_ui; - uint16_t srr_flags; - uint8_t reserved_4[19]; - uint8_t vp_index; - uint8_t srr_reject_vendor_uniq; - uint8_t srr_reject_code_expl; - uint8_t srr_reject_code; - uint8_t reserved_5[5]; - } isp24; - } u; - uint8_t reserved[2]; - uint16_t ox_id; -} __packed; -#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0 -#define NOTIFY_ACK_SRR_FLAGS_REJECT 1 - -#define NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM 0x9 - -#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL 0 -#define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_UNABLE_TO_SUPPLY_DATA 0x2a - -#define NOTIFY_ACK_SUCCESS 0x01 -#endif - -#ifndef ACCEPT_TGT_IO_TYPE -#define ACCEPT_TGT_IO_TYPE 0x16 /* Accept target I/O entry. */ -#endif - -#ifndef CONTINUE_TGT_IO_TYPE -#define CONTINUE_TGT_IO_TYPE 0x17 -/* - * ISP queue - Continue Target I/O (CTIO) entry for status mode 0 structure. - * This structure is sent to the ISP 2xxx from target driver. - */ -struct ctio_to_2xxx { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System defined handle */ - target_id_t target; - uint16_t rx_id; - uint16_t flags; - uint16_t status; - uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ - uint16_t dseg_count; /* Data segment count. */ - uint32_t relative_offset; - uint32_t residual; - uint16_t reserved_1[3]; - uint16_t scsi_status; - uint32_t transfer_length; - uint32_t dseg_0_address; /* Data segment 0 address. */ - uint32_t dseg_0_length; /* Data segment 0 length. */ - uint32_t dseg_1_address; /* Data segment 1 address. */ - uint32_t dseg_1_length; /* Data segment 1 length. */ - uint32_t dseg_2_address; /* Data segment 2 address. */ - uint32_t dseg_2_length; /* Data segment 2 length. */ -} __packed; -#define ATIO_PATH_INVALID 0x07 -#define ATIO_CANT_PROV_CAP 0x16 -#define ATIO_CDB_VALID 0x3D - -#define ATIO_EXEC_READ BIT_1 -#define ATIO_EXEC_WRITE BIT_0 -#endif - -#ifndef CTIO_A64_TYPE -#define CTIO_A64_TYPE 0x1F -#define CTIO_SUCCESS 0x01 -#define CTIO_ABORTED 0x02 -#define CTIO_INVALID_RX_ID 0x08 -#define CTIO_TIMEOUT 0x0B -#define CTIO_LIP_RESET 0x0E -#define CTIO_TARGET_RESET 0x17 -#define CTIO_PORT_UNAVAILABLE 0x28 -#define CTIO_PORT_LOGGED_OUT 0x29 -#define CTIO_PORT_CONF_CHANGED 0x2A -#define CTIO_SRR_RECEIVED 0x45 -#endif - -#ifndef CTIO_RET_TYPE -#define CTIO_RET_TYPE 0x17 /* CTIO return entry */ -#define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ - -struct fcp_hdr { - uint8_t r_ctl; - uint8_t d_id[3]; - uint8_t cs_ctl; - uint8_t s_id[3]; - uint8_t type; - uint8_t f_ctl[3]; - uint8_t seq_id; - uint8_t df_ctl; - uint16_t seq_cnt; - uint16_t ox_id; - uint16_t rx_id; - uint32_t parameter; -} __packed; - -struct fcp_hdr_le { - uint8_t d_id[3]; - uint8_t r_ctl; - uint8_t s_id[3]; - uint8_t cs_ctl; - uint8_t f_ctl[3]; - uint8_t type; - uint16_t seq_cnt; - uint8_t df_ctl; - uint8_t seq_id; - uint16_t rx_id; - uint16_t ox_id; - uint32_t parameter; -} __packed; - -#define F_CTL_EXCH_CONTEXT_RESP BIT_23 -#define F_CTL_SEQ_CONTEXT_RESIP BIT_22 -#define F_CTL_LAST_SEQ BIT_20 -#define F_CTL_END_SEQ BIT_19 -#define F_CTL_SEQ_INITIATIVE BIT_16 - -#define R_CTL_BASIC_LINK_SERV 0x80 -#define R_CTL_B_ACC 0x4 -#define R_CTL_B_RJT 0x5 - -struct atio7_fcp_cmnd { - uint64_t lun; - uint8_t cmnd_ref; - uint8_t task_attr:3; - uint8_t reserved:5; - uint8_t task_mgmt_flags; -#define FCP_CMND_TASK_MGMT_CLEAR_ACA 6 -#define FCP_CMND_TASK_MGMT_TARGET_RESET 5 -#define FCP_CMND_TASK_MGMT_LU_RESET 4 -#define FCP_CMND_TASK_MGMT_CLEAR_TASK_SET 2 -#define FCP_CMND_TASK_MGMT_ABORT_TASK_SET 1 - uint8_t wrdata:1; - uint8_t rddata:1; - uint8_t add_cdb_len:6; - uint8_t cdb[16]; - /* - * add_cdb is optional and can absent from struct atio7_fcp_cmnd. Size 4 - * only to make sizeof(struct atio7_fcp_cmnd) be as expected by - * BUILD_BUG_ON in qlt_init(). - */ - uint8_t add_cdb[4]; - /* uint32_t data_length; */ -} __packed; - -/* - * ISP queue - Accept Target I/O (ATIO) type entry IOCB structure. - * This is sent from the ISP to the target driver. - */ -struct atio_from_isp { - union { - struct { - uint16_t entry_hdr; - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t sys_define_2; /* System defined. */ - target_id_t target; - uint16_t rx_id; - uint16_t flags; - uint16_t status; - uint8_t command_ref; - uint8_t task_codes; - uint8_t task_flags; - uint8_t execution_codes; - uint8_t cdb[MAX_CMDSZ]; - uint32_t data_length; - uint16_t lun; - uint8_t initiator_port_name[WWN_SIZE]; /* on qla23xx */ - uint16_t reserved_32[6]; - uint16_t ox_id; - } isp2x; - struct { - uint16_t entry_hdr; - uint8_t fcp_cmnd_len_low; - uint8_t fcp_cmnd_len_high:4; - uint8_t attr:4; - uint32_t exchange_addr; -#define ATIO_EXCHANGE_ADDRESS_UNKNOWN 0xFFFFFFFF - struct fcp_hdr fcp_hdr; - struct atio7_fcp_cmnd fcp_cmnd; - } isp24; - struct { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t data[58]; - uint32_t signature; -#define ATIO_PROCESSED 0xDEADDEAD /* Signature */ - } raw; - } u; -} __packed; - -#define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ - -/* - * ISP queue - Continue Target I/O (ATIO) type 7 entry (for 24xx) structure. - * This structure is sent to the ISP 24xx from the target driver. - */ - -struct ctio7_to_24xx { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System defined handle */ - uint16_t nport_handle; -#define CTIO7_NHANDLE_UNRECOGNIZED 0xFFFF - uint16_t timeout; - uint16_t dseg_count; /* Data segment count. */ - uint8_t vp_index; - uint8_t add_flags; - uint8_t initiator_id[3]; - uint8_t reserved; - uint32_t exchange_addr; - union { - struct { - uint16_t reserved1; - uint16_t flags; - uint32_t residual; - uint16_t ox_id; - uint16_t scsi_status; - uint32_t relative_offset; - uint32_t reserved2; - uint32_t transfer_length; - uint32_t reserved3; - /* Data segment 0 address. */ - uint32_t dseg_0_address[2]; - /* Data segment 0 length. */ - uint32_t dseg_0_length; - } status0; - struct { - uint16_t sense_length; - uint16_t flags; - uint32_t residual; - uint16_t ox_id; - uint16_t scsi_status; - uint16_t response_len; - uint16_t reserved; - uint8_t sense_data[24]; - } status1; - } u; -} __packed; - -/* - * ISP queue - CTIO type 7 from ISP 24xx to target driver - * returned entry structure. - */ -struct ctio7_from_24xx { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System defined handle */ - uint16_t status; - uint16_t timeout; - uint16_t dseg_count; /* Data segment count. */ - uint8_t vp_index; - uint8_t reserved1[5]; - uint32_t exchange_address; - uint16_t reserved2; - uint16_t flags; - uint32_t residual; - uint16_t ox_id; - uint16_t reserved3; - uint32_t relative_offset; - uint8_t reserved4[24]; -} __packed; - -/* CTIO7 flags values */ -#define CTIO7_FLAGS_SEND_STATUS BIT_15 -#define CTIO7_FLAGS_TERMINATE BIT_14 -#define CTIO7_FLAGS_CONFORM_REQ BIT_13 -#define CTIO7_FLAGS_DONT_RET_CTIO BIT_8 -#define CTIO7_FLAGS_STATUS_MODE_0 0 -#define CTIO7_FLAGS_STATUS_MODE_1 BIT_6 -#define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5 -#define CTIO7_FLAGS_CONFIRM_SATISF BIT_4 -#define CTIO7_FLAGS_DSD_PTR BIT_2 -#define CTIO7_FLAGS_DATA_IN BIT_1 -#define CTIO7_FLAGS_DATA_OUT BIT_0 - -#define ELS_PLOGI 0x3 -#define ELS_FLOGI 0x4 -#define ELS_LOGO 0x5 -#define ELS_PRLI 0x20 -#define ELS_PRLO 0x21 -#define ELS_TPRLO 0x24 -#define ELS_PDISC 0x50 -#define ELS_ADISC 0x52 - -/* - * ISP queue - ABTS received/response entries structure definition for 24xx. - */ -#define ABTS_RECV_24XX 0x54 /* ABTS received (for 24xx) */ -#define ABTS_RESP_24XX 0x55 /* ABTS responce (for 24xx) */ - -/* - * ISP queue - ABTS received IOCB entry structure definition for 24xx. - * The ABTS BLS received from the wire is sent to the - * target driver by the ISP 24xx. - * The IOCB is placed on the response queue. - */ -struct abts_recv_from_24xx { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint8_t reserved_1[6]; - uint16_t nport_handle; - uint8_t reserved_2[2]; - uint8_t vp_index; - uint8_t reserved_3:4; - uint8_t sof_type:4; - uint32_t exchange_address; - struct fcp_hdr_le fcp_hdr_le; - uint8_t reserved_4[16]; - uint32_t exchange_addr_to_abort; -} __packed; - -#define ABTS_PARAM_ABORT_SEQ BIT_0 - -struct ba_acc_le { - uint16_t reserved; - uint8_t seq_id_last; - uint8_t seq_id_valid; -#define SEQ_ID_VALID 0x80 -#define SEQ_ID_INVALID 0x00 - uint16_t rx_id; - uint16_t ox_id; - uint16_t high_seq_cnt; - uint16_t low_seq_cnt; -} __packed; - -struct ba_rjt_le { - uint8_t vendor_uniq; - uint8_t reason_expl; - uint8_t reason_code; -#define BA_RJT_REASON_CODE_INVALID_COMMAND 0x1 -#define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM 0x9 - uint8_t reserved; -} __packed; - -/* - * ISP queue - ABTS Response IOCB entry structure definition for 24xx. - * The ABTS response to the ABTS received is sent by the - * target driver to the ISP 24xx. - * The IOCB is placed on the request queue. - */ -struct abts_resp_to_24xx { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; - uint16_t reserved_1; - uint16_t nport_handle; - uint16_t control_flags; -#define ABTS_CONTR_FLG_TERM_EXCHG BIT_0 - uint8_t vp_index; - uint8_t reserved_3:4; - uint8_t sof_type:4; - uint32_t exchange_address; - struct fcp_hdr_le fcp_hdr_le; - union { - struct ba_acc_le ba_acct; - struct ba_rjt_le ba_rjt; - } __packed payload; - uint32_t reserved_4; - uint32_t exchange_addr_to_abort; -} __packed; - -/* - * ISP queue - ABTS Response IOCB from ISP24xx Firmware entry structure. - * The ABTS response with completion status to the ABTS response - * (sent by the target driver to the ISP 24xx) is sent by the - * ISP24xx firmware to the target driver. - * The IOCB is placed on the response queue. - */ -struct abts_resp_from_24xx_fw { - uint8_t entry_type; /* Entry type. */ - uint8_t entry_count; /* Entry count. */ - uint8_t sys_define; /* System defined. */ - uint8_t entry_status; /* Entry Status. */ - uint32_t handle; - uint16_t compl_status; -#define ABTS_RESP_COMPL_SUCCESS 0 -#define ABTS_RESP_COMPL_SUBCODE_ERROR 0x31 - uint16_t nport_handle; - uint16_t reserved_1; - uint8_t reserved_2; - uint8_t reserved_3:4; - uint8_t sof_type:4; - uint32_t exchange_address; - struct fcp_hdr_le fcp_hdr_le; - uint8_t reserved_4[8]; - uint32_t error_subcode1; -#define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM 0x1E - uint32_t error_subcode2; - uint32_t exchange_addr_to_abort; -} __packed; - -/********************************************************************\ - * Type Definitions used by initiator & target halves -\********************************************************************/ - -struct qla_tgt_mgmt_cmd; -struct qla_tgt_sess; - -/* - * This structure provides a template of function calls that the - * target driver (from within qla_target.c) can issue to the - * target module (tcm_qla2xxx). - */ -struct qla_tgt_func_tmpl { - - int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, - unsigned char *, uint32_t, int, int, int); - int (*handle_data)(struct qla_tgt_cmd *); - int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, - uint32_t); - void (*free_cmd)(struct qla_tgt_cmd *); - void (*free_mcmd)(struct qla_tgt_mgmt_cmd *); - void (*free_session)(struct qla_tgt_sess *); - - int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, - void *, uint8_t *, uint16_t); - struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, - const uint16_t); - struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, - const uint8_t *); - void (*clear_nacl_from_fcport_map)(struct qla_tgt_sess *); - void (*put_sess)(struct qla_tgt_sess *); - void (*shutdown_sess)(struct qla_tgt_sess *); -}; - -int qla2x00_wait_for_hba_online(struct scsi_qla_host *); - -#include - -#define QLA_TGT_TIMEOUT 10 /* in seconds */ - -#define QLA_TGT_MAX_HW_PENDING_TIME 60 /* in seconds */ - -/* Immediate notify status constants */ -#define IMM_NTFY_LIP_RESET 0x000E -#define IMM_NTFY_LIP_LINK_REINIT 0x000F -#define IMM_NTFY_IOCB_OVERFLOW 0x0016 -#define IMM_NTFY_ABORT_TASK 0x0020 -#define IMM_NTFY_PORT_LOGOUT 0x0029 -#define IMM_NTFY_PORT_CONFIG 0x002A -#define IMM_NTFY_GLBL_TPRLO 0x002D -#define IMM_NTFY_GLBL_LOGO 0x002E -#define IMM_NTFY_RESOURCE 0x0034 -#define IMM_NTFY_MSG_RX 0x0036 -#define IMM_NTFY_SRR 0x0045 -#define IMM_NTFY_ELS 0x0046 - -/* Immediate notify task flags */ -#define IMM_NTFY_TASK_MGMT_SHIFT 8 - -#define QLA_TGT_CLEAR_ACA 0x40 -#define QLA_TGT_TARGET_RESET 0x20 -#define QLA_TGT_LUN_RESET 0x10 -#define QLA_TGT_CLEAR_TS 0x04 -#define QLA_TGT_ABORT_TS 0x02 -#define QLA_TGT_ABORT_ALL_SESS 0xFFFF -#define QLA_TGT_ABORT_ALL 0xFFFE -#define QLA_TGT_NEXUS_LOSS_SESS 0xFFFD -#define QLA_TGT_NEXUS_LOSS 0xFFFC - -/* Notify Acknowledge flags */ -#define NOTIFY_ACK_RES_COUNT BIT_8 -#define NOTIFY_ACK_CLEAR_LIP_RESET BIT_5 -#define NOTIFY_ACK_TM_RESP_CODE_VALID BIT_4 - -/* Command's states */ -#define QLA_TGT_STATE_NEW 0 /* New command + target processing */ -#define QLA_TGT_STATE_NEED_DATA 1 /* target needs data to continue */ -#define QLA_TGT_STATE_DATA_IN 2 /* Data arrived + target processing */ -#define QLA_TGT_STATE_PROCESSED 3 /* target done processing */ -#define QLA_TGT_STATE_ABORTED 4 /* Command aborted */ - -/* Special handles */ -#define QLA_TGT_NULL_HANDLE 0 -#define QLA_TGT_SKIP_HANDLE (0xFFFFFFFF & ~CTIO_COMPLETION_HANDLE_MARK) - -/* ATIO task_codes field */ -#define ATIO_SIMPLE_QUEUE 0 -#define ATIO_HEAD_OF_QUEUE 1 -#define ATIO_ORDERED_QUEUE 2 -#define ATIO_ACA_QUEUE 4 -#define ATIO_UNTAGGED 5 - -/* TM failed response codes, see FCP (9.4.11 FCP_RSP_INFO) */ -#define FC_TM_SUCCESS 0 -#define FC_TM_BAD_FCP_DATA 1 -#define FC_TM_BAD_CMD 2 -#define FC_TM_FCP_DATA_MISMATCH 3 -#define FC_TM_REJECT 4 -#define FC_TM_FAILED 5 - -/* - * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was - * terminated, so no more actions is needed and success should be returned - * to target. - */ -#define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED 0x1717 - -#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G) -#define pci_dma_lo32(a) (a & 0xffffffff) -#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff) -#else -#define pci_dma_lo32(a) (a & 0xffffffff) -#define pci_dma_hi32(a) 0 -#endif - -#define QLA_TGT_SENSE_VALID(sense) ((sense != NULL) && \ - (((const uint8_t *)(sense))[0] & 0x70) == 0x70) - -struct qla_port_24xx_data { - uint8_t port_name[WWN_SIZE]; - uint16_t loop_id; - uint16_t reserved; -}; - -struct qla_tgt { - struct scsi_qla_host *vha; - struct qla_hw_data *ha; - - /* - * To sync between IRQ handlers and qlt_target_release(). Needed, - * because req_pkt() can drop/reaquire HW lock inside. Protected by - * HW lock. - */ - int irq_cmd_count; - - int datasegs_per_cmd, datasegs_per_cont, sg_tablesize; - - /* Target's flags, serialized by pha->hardware_lock */ - unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addr enabled */ - unsigned int link_reinit_iocb_pending:1; - - /* - * Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex - * OR hardware_lock for reading. - */ - int tgt_stop; /* the target mode driver is being stopped */ - int tgt_stopped; /* the target mode driver has been stopped */ - - /* Count of sessions refering qla_tgt. Protected by hardware_lock. */ - int sess_count; - - /* Protected by hardware_lock. Addition also protected by tgt_mutex. */ - struct list_head sess_list; - - /* Protected by hardware_lock */ - struct list_head del_sess_list; - struct delayed_work sess_del_work; - - spinlock_t sess_work_lock; - struct list_head sess_works_list; - struct work_struct sess_work; - - struct imm_ntfy_from_isp link_reinit_iocb; - wait_queue_head_t waitQ; - int notify_ack_expected; - int abts_resp_expected; - int modify_lun_expected; - - int ctio_srr_id; - int imm_srr_id; - spinlock_t srr_lock; - struct list_head srr_ctio_list; - struct list_head srr_imm_list; - struct work_struct srr_work; - - atomic_t tgt_global_resets_count; - - struct list_head tgt_list_entry; -}; - -/* - * Equivilant to IT Nexus (Initiator-Target) - */ -struct qla_tgt_sess { - uint16_t loop_id; - port_id_t s_id; - - unsigned int conf_compl_supported:1; - unsigned int deleted:1; - unsigned int local:1; - unsigned int tearing_down:1; - - struct se_session *se_sess; - struct scsi_qla_host *vha; - struct qla_tgt *tgt; - - struct list_head sess_list_entry; - unsigned long expires; - struct list_head del_list_entry; - - uint8_t port_name[WWN_SIZE]; - struct work_struct free_work; -}; - -struct qla_tgt_cmd { - struct qla_tgt_sess *sess; - int state; - struct se_cmd se_cmd; - struct work_struct free_work; - struct work_struct work; - /* Sense buffer that will be mapped into outgoing status */ - unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; - - /* to save extra sess dereferences */ - unsigned int conf_compl_supported:1; - unsigned int sg_mapped:1; - unsigned int free_sg:1; - unsigned int aborted:1; /* Needed in case of SRR */ - unsigned int write_data_transferred:1; - - struct scatterlist *sg; /* cmd data buffer SG vector */ - int sg_cnt; /* SG segments count */ - int bufflen; /* cmd buffer length */ - int offset; - uint32_t tag; - uint32_t unpacked_lun; - enum dma_data_direction dma_data_direction; - - uint16_t loop_id; /* to save extra sess dereferences */ - struct qla_tgt *tgt; /* to save extra sess dereferences */ - struct scsi_qla_host *vha; - struct list_head cmd_list; - - struct atio_from_isp atio; -}; - -struct qla_tgt_sess_work_param { - struct list_head sess_works_list_entry; - -#define QLA_TGT_SESS_WORK_ABORT 1 -#define QLA_TGT_SESS_WORK_TM 2 - int type; - - union { - struct abts_recv_from_24xx abts; - struct imm_ntfy_from_isp tm_iocb; - struct atio_from_isp tm_iocb2; - }; -}; - -struct qla_tgt_mgmt_cmd { - uint8_t tmr_func; - uint8_t fc_tm_rsp; - struct qla_tgt_sess *sess; - struct se_cmd se_cmd; - struct work_struct free_work; - unsigned int flags; -#define QLA24XX_MGMT_SEND_NACK 1 - union { - struct atio_from_isp atio; - struct imm_ntfy_from_isp imm_ntfy; - struct abts_recv_from_24xx abts; - } __packed orig_iocb; -}; - -struct qla_tgt_prm { - struct qla_tgt_cmd *cmd; - struct qla_tgt *tgt; - void *pkt; - struct scatterlist *sg; /* cmd data buffer SG vector */ - int seg_cnt; - int req_cnt; - uint16_t rq_result; - uint16_t scsi_status; - unsigned char *sense_buffer; - int sense_buffer_len; - int residual; - int add_status_pkt; -}; - -struct qla_tgt_srr_imm { - struct list_head srr_list_entry; - int srr_id; - struct imm_ntfy_from_isp imm_ntfy; -}; - -struct qla_tgt_srr_ctio { - struct list_head srr_list_entry; - int srr_id; - struct qla_tgt_cmd *cmd; -}; - -#define QLA_TGT_XMIT_DATA 1 -#define QLA_TGT_XMIT_STATUS 2 -#define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) - -#include - -extern struct qla_tgt_data qla_target; -/* - * Internal function prototypes - */ -void qlt_disable_vha(struct scsi_qla_host *); - -/* - * Function prototypes for qla_target.c logic used by qla2xxx LLD code. - */ -extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *); -extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *); -extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64, - int (*callback)(struct scsi_qla_host *), void *); -extern void qlt_lport_deregister(struct scsi_qla_host *); -extern void qlt_unreg_sess(struct qla_tgt_sess *); -extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *); -extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *); -extern void qlt_set_mode(struct scsi_qla_host *ha); -extern void qlt_clear_mode(struct scsi_qla_host *ha); -extern int __init qlt_init(void); -extern void qlt_exit(void); -extern void qlt_update_vp_map(struct scsi_qla_host *, int); - -/* - * This macro is used during early initializations when host->active_mode - * is not set. Right now, ha value is ignored. - */ -#define QLA_TGT_MODE_ENABLED() (ql2x_ini_mode != QLA2XXX_INI_MODE_ENABLED) - -static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha) -{ - return ha->host->active_mode & MODE_TARGET; -} - -static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha) -{ - return ha->host->active_mode & MODE_INITIATOR; -} - -static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha) -{ - if (ha->host->active_mode & MODE_INITIATOR) - ha->host->active_mode &= ~MODE_INITIATOR; - else - ha->host->active_mode |= MODE_INITIATOR; -} - -/* - * Exported symbols from qla_target.c LLD logic used by qla2xxx code.. - */ -extern void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *, - struct atio_from_isp *); -extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); -extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); -extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); -extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); -extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); -extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); -extern void qlt_ctio_completion(struct scsi_qla_host *, uint32_t); -extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *); -extern void qlt_enable_vha(struct scsi_qla_host *); -extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); -extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *); -extern void qlt_init_atio_q_entries(struct scsi_qla_host *); -extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *); -extern void qlt_24xx_config_rings(struct scsi_qla_host *, - device_reg_t __iomem *); -extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *, - struct nvram_24xx *); -extern void qlt_24xx_config_nvram_stage2(struct scsi_qla_host *, - struct init_cb_24xx *); -extern int qlt_24xx_process_response_error(struct scsi_qla_host *, - struct sts_entry_24xx *); -extern void qlt_modify_vp_config(struct scsi_qla_host *, - struct vp_config_entry_24xx *); -extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); -extern int qlt_mem_alloc(struct qla_hw_data *); -extern void qlt_mem_free(struct qla_hw_data *); -extern void qlt_stop_phase1(struct qla_tgt *); -extern void qlt_stop_phase2(struct qla_tgt *); - -#endif /* __QLA_TARGET_H */ diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c deleted file mode 100644 index 436598f57404..000000000000 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ /dev/null @@ -1,1955 +0,0 @@ -/******************************************************************************* - * This file contains tcm implementation using v4 configfs fabric infrastructure - * for QLogic target mode HBAs - * - * ?? Copyright 2010-2011 RisingTide Systems LLC. - * - * Licensed to the Linux Foundation under the General Public License (GPL) - * version 2. - * - * Author: Nicholas A. Bellinger - * - * tcm_qla2xxx_parse_wwn() and tcm_qla2xxx_format_wwn() contains code from - * the TCM_FC / Open-FCoE.org fabric module. - * - * Copyright (c) 2010 Cisco Systems, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - ****************************************************************************/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qla_def.h" -#include "qla_target.h" -#include "tcm_qla2xxx.h" - -struct workqueue_struct *tcm_qla2xxx_free_wq; -struct workqueue_struct *tcm_qla2xxx_cmd_wq; - -static int tcm_qla2xxx_check_true(struct se_portal_group *se_tpg) -{ - return 1; -} - -static int tcm_qla2xxx_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - -/* - * Parse WWN. - * If strict, we require lower-case hex and colon separators to be sure - * the name is the same as what would be generated by ft_format_wwn() - * so the name and wwn are mapped one-to-one. - */ -static ssize_t tcm_qla2xxx_parse_wwn(const char *name, u64 *wwn, int strict) -{ - const char *cp; - char c; - u32 nibble; - u32 byte = 0; - u32 pos = 0; - u32 err; - - *wwn = 0; - for (cp = name; cp < &name[TCM_QLA2XXX_NAMELEN - 1]; cp++) { - c = *cp; - if (c == '\n' && cp[1] == '\0') - continue; - if (strict && pos++ == 2 && byte++ < 7) { - pos = 0; - if (c == ':') - continue; - err = 1; - goto fail; - } - if (c == '\0') { - err = 2; - if (strict && byte != 8) - goto fail; - return cp - name; - } - err = 3; - if (isdigit(c)) - nibble = c - '0'; - else if (isxdigit(c) && (islower(c) || !strict)) - nibble = tolower(c) - 'a' + 10; - else - goto fail; - *wwn = (*wwn << 4) | nibble; - } - err = 4; -fail: - pr_debug("err %u len %zu pos %u byte %u\n", - err, cp - name, pos, byte); - return -1; -} - -static ssize_t tcm_qla2xxx_format_wwn(char *buf, size_t len, u64 wwn) -{ - u8 b[8]; - - put_unaligned_be64(wwn, b); - return snprintf(buf, len, - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); -} - -static char *tcm_qla2xxx_get_fabric_name(void) -{ - return "qla2xxx"; -} - -/* - * From drivers/scsi/scsi_transport_fc.c:fc_parse_wwn - */ -static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm) -{ - unsigned int i, j, value; - u8 wwn[8]; - - memset(wwn, 0, sizeof(wwn)); - - /* Validate and store the new name */ - for (i = 0, j = 0; i < 16; i++) { - value = hex_to_bin(*ns++); - if (value >= 0) - j = (j << 4) | value; - else - return -EINVAL; - - if (i % 2) { - wwn[i/2] = j & 0xff; - j = 0; - } - } - - *nm = wwn_to_u64(wwn); - return 0; -} - -/* - * This parsing logic follows drivers/scsi/scsi_transport_fc.c: - * store_fc_host_vport_create() - */ -static int tcm_qla2xxx_npiv_parse_wwn( - const char *name, - size_t count, - u64 *wwpn, - u64 *wwnn) -{ - unsigned int cnt = count; - int rc; - - *wwpn = 0; - *wwnn = 0; - - /* count may include a LF at end of string */ - if (name[cnt-1] == '\n') - cnt--; - - /* validate we have enough characters for WWPN */ - if ((cnt != (16+1+16)) || (name[16] != ':')) - return -EINVAL; - - rc = tcm_qla2xxx_npiv_extract_wwn(&name[0], wwpn); - if (rc != 0) - return rc; - - rc = tcm_qla2xxx_npiv_extract_wwn(&name[17], wwnn); - if (rc != 0) - return rc; - - return 0; -} - -static ssize_t tcm_qla2xxx_npiv_format_wwn(char *buf, size_t len, - u64 wwpn, u64 wwnn) -{ - u8 b[8], b2[8]; - - put_unaligned_be64(wwpn, b); - put_unaligned_be64(wwnn, b2); - return snprintf(buf, len, - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x," - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], - b2[0], b2[1], b2[2], b2[3], b2[4], b2[5], b2[6], b2[7]); -} - -static char *tcm_qla2xxx_npiv_get_fabric_name(void) -{ - return "qla2xxx_npiv"; -} - -static u8 tcm_qla2xxx_get_fabric_proto_ident(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - u8 proto_id; - - switch (lport->lport_proto_id) { - case SCSI_PROTOCOL_FCP: - default: - proto_id = fc_get_fabric_proto_ident(se_tpg); - break; - } - - return proto_id; -} - -static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - - return &lport->lport_name[0]; -} - -static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - - return &lport->lport_npiv_name[0]; -} - -static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - return tpg->lport_tpgt; -} - -static u32 tcm_qla2xxx_get_default_depth(struct se_portal_group *se_tpg) -{ - return 1; -} - -static u32 tcm_qla2xxx_get_pr_transport_id( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code, - unsigned char *buf) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - int ret = 0; - - switch (lport->lport_proto_id) { - case SCSI_PROTOCOL_FCP: - default: - ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, - format_code, buf); - break; - } - - return ret; -} - -static u32 tcm_qla2xxx_get_pr_transport_id_len( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - int ret = 0; - - switch (lport->lport_proto_id) { - case SCSI_PROTOCOL_FCP: - default: - ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, - format_code); - break; - } - - return ret; -} - -static char *tcm_qla2xxx_parse_pr_out_transport_id( - struct se_portal_group *se_tpg, - const char *buf, - u32 *out_tid_len, - char **port_nexus_ptr) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - char *tid = NULL; - - switch (lport->lport_proto_id) { - case SCSI_PROTOCOL_FCP: - default: - tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, - port_nexus_ptr); - break; - } - - return tid; -} - -static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return QLA_TPG_ATTRIB(tpg)->generate_node_acls; -} - -static int tcm_qla2xxx_check_demo_mode_cache(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return QLA_TPG_ATTRIB(tpg)->cache_dynamic_acls; -} - -static int tcm_qla2xxx_check_demo_write_protect(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return QLA_TPG_ATTRIB(tpg)->demo_mode_write_protect; -} - -static int tcm_qla2xxx_check_prod_write_protect(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return QLA_TPG_ATTRIB(tpg)->prod_mode_write_protect; -} - -static struct se_node_acl *tcm_qla2xxx_alloc_fabric_acl( - struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_nacl *nacl; - - nacl = kzalloc(sizeof(struct tcm_qla2xxx_nacl), GFP_KERNEL); - if (!nacl) { - pr_err("Unable to alocate struct tcm_qla2xxx_nacl\n"); - return NULL; - } - - return &nacl->se_node_acl; -} - -static void tcm_qla2xxx_release_fabric_acl( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl) -{ - struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, - struct tcm_qla2xxx_nacl, se_node_acl); - kfree(nacl); -} - -static u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return tpg->lport_tpgt; -} - -static void tcm_qla2xxx_complete_mcmd(struct work_struct *work) -{ - struct qla_tgt_mgmt_cmd *mcmd = container_of(work, - struct qla_tgt_mgmt_cmd, free_work); - - transport_generic_free_cmd(&mcmd->se_cmd, 0); -} - -/* - * Called from qla_target_template->free_mcmd(), and will call - * tcm_qla2xxx_release_cmd() via normal struct target_core_fabric_ops - * release callback. qla_hw_data->hardware_lock is expected to be held - */ -static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) -{ - INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); - queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); -} - -static void tcm_qla2xxx_complete_free(struct work_struct *work) -{ - struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); - - transport_generic_free_cmd(&cmd->se_cmd, 0); -} - -/* - * Called from qla_target_template->free_cmd(), and will call - * tcm_qla2xxx_release_cmd via normal struct target_core_fabric_ops - * release callback. qla_hw_data->hardware_lock is expected to be held - */ -static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) -{ - INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); - queue_work(tcm_qla2xxx_free_wq, &cmd->work); -} - -/* - * Called from struct target_core_fabric_ops->check_stop_free() context - */ -static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd) -{ - return target_put_sess_cmd(se_cmd->se_sess, se_cmd); -} - -/* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying - * fabric descriptor @se_cmd command to release - */ -static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd) -{ - struct qla_tgt_cmd *cmd; - - if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) { - struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, - struct qla_tgt_mgmt_cmd, se_cmd); - qlt_free_mcmd(mcmd); - return; - } - - cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); - qlt_free_cmd(cmd); -} - -static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess) -{ - struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; - struct scsi_qla_host *vha; - unsigned long flags; - - BUG_ON(!sess); - vha = sess->vha; - - spin_lock_irqsave(&vha->hw->hardware_lock, flags); - sess->tearing_down = 1; - target_splice_sess_cmd_list(se_sess); - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); - - return 1; -} - -static void tcm_qla2xxx_close_session(struct se_session *se_sess) -{ - struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; - struct scsi_qla_host *vha; - unsigned long flags; - - BUG_ON(!sess); - vha = sess->vha; - - spin_lock_irqsave(&vha->hw->hardware_lock, flags); - qlt_unreg_sess(sess); - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); -} - -static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -/* - * The LIO target core uses DMA_TO_DEVICE to mean that data is going - * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean - * that data is coming from the target (eg handling a READ). However, - * this is just the opposite of what we have to tell the DMA mapping - * layer -- eg when handling a READ, the HBA will have to DMA the data - * out of memory so it can send it to the initiator, which means we - * need to use DMA_TO_DEVICE when we map the data. - */ -static enum dma_data_direction tcm_qla2xxx_mapping_dir(struct se_cmd *se_cmd) -{ - if (se_cmd->se_cmd_flags & SCF_BIDI) - return DMA_BIDIRECTIONAL; - - switch (se_cmd->data_direction) { - case DMA_TO_DEVICE: - return DMA_FROM_DEVICE; - case DMA_FROM_DEVICE: - return DMA_TO_DEVICE; - case DMA_NONE: - default: - return DMA_NONE; - } -} - -static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) -{ - struct qla_tgt_cmd *cmd = container_of(se_cmd, - struct qla_tgt_cmd, se_cmd); - - cmd->bufflen = se_cmd->data_length; - cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); - - cmd->sg_cnt = se_cmd->t_data_nents; - cmd->sg = se_cmd->t_data_sg; - - /* - * qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup - * the SGL mappings into PCIe memory for incoming FCP WRITE data. - */ - return qlt_rdy_to_xfer(cmd); -} - -static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd) -{ - unsigned long flags; - /* - * Check for WRITE_PENDING status to determine if we need to wait for - * CTIO aborts to be posted via hardware in tcm_qla2xxx_handle_data(). - */ - spin_lock_irqsave(&se_cmd->t_state_lock, flags); - if (se_cmd->t_state == TRANSPORT_WRITE_PENDING || - se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) { - spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); - wait_for_completion_timeout(&se_cmd->t_transport_stop_comp, - 3000); - return 0; - } - spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); - - return 0; -} - -static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - -static u32 tcm_qla2xxx_get_task_tag(struct se_cmd *se_cmd) -{ - struct qla_tgt_cmd *cmd = container_of(se_cmd, - struct qla_tgt_cmd, se_cmd); - - return cmd->tag; -} - -static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - -/* - * Called from process context in qla_target.c:qlt_do_work() code - */ -static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, - unsigned char *cdb, uint32_t data_length, int fcp_task_attr, - int data_dir, int bidi) -{ - struct se_cmd *se_cmd = &cmd->se_cmd; - struct se_session *se_sess; - struct qla_tgt_sess *sess; - int flags = TARGET_SCF_ACK_KREF; - - if (bidi) - flags |= TARGET_SCF_BIDI_OP; - - sess = cmd->sess; - if (!sess) { - pr_err("Unable to locate struct qla_tgt_sess from qla_tgt_cmd\n"); - return -EINVAL; - } - - se_sess = sess->se_sess; - if (!se_sess) { - pr_err("Unable to locate active struct se_session\n"); - return -EINVAL; - } - - target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], - cmd->unpacked_lun, data_length, fcp_task_attr, - data_dir, flags); - return 0; -} - -static void tcm_qla2xxx_do_rsp(struct work_struct *work) -{ - struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); - /* - * Dispatch ->queue_status from workqueue process context - */ - transport_generic_request_failure(&cmd->se_cmd); -} - -/* - * Called from qla_target.c:qlt_do_ctio_completion() - */ -static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) -{ - struct se_cmd *se_cmd = &cmd->se_cmd; - unsigned long flags; - /* - * Ensure that the complete FCP WRITE payload has been received. - * Otherwise return an exception via CHECK_CONDITION status. - */ - if (!cmd->write_data_transferred) { - /* - * Check if se_cmd has already been aborted via LUN_RESET, and - * waiting upon completion in tcm_qla2xxx_write_pending_status() - */ - spin_lock_irqsave(&se_cmd->t_state_lock, flags); - if (se_cmd->transport_state & CMD_T_ABORTED) { - spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); - complete(&se_cmd->t_transport_stop_comp); - return 0; - } - spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); - - se_cmd->scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD; - INIT_WORK(&cmd->work, tcm_qla2xxx_do_rsp); - queue_work(tcm_qla2xxx_free_wq, &cmd->work); - return 0; - } - /* - * We now tell TCM to queue this WRITE CDB with TRANSPORT_PROCESS_WRITE - * status to the backstore processing thread. - */ - return transport_generic_handle_data(&cmd->se_cmd); -} - -/* - * Called from qla_target.c:qlt_issue_task_mgmt() - */ -int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, - uint8_t tmr_func, uint32_t tag) -{ - struct qla_tgt_sess *sess = mcmd->sess; - struct se_cmd *se_cmd = &mcmd->se_cmd; - - return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd, - tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF); -} - -static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) -{ - struct qla_tgt_cmd *cmd = container_of(se_cmd, - struct qla_tgt_cmd, se_cmd); - - cmd->bufflen = se_cmd->data_length; - cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); - cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); - - cmd->sg_cnt = se_cmd->t_data_nents; - cmd->sg = se_cmd->t_data_sg; - cmd->offset = 0; - - /* - * Now queue completed DATA_IN the qla2xxx LLD and response ring - */ - return qlt_xmit_response(cmd, QLA_TGT_XMIT_DATA|QLA_TGT_XMIT_STATUS, - se_cmd->scsi_status); -} - -static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) -{ - struct qla_tgt_cmd *cmd = container_of(se_cmd, - struct qla_tgt_cmd, se_cmd); - int xmit_type = QLA_TGT_XMIT_STATUS; - - cmd->bufflen = se_cmd->data_length; - cmd->sg = NULL; - cmd->sg_cnt = 0; - cmd->offset = 0; - cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); - cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); - - if (se_cmd->data_direction == DMA_FROM_DEVICE) { - /* - * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen - * for qla_tgt_xmit_response LLD code - */ - se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; - se_cmd->residual_count = se_cmd->data_length; - - cmd->bufflen = 0; - } - /* - * Now queue status response to qla2xxx LLD code and response ring - */ - return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); -} - -static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) -{ - struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; - struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, - struct qla_tgt_mgmt_cmd, se_cmd); - - pr_debug("queue_tm_rsp: mcmd: %p func: 0x%02x response: 0x%02x\n", - mcmd, se_tmr->function, se_tmr->response); - /* - * Do translation between TCM TM response codes and - * QLA2xxx FC TM response codes. - */ - switch (se_tmr->response) { - case TMR_FUNCTION_COMPLETE: - mcmd->fc_tm_rsp = FC_TM_SUCCESS; - break; - case TMR_TASK_DOES_NOT_EXIST: - mcmd->fc_tm_rsp = FC_TM_BAD_CMD; - break; - case TMR_FUNCTION_REJECTED: - mcmd->fc_tm_rsp = FC_TM_REJECT; - break; - case TMR_LUN_DOES_NOT_EXIST: - default: - mcmd->fc_tm_rsp = FC_TM_FAILED; - break; - } - /* - * Queue the TM response to QLA2xxx LLD to build a - * CTIO response packet. - */ - qlt_xmit_tm_rsp(mcmd); - - return 0; -} - -static u16 tcm_qla2xxx_get_fabric_sense_len(void) -{ - return 0; -} - -static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - -/* Local pointer to allocated TCM configfs fabric module */ -struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; -struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; - -static int tcm_qla2xxx_setup_nacl_from_rport( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct tcm_qla2xxx_lport *lport, - struct tcm_qla2xxx_nacl *nacl, - u64 rport_wwnn) -{ - struct scsi_qla_host *vha = lport->qla_vha; - struct Scsi_Host *sh = vha->host; - struct fc_host_attrs *fc_host = shost_to_fc_host(sh); - struct fc_rport *rport; - unsigned long flags; - void *node; - int rc; - - /* - * Scan the existing rports, and create a session for the - * explict NodeACL is an matching rport->node_name already - * exists. - */ - spin_lock_irqsave(sh->host_lock, flags); - list_for_each_entry(rport, &fc_host->rports, peers) { - if (rport_wwnn != rport->node_name) - continue; - - pr_debug("Located existing rport_wwpn and rport->node_name: 0x%016LX, port_id: 0x%04x\n", - rport->node_name, rport->port_id); - nacl->nport_id = rport->port_id; - - spin_unlock_irqrestore(sh->host_lock, flags); - - spin_lock_irqsave(&vha->hw->hardware_lock, flags); - node = btree_lookup32(&lport->lport_fcport_map, rport->port_id); - if (node) { - rc = btree_update32(&lport->lport_fcport_map, - rport->port_id, se_nacl); - } else { - rc = btree_insert32(&lport->lport_fcport_map, - rport->port_id, se_nacl, - GFP_ATOMIC); - } - spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); - - if (rc) { - pr_err("Unable to insert se_nacl into fcport_map"); - WARN_ON(rc > 0); - return rc; - } - - pr_debug("Inserted into fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%08x\n", - se_nacl, rport_wwnn, nacl->nport_id); - - return 1; - } - spin_unlock_irqrestore(sh->host_lock, flags); - - return 0; -} - -/* - * Expected to be called with struct qla_hw_data->hardware_lock held - */ -static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess) -{ - struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; - struct se_portal_group *se_tpg = se_nacl->se_tpg; - struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; - struct tcm_qla2xxx_lport *lport = container_of(se_wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, - struct tcm_qla2xxx_nacl, se_node_acl); - void *node; - - pr_debug("fc_rport domain: port_id 0x%06x\n", nacl->nport_id); - - node = btree_remove32(&lport->lport_fcport_map, nacl->nport_id); - WARN_ON(node && (node != se_nacl)); - - pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n", - se_nacl, nacl->nport_wwnn, nacl->nport_id); -} - -static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) -{ - target_put_session(sess->se_sess); -} - -static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) -{ - tcm_qla2xxx_shutdown_session(sess->se_sess); -} - -static struct se_node_acl *tcm_qla2xxx_make_nodeacl( - struct se_portal_group *se_tpg, - struct config_group *group, - const char *name) -{ - struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; - struct tcm_qla2xxx_lport *lport = container_of(se_wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct se_node_acl *se_nacl, *se_nacl_new; - struct tcm_qla2xxx_nacl *nacl; - u64 wwnn; - u32 qla2xxx_nexus_depth; - int rc; - - if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) - return ERR_PTR(-EINVAL); - - se_nacl_new = tcm_qla2xxx_alloc_fabric_acl(se_tpg); - if (!se_nacl_new) - return ERR_PTR(-ENOMEM); -/* #warning FIXME: Hardcoded qla2xxx_nexus depth in tcm_qla2xxx_make_nodeacl */ - qla2xxx_nexus_depth = 1; - - /* - * se_nacl_new may be released by core_tpg_add_initiator_node_acl() - * when converting a NodeACL from demo mode -> explict - */ - se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, - name, qla2xxx_nexus_depth); - if (IS_ERR(se_nacl)) { - tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); - return se_nacl; - } - /* - * Locate our struct tcm_qla2xxx_nacl and set the FC Nport WWPN - */ - nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); - nacl->nport_wwnn = wwnn; - tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); - /* - * Setup a se_nacl handle based on an a matching struct fc_rport setup - * via drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() - */ - rc = tcm_qla2xxx_setup_nacl_from_rport(se_tpg, se_nacl, lport, - nacl, wwnn); - if (rc < 0) { - tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); - return ERR_PTR(rc); - } - - return se_nacl; -} - -static void tcm_qla2xxx_drop_nodeacl(struct se_node_acl *se_acl) -{ - struct se_portal_group *se_tpg = se_acl->se_tpg; - struct tcm_qla2xxx_nacl *nacl = container_of(se_acl, - struct tcm_qla2xxx_nacl, se_node_acl); - - core_tpg_del_initiator_node_acl(se_tpg, se_acl, 1); - kfree(nacl); -} - -/* Start items for tcm_qla2xxx_tpg_attrib_cit */ - -#define DEF_QLA_TPG_ATTRIB(name) \ - \ -static ssize_t tcm_qla2xxx_tpg_attrib_show_##name( \ - struct se_portal_group *se_tpg, \ - char *page) \ -{ \ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, \ - struct tcm_qla2xxx_tpg, se_tpg); \ - \ - return sprintf(page, "%u\n", QLA_TPG_ATTRIB(tpg)->name); \ -} \ - \ -static ssize_t tcm_qla2xxx_tpg_attrib_store_##name( \ - struct se_portal_group *se_tpg, \ - const char *page, \ - size_t count) \ -{ \ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, \ - struct tcm_qla2xxx_tpg, se_tpg); \ - unsigned long val; \ - int ret; \ - \ - ret = kstrtoul(page, 0, &val); \ - if (ret < 0) { \ - pr_err("kstrtoul() failed with" \ - " ret: %d\n", ret); \ - return -EINVAL; \ - } \ - ret = tcm_qla2xxx_set_attrib_##name(tpg, val); \ - \ - return (!ret) ? count : -EINVAL; \ -} - -#define DEF_QLA_TPG_ATTR_BOOL(_name) \ - \ -static int tcm_qla2xxx_set_attrib_##_name( \ - struct tcm_qla2xxx_tpg *tpg, \ - unsigned long val) \ -{ \ - struct tcm_qla2xxx_tpg_attrib *a = &tpg->tpg_attrib; \ - \ - if ((val != 0) && (val != 1)) { \ - pr_err("Illegal boolean value %lu\n", val); \ - return -EINVAL; \ - } \ - \ - a->_name = val; \ - return 0; \ -} - -#define QLA_TPG_ATTR(_name, _mode) \ - TF_TPG_ATTRIB_ATTR(tcm_qla2xxx, _name, _mode); - -/* - * Define tcm_qla2xxx_tpg_attrib_s_generate_node_acls - */ -DEF_QLA_TPG_ATTR_BOOL(generate_node_acls); -DEF_QLA_TPG_ATTRIB(generate_node_acls); -QLA_TPG_ATTR(generate_node_acls, S_IRUGO | S_IWUSR); - -/* - Define tcm_qla2xxx_attrib_s_cache_dynamic_acls - */ -DEF_QLA_TPG_ATTR_BOOL(cache_dynamic_acls); -DEF_QLA_TPG_ATTRIB(cache_dynamic_acls); -QLA_TPG_ATTR(cache_dynamic_acls, S_IRUGO | S_IWUSR); - -/* - * Define tcm_qla2xxx_tpg_attrib_s_demo_mode_write_protect - */ -DEF_QLA_TPG_ATTR_BOOL(demo_mode_write_protect); -DEF_QLA_TPG_ATTRIB(demo_mode_write_protect); -QLA_TPG_ATTR(demo_mode_write_protect, S_IRUGO | S_IWUSR); - -/* - * Define tcm_qla2xxx_tpg_attrib_s_prod_mode_write_protect - */ -DEF_QLA_TPG_ATTR_BOOL(prod_mode_write_protect); -DEF_QLA_TPG_ATTRIB(prod_mode_write_protect); -QLA_TPG_ATTR(prod_mode_write_protect, S_IRUGO | S_IWUSR); - -static struct configfs_attribute *tcm_qla2xxx_tpg_attrib_attrs[] = { - &tcm_qla2xxx_tpg_attrib_generate_node_acls.attr, - &tcm_qla2xxx_tpg_attrib_cache_dynamic_acls.attr, - &tcm_qla2xxx_tpg_attrib_demo_mode_write_protect.attr, - &tcm_qla2xxx_tpg_attrib_prod_mode_write_protect.attr, - NULL, -}; - -/* End items for tcm_qla2xxx_tpg_attrib_cit */ - -static ssize_t tcm_qla2xxx_tpg_show_enable( - struct se_portal_group *se_tpg, - char *page) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return snprintf(page, PAGE_SIZE, "%d\n", - atomic_read(&tpg->lport_tpg_enabled)); -} - -static ssize_t tcm_qla2xxx_tpg_store_enable( - struct se_portal_group *se_tpg, - const char *page, - size_t count) -{ - struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; - struct tcm_qla2xxx_lport *lport = container_of(se_wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct scsi_qla_host *vha = lport->qla_vha; - struct qla_hw_data *ha = vha->hw; - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - unsigned long op; - int rc; - - rc = kstrtoul(page, 0, &op); - if (rc < 0) { - pr_err("kstrtoul() returned %d\n", rc); - return -EINVAL; - } - if ((op != 1) && (op != 0)) { - pr_err("Illegal value for tpg_enable: %lu\n", op); - return -EINVAL; - } - - if (op) { - atomic_set(&tpg->lport_tpg_enabled, 1); - qlt_enable_vha(vha); - } else { - if (!ha->tgt.qla_tgt) { - pr_err("truct qla_hw_data *ha->tgt.qla_tgt is NULL\n"); - return -ENODEV; - } - atomic_set(&tpg->lport_tpg_enabled, 0); - qlt_stop_phase1(ha->tgt.qla_tgt); - } - - return count; -} - -TF_TPG_BASE_ATTR(tcm_qla2xxx, enable, S_IRUGO | S_IWUSR); - -static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = { - &tcm_qla2xxx_tpg_enable.attr, - NULL, -}; - -static struct se_portal_group *tcm_qla2xxx_make_tpg( - struct se_wwn *wwn, - struct config_group *group, - const char *name) -{ - struct tcm_qla2xxx_lport *lport = container_of(wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct tcm_qla2xxx_tpg *tpg; - unsigned long tpgt; - int ret; - - if (strstr(name, "tpgt_") != name) - return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) - return ERR_PTR(-EINVAL); - - if (!lport->qla_npiv_vp && (tpgt != 1)) { - pr_err("In non NPIV mode, a single TPG=1 is used for HW port mappings\n"); - return ERR_PTR(-ENOSYS); - } - - tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); - if (!tpg) { - pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); - return ERR_PTR(-ENOMEM); - } - tpg->lport = lport; - tpg->lport_tpgt = tpgt; - /* - * By default allow READ-ONLY TPG demo-mode access w/ cached dynamic - * NodeACLs - */ - QLA_TPG_ATTRIB(tpg)->generate_node_acls = 1; - QLA_TPG_ATTRIB(tpg)->demo_mode_write_protect = 1; - QLA_TPG_ATTRIB(tpg)->cache_dynamic_acls = 1; - - ret = core_tpg_register(&tcm_qla2xxx_fabric_configfs->tf_ops, wwn, - &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); - if (ret < 0) { - kfree(tpg); - return NULL; - } - /* - * Setup local TPG=1 pointer for non NPIV mode. - */ - if (lport->qla_npiv_vp == NULL) - lport->tpg_1 = tpg; - - return &tpg->se_tpg; -} - -static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) -{ - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - struct tcm_qla2xxx_lport *lport = tpg->lport; - struct scsi_qla_host *vha = lport->qla_vha; - struct qla_hw_data *ha = vha->hw; - /* - * Call into qla2x_target.c LLD logic to shutdown the active - * FC Nexuses and disable target mode operation for this qla_hw_data - */ - if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stop) - qlt_stop_phase1(ha->tgt.qla_tgt); - - core_tpg_deregister(se_tpg); - /* - * Clear local TPG=1 pointer for non NPIV mode. - */ - if (lport->qla_npiv_vp == NULL) - lport->tpg_1 = NULL; - - kfree(tpg); -} - -static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( - struct se_wwn *wwn, - struct config_group *group, - const char *name) -{ - struct tcm_qla2xxx_lport *lport = container_of(wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct tcm_qla2xxx_tpg *tpg; - unsigned long tpgt; - int ret; - - if (strstr(name, "tpgt_") != name) - return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) - return ERR_PTR(-EINVAL); - - tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); - if (!tpg) { - pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); - return ERR_PTR(-ENOMEM); - } - tpg->lport = lport; - tpg->lport_tpgt = tpgt; - - ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, - &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); - if (ret < 0) { - kfree(tpg); - return NULL; - } - return &tpg->se_tpg; -} - -/* - * Expected to be called with struct qla_hw_data->hardware_lock held - */ -static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id( - scsi_qla_host_t *vha, - const uint8_t *s_id) -{ - struct qla_hw_data *ha = vha->hw; - struct tcm_qla2xxx_lport *lport; - struct se_node_acl *se_nacl; - struct tcm_qla2xxx_nacl *nacl; - u32 key; - - lport = ha->tgt.target_lport_ptr; - if (!lport) { - pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); - dump_stack(); - return NULL; - } - - key = (((unsigned long)s_id[0] << 16) | - ((unsigned long)s_id[1] << 8) | - (unsigned long)s_id[2]); - pr_debug("find_sess_by_s_id: 0x%06x\n", key); - - se_nacl = btree_lookup32(&lport->lport_fcport_map, key); - if (!se_nacl) { - pr_debug("Unable to locate s_id: 0x%06x\n", key); - return NULL; - } - pr_debug("find_sess_by_s_id: located se_nacl: %p, initiatorname: %s\n", - se_nacl, se_nacl->initiatorname); - - nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); - if (!nacl->qla_tgt_sess) { - pr_err("Unable to locate struct qla_tgt_sess\n"); - return NULL; - } - - return nacl->qla_tgt_sess; -} - -/* - * Expected to be called with struct qla_hw_data->hardware_lock held - */ -static void tcm_qla2xxx_set_sess_by_s_id( - struct tcm_qla2xxx_lport *lport, - struct se_node_acl *new_se_nacl, - struct tcm_qla2xxx_nacl *nacl, - struct se_session *se_sess, - struct qla_tgt_sess *qla_tgt_sess, - uint8_t *s_id) -{ - u32 key; - void *slot; - int rc; - - key = (((unsigned long)s_id[0] << 16) | - ((unsigned long)s_id[1] << 8) | - (unsigned long)s_id[2]); - pr_debug("set_sess_by_s_id: %06x\n", key); - - slot = btree_lookup32(&lport->lport_fcport_map, key); - if (!slot) { - if (new_se_nacl) { - pr_debug("Setting up new fc_port entry to new_se_nacl\n"); - nacl->nport_id = key; - rc = btree_insert32(&lport->lport_fcport_map, key, - new_se_nacl, GFP_ATOMIC); - if (rc) - printk(KERN_ERR "Unable to insert s_id into fcport_map: %06x\n", - (int)key); - } else { - pr_debug("Wiping nonexisting fc_port entry\n"); - } - - qla_tgt_sess->se_sess = se_sess; - nacl->qla_tgt_sess = qla_tgt_sess; - return; - } - - if (nacl->qla_tgt_sess) { - if (new_se_nacl == NULL) { - pr_debug("Clearing existing nacl->qla_tgt_sess and fc_port entry\n"); - btree_remove32(&lport->lport_fcport_map, key); - nacl->qla_tgt_sess = NULL; - return; - } - pr_debug("Replacing existing nacl->qla_tgt_sess and fc_port entry\n"); - btree_update32(&lport->lport_fcport_map, key, new_se_nacl); - qla_tgt_sess->se_sess = se_sess; - nacl->qla_tgt_sess = qla_tgt_sess; - return; - } - - if (new_se_nacl == NULL) { - pr_debug("Clearing existing fc_port entry\n"); - btree_remove32(&lport->lport_fcport_map, key); - return; - } - - pr_debug("Replacing existing fc_port entry w/o active nacl->qla_tgt_sess\n"); - btree_update32(&lport->lport_fcport_map, key, new_se_nacl); - qla_tgt_sess->se_sess = se_sess; - nacl->qla_tgt_sess = qla_tgt_sess; - - pr_debug("Setup nacl->qla_tgt_sess %p by s_id for se_nacl: %p, initiatorname: %s\n", - nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); -} - -/* - * Expected to be called with struct qla_hw_data->hardware_lock held - */ -static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id( - scsi_qla_host_t *vha, - const uint16_t loop_id) -{ - struct qla_hw_data *ha = vha->hw; - struct tcm_qla2xxx_lport *lport; - struct se_node_acl *se_nacl; - struct tcm_qla2xxx_nacl *nacl; - struct tcm_qla2xxx_fc_loopid *fc_loopid; - - lport = ha->tgt.target_lport_ptr; - if (!lport) { - pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); - dump_stack(); - return NULL; - } - - pr_debug("find_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id); - - fc_loopid = lport->lport_loopid_map + loop_id; - se_nacl = fc_loopid->se_nacl; - if (!se_nacl) { - pr_debug("Unable to locate se_nacl by loop_id: 0x%04x\n", - loop_id); - return NULL; - } - - nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); - - if (!nacl->qla_tgt_sess) { - pr_err("Unable to locate struct qla_tgt_sess\n"); - return NULL; - } - - return nacl->qla_tgt_sess; -} - -/* - * Expected to be called with struct qla_hw_data->hardware_lock held - */ -static void tcm_qla2xxx_set_sess_by_loop_id( - struct tcm_qla2xxx_lport *lport, - struct se_node_acl *new_se_nacl, - struct tcm_qla2xxx_nacl *nacl, - struct se_session *se_sess, - struct qla_tgt_sess *qla_tgt_sess, - uint16_t loop_id) -{ - struct se_node_acl *saved_nacl; - struct tcm_qla2xxx_fc_loopid *fc_loopid; - - pr_debug("set_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id); - - fc_loopid = &((struct tcm_qla2xxx_fc_loopid *) - lport->lport_loopid_map)[loop_id]; - - saved_nacl = fc_loopid->se_nacl; - if (!saved_nacl) { - pr_debug("Setting up new fc_loopid->se_nacl to new_se_nacl\n"); - fc_loopid->se_nacl = new_se_nacl; - if (qla_tgt_sess->se_sess != se_sess) - qla_tgt_sess->se_sess = se_sess; - if (nacl->qla_tgt_sess != qla_tgt_sess) - nacl->qla_tgt_sess = qla_tgt_sess; - return; - } - - if (nacl->qla_tgt_sess) { - if (new_se_nacl == NULL) { - pr_debug("Clearing nacl->qla_tgt_sess and fc_loopid->se_nacl\n"); - fc_loopid->se_nacl = NULL; - nacl->qla_tgt_sess = NULL; - return; - } - - pr_debug("Replacing existing nacl->qla_tgt_sess and fc_loopid->se_nacl\n"); - fc_loopid->se_nacl = new_se_nacl; - if (qla_tgt_sess->se_sess != se_sess) - qla_tgt_sess->se_sess = se_sess; - if (nacl->qla_tgt_sess != qla_tgt_sess) - nacl->qla_tgt_sess = qla_tgt_sess; - return; - } - - if (new_se_nacl == NULL) { - pr_debug("Clearing fc_loopid->se_nacl\n"); - fc_loopid->se_nacl = NULL; - return; - } - - pr_debug("Replacing existing fc_loopid->se_nacl w/o active nacl->qla_tgt_sess\n"); - fc_loopid->se_nacl = new_se_nacl; - if (qla_tgt_sess->se_sess != se_sess) - qla_tgt_sess->se_sess = se_sess; - if (nacl->qla_tgt_sess != qla_tgt_sess) - nacl->qla_tgt_sess = qla_tgt_sess; - - pr_debug("Setup nacl->qla_tgt_sess %p by loop_id for se_nacl: %p, initiatorname: %s\n", - nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); -} - -static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) -{ - struct qla_tgt *tgt = sess->tgt; - struct qla_hw_data *ha = tgt->ha; - struct se_session *se_sess; - struct se_node_acl *se_nacl; - struct tcm_qla2xxx_lport *lport; - struct tcm_qla2xxx_nacl *nacl; - unsigned char be_sid[3]; - unsigned long flags; - - BUG_ON(in_interrupt()); - - se_sess = sess->se_sess; - if (!se_sess) { - pr_err("struct qla_tgt_sess->se_sess is NULL\n"); - dump_stack(); - return; - } - se_nacl = se_sess->se_node_acl; - nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); - - lport = ha->tgt.target_lport_ptr; - if (!lport) { - pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); - dump_stack(); - return; - } - target_wait_for_sess_cmds(se_sess, 0); - /* - * And now clear the se_nacl and session pointers from our HW lport - * mappings for fabric S_ID and LOOP_ID. - */ - memset(&be_sid, 0, 3); - be_sid[0] = sess->s_id.b.domain; - be_sid[1] = sess->s_id.b.area; - be_sid[2] = sess->s_id.b.al_pa; - - spin_lock_irqsave(&ha->hardware_lock, flags); - tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, - sess, be_sid); - tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, - sess, sess->loop_id); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - transport_deregister_session_configfs(sess->se_sess); - transport_deregister_session(sess->se_sess); -} - -/* - * Called via qlt_create_sess():ha->qla2x_tmpl->check_initiator_node_acl() - * to locate struct se_node_acl - */ -static int tcm_qla2xxx_check_initiator_node_acl( - scsi_qla_host_t *vha, - unsigned char *fc_wwpn, - void *qla_tgt_sess, - uint8_t *s_id, - uint16_t loop_id) -{ - struct qla_hw_data *ha = vha->hw; - struct tcm_qla2xxx_lport *lport; - struct tcm_qla2xxx_tpg *tpg; - struct tcm_qla2xxx_nacl *nacl; - struct se_portal_group *se_tpg; - struct se_node_acl *se_nacl; - struct se_session *se_sess; - struct qla_tgt_sess *sess = qla_tgt_sess; - unsigned char port_name[36]; - unsigned long flags; - - lport = ha->tgt.target_lport_ptr; - if (!lport) { - pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); - dump_stack(); - return -EINVAL; - } - /* - * Locate the TPG=1 reference.. - */ - tpg = lport->tpg_1; - if (!tpg) { - pr_err("Unable to lcoate struct tcm_qla2xxx_lport->tpg_1\n"); - return -EINVAL; - } - se_tpg = &tpg->se_tpg; - - se_sess = transport_init_session(); - if (IS_ERR(se_sess)) { - pr_err("Unable to initialize struct se_session\n"); - return PTR_ERR(se_sess); - } - /* - * Format the FCP Initiator port_name into colon seperated values to - * match the format by tcm_qla2xxx explict ConfigFS NodeACLs. - */ - memset(&port_name, 0, 36); - snprintf(port_name, 36, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - fc_wwpn[0], fc_wwpn[1], fc_wwpn[2], fc_wwpn[3], fc_wwpn[4], - fc_wwpn[5], fc_wwpn[6], fc_wwpn[7]); - /* - * Locate our struct se_node_acl either from an explict NodeACL created - * via ConfigFS, or via running in TPG demo mode. - */ - se_sess->se_node_acl = core_tpg_check_initiator_node_acl(se_tpg, - port_name); - if (!se_sess->se_node_acl) { - transport_free_session(se_sess); - return -EINVAL; - } - se_nacl = se_sess->se_node_acl; - nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); - /* - * And now setup the new se_nacl and session pointers into our HW lport - * mappings for fabric S_ID and LOOP_ID. - */ - spin_lock_irqsave(&ha->hardware_lock, flags); - tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess, - qla_tgt_sess, s_id); - tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess, - qla_tgt_sess, loop_id); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - /* - * Finally register the new FC Nexus with TCM - */ - __transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess); - - return 0; -} - -/* - * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. - */ -static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { - .handle_cmd = tcm_qla2xxx_handle_cmd, - .handle_data = tcm_qla2xxx_handle_data, - .handle_tmr = tcm_qla2xxx_handle_tmr, - .free_cmd = tcm_qla2xxx_free_cmd, - .free_mcmd = tcm_qla2xxx_free_mcmd, - .free_session = tcm_qla2xxx_free_session, - .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, - .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, - .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, - .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, - .put_sess = tcm_qla2xxx_put_sess, - .shutdown_sess = tcm_qla2xxx_shutdown_sess, -}; - -static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) -{ - int rc; - - rc = btree_init32(&lport->lport_fcport_map); - if (rc) { - pr_err("Unable to initialize lport->lport_fcport_map btree\n"); - return rc; - } - - lport->lport_loopid_map = vmalloc(sizeof(struct tcm_qla2xxx_fc_loopid) * - 65536); - if (!lport->lport_loopid_map) { - pr_err("Unable to allocate lport->lport_loopid_map of %zu bytes\n", - sizeof(struct tcm_qla2xxx_fc_loopid) * 65536); - btree_destroy32(&lport->lport_fcport_map); - return -ENOMEM; - } - memset(lport->lport_loopid_map, 0, sizeof(struct tcm_qla2xxx_fc_loopid) - * 65536); - pr_debug("qla2xxx: Allocated lport_loopid_map of %zu bytes\n", - sizeof(struct tcm_qla2xxx_fc_loopid) * 65536); - return 0; -} - -static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha) -{ - struct qla_hw_data *ha = vha->hw; - struct tcm_qla2xxx_lport *lport; - /* - * Setup local pointer to vha, NPIV VP pointer (if present) and - * vha->tcm_lport pointer - */ - lport = (struct tcm_qla2xxx_lport *)ha->tgt.target_lport_ptr; - lport->qla_vha = vha; - - return 0; -} - -static struct se_wwn *tcm_qla2xxx_make_lport( - struct target_fabric_configfs *tf, - struct config_group *group, - const char *name) -{ - struct tcm_qla2xxx_lport *lport; - u64 wwpn; - int ret = -ENODEV; - - if (tcm_qla2xxx_parse_wwn(name, &wwpn, 1) < 0) - return ERR_PTR(-EINVAL); - - lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); - if (!lport) { - pr_err("Unable to allocate struct tcm_qla2xxx_lport\n"); - return ERR_PTR(-ENOMEM); - } - lport->lport_wwpn = wwpn; - tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, - wwpn); - - ret = tcm_qla2xxx_init_lport(lport); - if (ret != 0) - goto out; - - ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn, - tcm_qla2xxx_lport_register_cb, lport); - if (ret != 0) - goto out_lport; - - return &lport->lport_wwn; -out_lport: - vfree(lport->lport_loopid_map); - btree_destroy32(&lport->lport_fcport_map); -out: - kfree(lport); - return ERR_PTR(ret); -} - -static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn) -{ - struct tcm_qla2xxx_lport *lport = container_of(wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct scsi_qla_host *vha = lport->qla_vha; - struct qla_hw_data *ha = vha->hw; - struct se_node_acl *node; - u32 key = 0; - - /* - * Call into qla2x_target.c LLD logic to complete the - * shutdown of struct qla_tgt after the call to - * qlt_stop_phase1() from tcm_qla2xxx_drop_tpg() above.. - */ - if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stopped) - qlt_stop_phase2(ha->tgt.qla_tgt); - - qlt_lport_deregister(vha); - - vfree(lport->lport_loopid_map); - btree_for_each_safe32(&lport->lport_fcport_map, key, node) - btree_remove32(&lport->lport_fcport_map, key); - btree_destroy32(&lport->lport_fcport_map); - kfree(lport); -} - -static struct se_wwn *tcm_qla2xxx_npiv_make_lport( - struct target_fabric_configfs *tf, - struct config_group *group, - const char *name) -{ - struct tcm_qla2xxx_lport *lport; - u64 npiv_wwpn, npiv_wwnn; - int ret; - - if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1, - &npiv_wwpn, &npiv_wwnn) < 0) - return ERR_PTR(-EINVAL); - - lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); - if (!lport) { - pr_err("Unable to allocate struct tcm_qla2xxx_lport for NPIV\n"); - return ERR_PTR(-ENOMEM); - } - lport->lport_npiv_wwpn = npiv_wwpn; - lport->lport_npiv_wwnn = npiv_wwnn; - tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], - TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); - -/* FIXME: tcm_qla2xxx_npiv_make_lport */ - ret = -ENOSYS; - if (ret != 0) - goto out; - - return &lport->lport_wwn; -out: - kfree(lport); - return ERR_PTR(ret); -} - -static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn) -{ - struct tcm_qla2xxx_lport *lport = container_of(wwn, - struct tcm_qla2xxx_lport, lport_wwn); - struct scsi_qla_host *vha = lport->qla_vha; - struct Scsi_Host *sh = vha->host; - /* - * Notify libfc that we want to release the lport->npiv_vport - */ - fc_vport_terminate(lport->npiv_vport); - - scsi_host_put(sh); - kfree(lport); -} - - -static ssize_t tcm_qla2xxx_wwn_show_attr_version( - struct target_fabric_configfs *tf, - char *page) -{ - return sprintf(page, - "TCM QLOGIC QLA2XXX NPIV capable fabric module %s on %s/%s on " - UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, - utsname()->machine); -} - -TF_WWN_ATTR_RO(tcm_qla2xxx, version); - -static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = { - &tcm_qla2xxx_wwn_version.attr, - NULL, -}; - -static struct target_core_fabric_ops tcm_qla2xxx_ops = { - .get_fabric_name = tcm_qla2xxx_get_fabric_name, - .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, - .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, - .tpg_get_tag = tcm_qla2xxx_get_tag, - .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, - .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, - .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, - .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, - .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode, - .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache, - .tpg_check_demo_mode_write_protect = - tcm_qla2xxx_check_demo_write_protect, - .tpg_check_prod_mode_write_protect = - tcm_qla2xxx_check_prod_write_protect, - .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_true, - .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, - .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, - .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, - .new_cmd_map = NULL, - .check_stop_free = tcm_qla2xxx_check_stop_free, - .release_cmd = tcm_qla2xxx_release_cmd, - .shutdown_session = tcm_qla2xxx_shutdown_session, - .close_session = tcm_qla2xxx_close_session, - .sess_get_index = tcm_qla2xxx_sess_get_index, - .sess_get_initiator_sid = NULL, - .write_pending = tcm_qla2xxx_write_pending, - .write_pending_status = tcm_qla2xxx_write_pending_status, - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, - .get_task_tag = tcm_qla2xxx_get_task_tag, - .get_cmd_state = tcm_qla2xxx_get_cmd_state, - .queue_data_in = tcm_qla2xxx_queue_data_in, - .queue_status = tcm_qla2xxx_queue_status, - .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, - /* - * Setup function pointers for generic logic in - * target_core_fabric_configfs.c - */ - .fabric_make_wwn = tcm_qla2xxx_make_lport, - .fabric_drop_wwn = tcm_qla2xxx_drop_lport, - .fabric_make_tpg = tcm_qla2xxx_make_tpg, - .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, - .fabric_post_link = NULL, - .fabric_pre_unlink = NULL, - .fabric_make_np = NULL, - .fabric_drop_np = NULL, - .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, - .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, -}; - -static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { - .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, - .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, - .tpg_get_wwn = tcm_qla2xxx_npiv_get_fabric_wwn, - .tpg_get_tag = tcm_qla2xxx_get_tag, - .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, - .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, - .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, - .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, - .tpg_check_demo_mode = tcm_qla2xxx_check_false, - .tpg_check_demo_mode_cache = tcm_qla2xxx_check_true, - .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_true, - .tpg_check_prod_mode_write_protect = tcm_qla2xxx_check_false, - .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_true, - .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, - .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, - .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, - .release_cmd = tcm_qla2xxx_release_cmd, - .shutdown_session = tcm_qla2xxx_shutdown_session, - .close_session = tcm_qla2xxx_close_session, - .sess_get_index = tcm_qla2xxx_sess_get_index, - .sess_get_initiator_sid = NULL, - .write_pending = tcm_qla2xxx_write_pending, - .write_pending_status = tcm_qla2xxx_write_pending_status, - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, - .get_task_tag = tcm_qla2xxx_get_task_tag, - .get_cmd_state = tcm_qla2xxx_get_cmd_state, - .queue_data_in = tcm_qla2xxx_queue_data_in, - .queue_status = tcm_qla2xxx_queue_status, - .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, - /* - * Setup function pointers for generic logic in - * target_core_fabric_configfs.c - */ - .fabric_make_wwn = tcm_qla2xxx_npiv_make_lport, - .fabric_drop_wwn = tcm_qla2xxx_npiv_drop_lport, - .fabric_make_tpg = tcm_qla2xxx_npiv_make_tpg, - .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, - .fabric_post_link = NULL, - .fabric_pre_unlink = NULL, - .fabric_make_np = NULL, - .fabric_drop_np = NULL, - .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, - .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, -}; - -static int tcm_qla2xxx_register_configfs(void) -{ - struct target_fabric_configfs *fabric, *npiv_fabric; - int ret; - - pr_debug("TCM QLOGIC QLA2XXX fabric module %s on %s/%s on " - UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, - utsname()->machine); - /* - * Register the top level struct config_item_type with TCM core - */ - fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx"); - if (IS_ERR(fabric)) { - pr_err("target_fabric_configfs_init() failed\n"); - return PTR_ERR(fabric); - } - /* - * Setup fabric->tf_ops from our local tcm_qla2xxx_ops - */ - fabric->tf_ops = tcm_qla2xxx_ops; - /* - * Setup default attribute lists for various fabric->tf_cit_tmpl - */ - TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_qla2xxx_tpg_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = - tcm_qla2xxx_tpg_attrib_attrs; - TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the fabric for use within TCM - */ - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); - return ret; - } - /* - * Setup our local pointer to *fabric - */ - tcm_qla2xxx_fabric_configfs = fabric; - pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_fabric_configfs\n"); - - /* - * Register the top level struct config_item_type for NPIV with TCM core - */ - npiv_fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx_npiv"); - if (IS_ERR(npiv_fabric)) { - pr_err("target_fabric_configfs_init() failed\n"); - ret = PTR_ERR(npiv_fabric); - goto out_fabric; - } - /* - * Setup fabric->tf_ops from our local tcm_qla2xxx_npiv_ops - */ - npiv_fabric->tf_ops = tcm_qla2xxx_npiv_ops; - /* - * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl - */ - TF_CIT_TMPL(npiv_fabric)->tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_param_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the npiv_fabric for use within TCM - */ - ret = target_fabric_configfs_register(npiv_fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); - goto out_fabric; - } - /* - * Setup our local pointer to *npiv_fabric - */ - tcm_qla2xxx_npiv_fabric_configfs = npiv_fabric; - pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_npiv_fabric_configfs\n"); - - tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free", - WQ_MEM_RECLAIM, 0); - if (!tcm_qla2xxx_free_wq) { - ret = -ENOMEM; - goto out_fabric_npiv; - } - - tcm_qla2xxx_cmd_wq = alloc_workqueue("tcm_qla2xxx_cmd", 0, 0); - if (!tcm_qla2xxx_cmd_wq) { - ret = -ENOMEM; - goto out_free_wq; - } - - return 0; - -out_free_wq: - destroy_workqueue(tcm_qla2xxx_free_wq); -out_fabric_npiv: - target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); -out_fabric: - target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); - return ret; -} - -static void tcm_qla2xxx_deregister_configfs(void) -{ - destroy_workqueue(tcm_qla2xxx_cmd_wq); - destroy_workqueue(tcm_qla2xxx_free_wq); - - target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); - tcm_qla2xxx_fabric_configfs = NULL; - pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_fabric_configfs\n"); - - target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); - tcm_qla2xxx_npiv_fabric_configfs = NULL; - pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_npiv_fabric_configfs\n"); -} - -static int __init tcm_qla2xxx_init(void) -{ - int ret; - - ret = tcm_qla2xxx_register_configfs(); - if (ret < 0) - return ret; - - return 0; -} - -static void __exit tcm_qla2xxx_exit(void) -{ - tcm_qla2xxx_deregister_configfs(); -} - -MODULE_DESCRIPTION("TCM QLA2XXX series NPIV enabled fabric driver"); -MODULE_LICENSE("GPL"); -module_init(tcm_qla2xxx_init); -module_exit(tcm_qla2xxx_exit); diff --git a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h deleted file mode 100644 index 825498103352..000000000000 --- a/trunk/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -#define TCM_QLA2XXX_VERSION "v0.1" -/* length of ASCII WWPNs including pad */ -#define TCM_QLA2XXX_NAMELEN 32 -/* lenth of ASCII NPIV 'WWPN+WWNN' including pad */ -#define TCM_QLA2XXX_NPIV_NAMELEN 66 - -#include "qla_target.h" - -struct tcm_qla2xxx_nacl { - /* From libfc struct fc_rport->port_id */ - u32 nport_id; - /* Binary World Wide unique Node Name for remote FC Initiator Nport */ - u64 nport_wwnn; - /* ASCII formatted WWPN for FC Initiator Nport */ - char nport_name[TCM_QLA2XXX_NAMELEN]; - /* Pointer to qla_tgt_sess */ - struct qla_tgt_sess *qla_tgt_sess; - /* Pointer to TCM FC nexus */ - struct se_session *nport_nexus; - /* Returned by tcm_qla2xxx_make_nodeacl() */ - struct se_node_acl se_node_acl; -}; - -struct tcm_qla2xxx_tpg_attrib { - int generate_node_acls; - int cache_dynamic_acls; - int demo_mode_write_protect; - int prod_mode_write_protect; -}; - -struct tcm_qla2xxx_tpg { - /* FC lport target portal group tag for TCM */ - u16 lport_tpgt; - /* Atomic bit to determine TPG active status */ - atomic_t lport_tpg_enabled; - /* Pointer back to tcm_qla2xxx_lport */ - struct tcm_qla2xxx_lport *lport; - /* Used by tcm_qla2xxx_tpg_attrib_cit */ - struct tcm_qla2xxx_tpg_attrib tpg_attrib; - /* Returned by tcm_qla2xxx_make_tpg() */ - struct se_portal_group se_tpg; -}; - -#define QLA_TPG_ATTRIB(tpg) (&(tpg)->tpg_attrib) - -struct tcm_qla2xxx_fc_loopid { - struct se_node_acl *se_nacl; -}; - -struct tcm_qla2xxx_lport { - /* SCSI protocol the lport is providing */ - u8 lport_proto_id; - /* Binary World Wide unique Port Name for FC Target Lport */ - u64 lport_wwpn; - /* Binary World Wide unique Port Name for FC NPIV Target Lport */ - u64 lport_npiv_wwpn; - /* Binary World Wide unique Node Name for FC NPIV Target Lport */ - u64 lport_npiv_wwnn; - /* ASCII formatted WWPN for FC Target Lport */ - char lport_name[TCM_QLA2XXX_NAMELEN]; - /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ - char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; - /* map for fc_port pointers in 24-bit FC Port ID space */ - struct btree_head32 lport_fcport_map; - /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ - struct tcm_qla2xxx_fc_loopid *lport_loopid_map; - /* Pointer to struct scsi_qla_host from qla2xxx LLD */ - struct scsi_qla_host *qla_vha; - /* Pointer to struct scsi_qla_host for NPIV VP from qla2xxx LLD */ - struct scsi_qla_host *qla_npiv_vp; - /* Pointer to struct qla_tgt pointer */ - struct qla_tgt lport_qla_tgt; - /* Pointer to struct fc_vport for NPIV vport from libfc */ - struct fc_vport *npiv_vport; - /* Pointer to TPG=1 for non NPIV mode */ - struct tcm_qla2xxx_tpg *tpg_1; - /* Returned by tcm_qla2xxx_make_lport() */ - struct se_wwn lport_wwn; -}; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_attr.c b/trunk/drivers/scsi/qla4xxx/ql4_attr.c index c681b2a355e1..0b0a7d42137d 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_attr.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_attr.c @@ -9,140 +9,6 @@ #include "ql4_glbl.h" #include "ql4_dbg.h" -static ssize_t -qla4_8xxx_sysfs_read_fw_dump(struct file *filep, struct kobject *kobj, - struct bin_attribute *ba, char *buf, loff_t off, - size_t count) -{ - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, - struct device, kobj))); - - if (!is_qla8022(ha)) - return -EINVAL; - - if (!test_bit(AF_82XX_DUMP_READING, &ha->flags)) - return 0; - - return memory_read_from_buffer(buf, count, &off, ha->fw_dump, - ha->fw_dump_size); -} - -static ssize_t -qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj, - struct bin_attribute *ba, char *buf, loff_t off, - size_t count) -{ - struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, - struct device, kobj))); - uint32_t dev_state; - long reading; - int ret = 0; - - if (!is_qla8022(ha)) - return -EINVAL; - - if (off != 0) - return ret; - - buf[1] = 0; - ret = kstrtol(buf, 10, &reading); - if (ret) { - ql4_printk(KERN_ERR, ha, "%s: Invalid input. Return err %d\n", - __func__, ret); - return ret; - } - - switch (reading) { - case 0: - /* clear dump collection flags */ - if (test_and_clear_bit(AF_82XX_DUMP_READING, &ha->flags)) { - clear_bit(AF_82XX_FW_DUMPED, &ha->flags); - /* Reload minidump template */ - qla4xxx_alloc_fw_dump(ha); - DEBUG2(ql4_printk(KERN_INFO, ha, - "Firmware template reloaded\n")); - } - break; - case 1: - /* Set flag to read dump */ - if (test_bit(AF_82XX_FW_DUMPED, &ha->flags) && - !test_bit(AF_82XX_DUMP_READING, &ha->flags)) { - set_bit(AF_82XX_DUMP_READING, &ha->flags); - DEBUG2(ql4_printk(KERN_INFO, ha, - "Raw firmware dump ready for read on (%ld).\n", - ha->host_no)); - } - break; - case 2: - /* Reset HBA */ - qla4_8xxx_idc_lock(ha); - dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - if (dev_state == QLA82XX_DEV_READY) { - ql4_printk(KERN_INFO, ha, - "%s: Setting Need reset, reset_owner is 0x%x.\n", - __func__, ha->func_num); - qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, - QLA82XX_DEV_NEED_RESET); - set_bit(AF_82XX_RST_OWNER, &ha->flags); - } else - ql4_printk(KERN_INFO, ha, - "%s: Reset not performed as device state is 0x%x\n", - __func__, dev_state); - - qla4_8xxx_idc_unlock(ha); - break; - default: - /* do nothing */ - break; - } - - return count; -} - -static struct bin_attribute sysfs_fw_dump_attr = { - .attr = { - .name = "fw_dump", - .mode = S_IRUSR | S_IWUSR, - }, - .size = 0, - .read = qla4_8xxx_sysfs_read_fw_dump, - .write = qla4_8xxx_sysfs_write_fw_dump, -}; - -static struct sysfs_entry { - char *name; - struct bin_attribute *attr; -} bin_file_entries[] = { - { "fw_dump", &sysfs_fw_dump_attr }, - { NULL }, -}; - -void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha) -{ - struct Scsi_Host *host = ha->host; - struct sysfs_entry *iter; - int ret; - - for (iter = bin_file_entries; iter->name; iter++) { - ret = sysfs_create_bin_file(&host->shost_gendev.kobj, - iter->attr); - if (ret) - ql4_printk(KERN_ERR, ha, - "Unable to create sysfs %s binary attribute (%d).\n", - iter->name, ret); - } -} - -void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha) -{ - struct Scsi_Host *host = ha->host; - struct sysfs_entry *iter; - - for (iter = bin_file_entries; iter->name; iter++) - sysfs_remove_bin_file(&host->shost_gendev.kobj, - iter->attr); -} - /* Scsi_Host attributes. */ static ssize_t qla4xxx_fw_version_show(struct device *dev, diff --git a/trunk/drivers/scsi/qla4xxx/ql4_def.h b/trunk/drivers/scsi/qla4xxx/ql4_def.h index 96a5616a8fda..7f2492e88be7 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_def.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_def.h @@ -398,16 +398,6 @@ struct isp_operations { int (*get_sys_info) (struct scsi_qla_host *); }; -struct ql4_mdump_size_table { - uint32_t size; - uint32_t size_cmask_02; - uint32_t size_cmask_04; - uint32_t size_cmask_08; - uint32_t size_cmask_10; - uint32_t size_cmask_FF; - uint32_t version; -}; - /*qla4xxx ipaddress configuration details */ struct ipaddress_config { uint16_t ipv4_options; @@ -495,10 +485,6 @@ struct scsi_qla_host { #define AF_EEH_BUSY 20 /* 0x00100000 */ #define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ #define AF_BUILD_DDB_LIST 22 /* 0x00400000 */ -#define AF_82XX_FW_DUMPED 24 /* 0x01000000 */ -#define AF_82XX_RST_OWNER 25 /* 0x02000000 */ -#define AF_82XX_DUMP_READING 26 /* 0x04000000 */ - unsigned long dpc_flags; #define DPC_RESET_HA 1 /* 0x00000002 */ @@ -676,11 +662,6 @@ struct scsi_qla_host { uint32_t nx_dev_init_timeout; uint32_t nx_reset_timeout; - void *fw_dump; - uint32_t fw_dump_size; - uint32_t fw_dump_capture_mask; - void *fw_dump_tmplt_hdr; - uint32_t fw_dump_tmplt_size; struct completion mbx_intr_comp; @@ -955,7 +936,4 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha) #define PROCESS_ALL_AENS 0 #define FLUSH_DDB_CHANGED_AENS 1 -/* Defines for udev events */ -#define QL4_UEVENT_CODE_FW_DUMP 0 - #endif /*_QLA4XXX_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_fw.h b/trunk/drivers/scsi/qla4xxx/ql4_fw.h index 7240948fb929..210cd1d64475 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_fw.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_fw.h @@ -385,11 +385,6 @@ struct qla_flt_region { #define MBOX_CMD_GET_IP_ADDR_STATE 0x0091 #define MBOX_CMD_SEND_IPV6_ROUTER_SOL 0x0092 #define MBOX_CMD_GET_DB_ENTRY_CURRENT_IP_ADDR 0x0093 -#define MBOX_CMD_MINIDUMP 0x0129 - -/* Minidump subcommand */ -#define MINIDUMP_GET_SIZE_SUBCOMMAND 0x00 -#define MINIDUMP_GET_TMPLT_SUBCOMMAND 0x01 /* Mailbox 1 */ #define FW_STATE_READY 0x0000 @@ -1195,27 +1190,4 @@ struct ql_iscsi_stats { uint8_t reserved2[264]; /* 0x0308 - 0x040F */ }; -#define QLA82XX_DBG_STATE_ARRAY_LEN 16 -#define QLA82XX_DBG_CAP_SIZE_ARRAY_LEN 8 -#define QLA82XX_DBG_RSVD_ARRAY_LEN 8 - -struct qla4_8xxx_minidump_template_hdr { - uint32_t entry_type; - uint32_t first_entry_offset; - uint32_t size_of_template; - uint32_t capture_debug_level; - uint32_t num_of_entries; - uint32_t version; - uint32_t driver_timestamp; - uint32_t checksum; - - uint32_t driver_capture_mask; - uint32_t driver_info_word2; - uint32_t driver_info_word3; - uint32_t driver_info_word4; - - uint32_t saved_state_array[QLA82XX_DBG_STATE_ARRAY_LEN]; - uint32_t capture_size_array[QLA82XX_DBG_CAP_SIZE_ARRAY_LEN]; -}; - #endif /* _QLA4X_FW_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h index 20b49d019043..910536667cf5 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h @@ -196,18 +196,10 @@ int qla4xxx_bsg_request(struct bsg_job *bsg_job); int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry); -int qla4xxx_get_minidump_template(struct scsi_qla_host *ha, - dma_addr_t phys_addr); -int qla4xxx_req_template_size(struct scsi_qla_host *ha); -void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha); -void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha); -void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha); extern int ql4xextended_error_logging; extern int ql4xdontresethba; extern int ql4xenablemsix; -extern int ql4xmdcapmask; -extern int ql4xenablemd; extern struct device_attribute *qla4xxx_host_attrs[]; #endif /* _QLA4x_GBL_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_init.c b/trunk/drivers/scsi/qla4xxx/ql4_init.c index bf36723b84e1..90ee5d8fa731 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_init.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_init.c @@ -277,94 +277,6 @@ qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha) return ipv4_wait|ipv6_wait; } -/** - * qla4xxx_alloc_fw_dump - Allocate memory for minidump data. - * @ha: pointer to host adapter structure. - **/ -void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha) -{ - int status; - uint32_t capture_debug_level; - int hdr_entry_bit, k; - void *md_tmp; - dma_addr_t md_tmp_dma; - struct qla4_8xxx_minidump_template_hdr *md_hdr; - - if (ha->fw_dump) { - ql4_printk(KERN_WARNING, ha, - "Firmware dump previously allocated.\n"); - return; - } - - status = qla4xxx_req_template_size(ha); - if (status != QLA_SUCCESS) { - ql4_printk(KERN_INFO, ha, - "scsi%ld: Failed to get template size\n", - ha->host_no); - return; - } - - clear_bit(AF_82XX_FW_DUMPED, &ha->flags); - - /* Allocate memory for saving the template */ - md_tmp = dma_alloc_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, - &md_tmp_dma, GFP_KERNEL); - - /* Request template */ - status = qla4xxx_get_minidump_template(ha, md_tmp_dma); - if (status != QLA_SUCCESS) { - ql4_printk(KERN_INFO, ha, - "scsi%ld: Failed to get minidump template\n", - ha->host_no); - goto alloc_cleanup; - } - - md_hdr = (struct qla4_8xxx_minidump_template_hdr *)md_tmp; - - capture_debug_level = md_hdr->capture_debug_level; - - /* Get capture mask based on module loadtime setting. */ - if (ql4xmdcapmask >= 0x3 && ql4xmdcapmask <= 0x7F) - ha->fw_dump_capture_mask = ql4xmdcapmask; - else - ha->fw_dump_capture_mask = capture_debug_level; - - md_hdr->driver_capture_mask = ha->fw_dump_capture_mask; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Minimum num of entries = %d\n", - md_hdr->num_of_entries)); - DEBUG2(ql4_printk(KERN_INFO, ha, "Dump template size = %d\n", - ha->fw_dump_tmplt_size)); - DEBUG2(ql4_printk(KERN_INFO, ha, "Selected Capture mask =0x%x\n", - ha->fw_dump_capture_mask)); - - /* Calculate fw_dump_size */ - for (hdr_entry_bit = 0x2, k = 1; (hdr_entry_bit & 0xFF); - hdr_entry_bit <<= 1, k++) { - if (hdr_entry_bit & ha->fw_dump_capture_mask) - ha->fw_dump_size += md_hdr->capture_size_array[k]; - } - - /* Total firmware dump size including command header */ - ha->fw_dump_size += ha->fw_dump_tmplt_size; - ha->fw_dump = vmalloc(ha->fw_dump_size); - if (!ha->fw_dump) - goto alloc_cleanup; - - DEBUG2(ql4_printk(KERN_INFO, ha, - "Minidump Tempalate Size = 0x%x KB\n", - ha->fw_dump_tmplt_size)); - DEBUG2(ql4_printk(KERN_INFO, ha, - "Total Minidump size = 0x%x KB\n", ha->fw_dump_size)); - - memcpy(ha->fw_dump, md_tmp, ha->fw_dump_tmplt_size); - ha->fw_dump_tmplt_hdr = ha->fw_dump; - -alloc_cleanup: - dma_free_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, - md_tmp, md_tmp_dma); -} - static int qla4xxx_fw_ready(struct scsi_qla_host *ha) { uint32_t timeout_count; @@ -533,13 +445,9 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) "control block\n", ha->host_no, __func__)); return status; } - if (!qla4xxx_fw_ready(ha)) return status; - if (is_qla8022(ha) && !test_bit(AF_INIT_DONE, &ha->flags)) - qla4xxx_alloc_fw_dump(ha); - return qla4xxx_get_firmware_status(ha); } @@ -976,8 +884,8 @@ int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, switch (state) { case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY: - qla4xxx_update_session_conn_param(ha, ddb_entry); ddb_entry->unblock_sess(ddb_entry->sess); + qla4xxx_update_session_conn_param(ha, ddb_entry); status = QLA_SUCCESS; break; case DDB_DS_SESSION_FAILED: @@ -989,7 +897,6 @@ int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, } break; case DDB_DS_SESSION_ACTIVE: - case DDB_DS_DISCOVERY: switch (state) { case DDB_DS_SESSION_FAILED: /* diff --git a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c b/trunk/drivers/scsi/qla4xxx/ql4_mbx.c index cab8f665a41f..7ac21dabbf22 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_mbx.c @@ -51,6 +51,25 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, } } + if (is_qla8022(ha)) { + if (test_bit(AF_FW_RECOVERY, &ha->flags)) { + DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " + "prematurely completing mbx cmd as firmware " + "recovery detected\n", ha->host_no, __func__)); + return status; + } + /* Do not send any mbx cmd if h/w is in failed state*/ + qla4_8xxx_idc_lock(ha); + dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); + qla4_8xxx_idc_unlock(ha); + if (dev_state == QLA82XX_DEV_FAILED) { + ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in " + "failed state, do not send any mailbox commands\n", + ha->host_no, __func__); + return status; + } + } + if ((is_aer_supported(ha)) && (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " @@ -77,25 +96,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, msleep(10); } - if (is_qla8022(ha)) { - if (test_bit(AF_FW_RECOVERY, &ha->flags)) { - DEBUG2(ql4_printk(KERN_WARNING, ha, - "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n", - ha->host_no, __func__)); - goto mbox_exit; - } - /* Do not send any mbx cmd if h/w is in failed state*/ - qla4_8xxx_idc_lock(ha); - dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - qla4_8xxx_idc_unlock(ha); - if (dev_state == QLA82XX_DEV_FAILED) { - ql4_printk(KERN_WARNING, ha, - "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n", - ha->host_no, __func__); - goto mbox_exit; - } - } - spin_lock_irqsave(&ha->hardware_lock, flags); ha->mbox_status_count = outCount; @@ -270,79 +270,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, return status; } -/** - * qla4xxx_get_minidump_template - Get the firmware template - * @ha: Pointer to host adapter structure. - * @phys_addr: dma address for template - * - * Obtain the minidump template from firmware during initialization - * as it may not be available when minidump is desired. - **/ -int qla4xxx_get_minidump_template(struct scsi_qla_host *ha, - dma_addr_t phys_addr) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - int status; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - - mbox_cmd[0] = MBOX_CMD_MINIDUMP; - mbox_cmd[1] = MINIDUMP_GET_TMPLT_SUBCOMMAND; - mbox_cmd[2] = LSDW(phys_addr); - mbox_cmd[3] = MSDW(phys_addr); - mbox_cmd[4] = ha->fw_dump_tmplt_size; - mbox_cmd[5] = 0; - - status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], - &mbox_sts[0]); - if (status != QLA_SUCCESS) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "scsi%ld: %s: Cmd = %08X, mbx[0] = 0x%04x, mbx[1] = 0x%04x\n", - ha->host_no, __func__, mbox_cmd[0], - mbox_sts[0], mbox_sts[1])); - } - return status; -} - -/** - * qla4xxx_req_template_size - Get minidump template size from firmware. - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_req_template_size(struct scsi_qla_host *ha) -{ - uint32_t mbox_cmd[MBOX_REG_COUNT]; - uint32_t mbox_sts[MBOX_REG_COUNT]; - int status; - - memset(&mbox_cmd, 0, sizeof(mbox_cmd)); - memset(&mbox_sts, 0, sizeof(mbox_sts)); - - mbox_cmd[0] = MBOX_CMD_MINIDUMP; - mbox_cmd[1] = MINIDUMP_GET_SIZE_SUBCOMMAND; - - status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0], - &mbox_sts[0]); - if (status == QLA_SUCCESS) { - ha->fw_dump_tmplt_size = mbox_sts[1]; - DEBUG2(ql4_printk(KERN_INFO, ha, - "%s: sts[0]=0x%04x, template size=0x%04x, size_cm_02=0x%04x, size_cm_04=0x%04x, size_cm_08=0x%04x, size_cm_10=0x%04x, size_cm_FF=0x%04x, version=0x%04x\n", - __func__, mbox_sts[0], mbox_sts[1], - mbox_sts[2], mbox_sts[3], mbox_sts[4], - mbox_sts[5], mbox_sts[6], mbox_sts[7])); - if (ha->fw_dump_tmplt_size == 0) - status = QLA_ERROR; - } else { - ql4_printk(KERN_WARNING, ha, - "%s: Error sts[0]=0x%04x, mbx[1]=0x%04x\n", - __func__, mbox_sts[0], mbox_sts[1]); - status = QLA_ERROR; - } - - return status; -} - void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha) { set_bit(AF_FW_RECOVERY, &ha->flags); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nx.c b/trunk/drivers/scsi/qla4xxx/ql4_nx.c index 228b67020d2c..e1e46b6dac75 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_nx.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_nx.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "ql4_def.h" #include "ql4_glbl.h" @@ -421,38 +420,6 @@ qla4_8xxx_rd_32(struct scsi_qla_host *ha, ulong off) return data; } -/* Minidump related functions */ -static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off, - u32 data, uint8_t flag) -{ - uint32_t win_read, off_value, rval = QLA_SUCCESS; - - off_value = off & 0xFFFF0000; - writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase)); - - /* Read back value to make sure write has gone through before trying - * to use it. - */ - win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase)); - if (win_read != off_value) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "%s: Written (0x%x) != Read (0x%x), off=0x%x\n", - __func__, off_value, win_read, off)); - return QLA_ERROR; - } - - off_value = off & 0x0000FFFF; - - if (flag) - writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M + - ha->nx_pcibase)); - else - rval = readl((void __iomem *)(off_value + CRB_INDIRECT_2M + - ha->nx_pcibase)); - - return rval; -} - #define CRB_WIN_LOCK_TIMEOUT 100000000 int qla4_8xxx_crb_win_lock(struct scsi_qla_host *ha) @@ -1285,9 +1252,9 @@ qla4_8xxx_pci_mem_read_2M(struct scsi_qla_host *ha, } if (j >= MAX_CTL_CHECK) { - printk_ratelimited(KERN_ERR - "%s: failed to read through agent\n", - __func__); + if (printk_ratelimit()) + ql4_printk(KERN_ERR, ha, + "failed to read through agent\n"); break; } @@ -1423,8 +1390,7 @@ qla4_8xxx_pci_mem_write_2M(struct scsi_qla_host *ha, if (j >= MAX_CTL_CHECK) { if (printk_ratelimit()) ql4_printk(KERN_ERR, ha, - "%s: failed to read through agent\n", - __func__); + "failed to write through agent\n"); ret = -1; break; } @@ -1496,8 +1462,6 @@ qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); drv_active |= (1 << (ha->func_num * 4)); - ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", - __func__, ha->host_no, drv_active); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); } @@ -1508,8 +1472,6 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha) drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); drv_active &= ~(1 << (ha->func_num * 4)); - ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", - __func__, ha->host_no, drv_active); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); } @@ -1535,8 +1497,6 @@ qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha) drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE); drv_state |= (1 << (ha->func_num * 4)); - ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", - __func__, ha->host_no, drv_state); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state); } @@ -1547,8 +1507,6 @@ qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha) drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE); drv_state &= ~(1 << (ha->func_num * 4)); - ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", - __func__, ha->host_no, drv_state); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state); } @@ -1643,629 +1601,6 @@ static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha) qla4_8xxx_rom_unlock(ha); } -static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t r_addr, r_stride, loop_cnt, i, r_value; - struct qla82xx_minidump_entry_crb *crb_hdr; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - crb_hdr = (struct qla82xx_minidump_entry_crb *)entry_hdr; - r_addr = crb_hdr->addr; - r_stride = crb_hdr->crb_strd.addr_stride; - loop_cnt = crb_hdr->op_count; - - for (i = 0; i < loop_cnt; i++) { - r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); - *data_ptr++ = cpu_to_le32(r_addr); - *data_ptr++ = cpu_to_le32(r_value); - r_addr += r_stride; - } - *d_ptr = data_ptr; -} - -static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t addr, r_addr, c_addr, t_r_addr; - uint32_t i, k, loop_count, t_value, r_cnt, r_value; - unsigned long p_wait, w_time, p_mask; - uint32_t c_value_w, c_value_r; - struct qla82xx_minidump_entry_cache *cache_hdr; - int rval = QLA_ERROR; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr; - - loop_count = cache_hdr->op_count; - r_addr = cache_hdr->read_addr; - c_addr = cache_hdr->control_addr; - c_value_w = cache_hdr->cache_ctrl.write_value; - - t_r_addr = cache_hdr->tag_reg_addr; - t_value = cache_hdr->addr_ctrl.init_tag_value; - r_cnt = cache_hdr->read_ctrl.read_addr_cnt; - p_wait = cache_hdr->cache_ctrl.poll_wait; - p_mask = cache_hdr->cache_ctrl.poll_mask; - - for (i = 0; i < loop_count; i++) { - qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1); - - if (c_value_w) - qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1); - - if (p_mask) { - w_time = jiffies + p_wait; - do { - c_value_r = qla4_8xxx_md_rw_32(ha, c_addr, - 0, 0); - if ((c_value_r & p_mask) == 0) { - break; - } else if (time_after_eq(jiffies, w_time)) { - /* capturing dump failed */ - return rval; - } - } while (1); - } - - addr = r_addr; - for (k = 0; k < r_cnt; k++) { - r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); - *data_ptr++ = cpu_to_le32(r_value); - addr += cache_hdr->read_ctrl.read_addr_stride; - } - - t_value += cache_hdr->addr_ctrl.tag_value_stride; - } - *d_ptr = data_ptr; - return QLA_SUCCESS; -} - -static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr) -{ - struct qla82xx_minidump_entry_crb *crb_entry; - uint32_t read_value, opcode, poll_time, addr, index, rval = QLA_SUCCESS; - uint32_t crb_addr; - unsigned long wtime; - struct qla4_8xxx_minidump_template_hdr *tmplt_hdr; - int i; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *) - ha->fw_dump_tmplt_hdr; - crb_entry = (struct qla82xx_minidump_entry_crb *)entry_hdr; - - crb_addr = crb_entry->addr; - for (i = 0; i < crb_entry->op_count; i++) { - opcode = crb_entry->crb_ctrl.opcode; - if (opcode & QLA82XX_DBG_OPCODE_WR) { - qla4_8xxx_md_rw_32(ha, crb_addr, - crb_entry->value_1, 1); - opcode &= ~QLA82XX_DBG_OPCODE_WR; - } - if (opcode & QLA82XX_DBG_OPCODE_RW) { - read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); - qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); - opcode &= ~QLA82XX_DBG_OPCODE_RW; - } - if (opcode & QLA82XX_DBG_OPCODE_AND) { - read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); - read_value &= crb_entry->value_2; - opcode &= ~QLA82XX_DBG_OPCODE_AND; - if (opcode & QLA82XX_DBG_OPCODE_OR) { - read_value |= crb_entry->value_3; - opcode &= ~QLA82XX_DBG_OPCODE_OR; - } - qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); - } - if (opcode & QLA82XX_DBG_OPCODE_OR) { - read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); - read_value |= crb_entry->value_3; - qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); - opcode &= ~QLA82XX_DBG_OPCODE_OR; - } - if (opcode & QLA82XX_DBG_OPCODE_POLL) { - poll_time = crb_entry->crb_strd.poll_timeout; - wtime = jiffies + poll_time; - read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); - - do { - if ((read_value & crb_entry->value_2) == - crb_entry->value_1) - break; - else if (time_after_eq(jiffies, wtime)) { - /* capturing dump failed */ - rval = QLA_ERROR; - break; - } else - read_value = qla4_8xxx_md_rw_32(ha, - crb_addr, 0, 0); - } while (1); - opcode &= ~QLA82XX_DBG_OPCODE_POLL; - } - - if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) { - if (crb_entry->crb_strd.state_index_a) { - index = crb_entry->crb_strd.state_index_a; - addr = tmplt_hdr->saved_state_array[index]; - } else { - addr = crb_addr; - } - - read_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); - index = crb_entry->crb_ctrl.state_index_v; - tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE; - } - - if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) { - if (crb_entry->crb_strd.state_index_a) { - index = crb_entry->crb_strd.state_index_a; - addr = tmplt_hdr->saved_state_array[index]; - } else { - addr = crb_addr; - } - - if (crb_entry->crb_ctrl.state_index_v) { - index = crb_entry->crb_ctrl.state_index_v; - read_value = - tmplt_hdr->saved_state_array[index]; - } else { - read_value = crb_entry->value_1; - } - - qla4_8xxx_md_rw_32(ha, addr, read_value, 1); - opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE; - } - - if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) { - index = crb_entry->crb_ctrl.state_index_v; - read_value = tmplt_hdr->saved_state_array[index]; - read_value <<= crb_entry->crb_ctrl.shl; - read_value >>= crb_entry->crb_ctrl.shr; - if (crb_entry->value_2) - read_value &= crb_entry->value_2; - read_value |= crb_entry->value_3; - read_value += crb_entry->value_1; - tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE; - } - crb_addr += crb_entry->crb_strd.addr_stride; - } - DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s\n", __func__)); - return rval; -} - -static void qla4_8xxx_minidump_process_rdocm(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t r_addr, r_stride, loop_cnt, i, r_value; - struct qla82xx_minidump_entry_rdocm *ocm_hdr; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - ocm_hdr = (struct qla82xx_minidump_entry_rdocm *)entry_hdr; - r_addr = ocm_hdr->read_addr; - r_stride = ocm_hdr->read_addr_stride; - loop_cnt = ocm_hdr->op_count; - - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n", - __func__, r_addr, r_stride, loop_cnt)); - - for (i = 0; i < loop_cnt; i++) { - r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase)); - *data_ptr++ = cpu_to_le32(r_value); - r_addr += r_stride; - } - DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%lx\n", - __func__, (loop_cnt * sizeof(uint32_t)))); - *d_ptr = data_ptr; -} - -static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value; - struct qla82xx_minidump_entry_mux *mux_hdr; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - mux_hdr = (struct qla82xx_minidump_entry_mux *)entry_hdr; - r_addr = mux_hdr->read_addr; - s_addr = mux_hdr->select_addr; - s_stride = mux_hdr->select_value_stride; - s_value = mux_hdr->select_value; - loop_cnt = mux_hdr->op_count; - - for (i = 0; i < loop_cnt; i++) { - qla4_8xxx_md_rw_32(ha, s_addr, s_value, 1); - r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); - *data_ptr++ = cpu_to_le32(s_value); - *data_ptr++ = cpu_to_le32(r_value); - s_value += s_stride; - } - *d_ptr = data_ptr; -} - -static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t addr, r_addr, c_addr, t_r_addr; - uint32_t i, k, loop_count, t_value, r_cnt, r_value; - uint32_t c_value_w; - struct qla82xx_minidump_entry_cache *cache_hdr; - uint32_t *data_ptr = *d_ptr; - - cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr; - loop_count = cache_hdr->op_count; - r_addr = cache_hdr->read_addr; - c_addr = cache_hdr->control_addr; - c_value_w = cache_hdr->cache_ctrl.write_value; - - t_r_addr = cache_hdr->tag_reg_addr; - t_value = cache_hdr->addr_ctrl.init_tag_value; - r_cnt = cache_hdr->read_ctrl.read_addr_cnt; - - for (i = 0; i < loop_count; i++) { - qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1); - qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1); - addr = r_addr; - for (k = 0; k < r_cnt; k++) { - r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); - *data_ptr++ = cpu_to_le32(r_value); - addr += cache_hdr->read_ctrl.read_addr_stride; - } - t_value += cache_hdr->addr_ctrl.tag_value_stride; - } - *d_ptr = data_ptr; -} - -static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t s_addr, r_addr; - uint32_t r_stride, r_value, r_cnt, qid = 0; - uint32_t i, k, loop_cnt; - struct qla82xx_minidump_entry_queue *q_hdr; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - q_hdr = (struct qla82xx_minidump_entry_queue *)entry_hdr; - s_addr = q_hdr->select_addr; - r_cnt = q_hdr->rd_strd.read_addr_cnt; - r_stride = q_hdr->rd_strd.read_addr_stride; - loop_cnt = q_hdr->op_count; - - for (i = 0; i < loop_cnt; i++) { - qla4_8xxx_md_rw_32(ha, s_addr, qid, 1); - r_addr = q_hdr->read_addr; - for (k = 0; k < r_cnt; k++) { - r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); - *data_ptr++ = cpu_to_le32(r_value); - r_addr += r_stride; - } - qid += q_hdr->q_strd.queue_id_stride; - } - *d_ptr = data_ptr; -} - -#define MD_DIRECT_ROM_WINDOW 0x42110030 -#define MD_DIRECT_ROM_READ_BASE 0x42150000 - -static void qla4_8xxx_minidump_process_rdrom(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t r_addr, r_value; - uint32_t i, loop_cnt; - struct qla82xx_minidump_entry_rdrom *rom_hdr; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - rom_hdr = (struct qla82xx_minidump_entry_rdrom *)entry_hdr; - r_addr = rom_hdr->read_addr; - loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t); - - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: flash_addr: 0x%x, read_data_size: 0x%x\n", - __func__, r_addr, loop_cnt)); - - for (i = 0; i < loop_cnt; i++) { - qla4_8xxx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW, - (r_addr & 0xFFFF0000), 1); - r_value = qla4_8xxx_md_rw_32(ha, - MD_DIRECT_ROM_READ_BASE + - (r_addr & 0x0000FFFF), 0, 0); - *data_ptr++ = cpu_to_le32(r_value); - r_addr += sizeof(uint32_t); - } - *d_ptr = data_ptr; -} - -#define MD_MIU_TEST_AGT_CTRL 0x41000090 -#define MD_MIU_TEST_AGT_ADDR_LO 0x41000094 -#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098 - -static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - uint32_t **d_ptr) -{ - uint32_t r_addr, r_value, r_data; - uint32_t i, j, loop_cnt; - struct qla82xx_minidump_entry_rdmem *m_hdr; - unsigned long flags; - uint32_t *data_ptr = *d_ptr; - - DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); - m_hdr = (struct qla82xx_minidump_entry_rdmem *)entry_hdr; - r_addr = m_hdr->read_addr; - loop_cnt = m_hdr->read_data_size/16; - - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n", - __func__, r_addr, m_hdr->read_data_size)); - - if (r_addr & 0xf) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: Read addr 0x%x not 16 bytes alligned\n", - __func__, r_addr)); - return QLA_ERROR; - } - - if (m_hdr->read_data_size % 16) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: Read data[0x%x] not multiple of 16 bytes\n", - __func__, m_hdr->read_data_size)); - return QLA_ERROR; - } - - DEBUG2(ql4_printk(KERN_INFO, ha, - "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n", - __func__, r_addr, m_hdr->read_data_size, loop_cnt)); - - write_lock_irqsave(&ha->hw_lock, flags); - for (i = 0; i < loop_cnt; i++) { - qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1); - r_value = 0; - qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1); - r_value = MIU_TA_CTL_ENABLE; - qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1); - r_value = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE; - qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1); - - for (j = 0; j < MAX_CTL_CHECK; j++) { - r_value = qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, - 0, 0); - if ((r_value & MIU_TA_CTL_BUSY) == 0) - break; - } - - if (j >= MAX_CTL_CHECK) { - printk_ratelimited(KERN_ERR - "%s: failed to read through agent\n", - __func__); - write_unlock_irqrestore(&ha->hw_lock, flags); - return QLA_SUCCESS; - } - - for (j = 0; j < 4; j++) { - r_data = qla4_8xxx_md_rw_32(ha, - MD_MIU_TEST_AGT_RDDATA[j], - 0, 0); - *data_ptr++ = cpu_to_le32(r_data); - } - - r_addr += 16; - } - write_unlock_irqrestore(&ha->hw_lock, flags); - - DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%x\n", - __func__, (loop_cnt * 16))); - - *d_ptr = data_ptr; - return QLA_SUCCESS; -} - -static void ql4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha, - struct qla82xx_minidump_entry_hdr *entry_hdr, - int index) -{ - entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG; - DEBUG2(ql4_printk(KERN_INFO, ha, - "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n", - ha->host_no, index, entry_hdr->entry_type, - entry_hdr->d_ctrl.entry_capture_mask)); -} - -/** - * qla82xx_collect_md_data - Retrieve firmware minidump data. - * @ha: pointer to adapter structure - **/ -static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha) -{ - int num_entry_hdr = 0; - struct qla82xx_minidump_entry_hdr *entry_hdr; - struct qla4_8xxx_minidump_template_hdr *tmplt_hdr; - uint32_t *data_ptr; - uint32_t data_collected = 0; - int i, rval = QLA_ERROR; - uint64_t now; - uint32_t timestamp; - - if (!ha->fw_dump) { - ql4_printk(KERN_INFO, ha, "%s(%ld) No buffer to dump\n", - __func__, ha->host_no); - return rval; - } - - tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *) - ha->fw_dump_tmplt_hdr; - data_ptr = (uint32_t *)((uint8_t *)ha->fw_dump + - ha->fw_dump_tmplt_size); - data_collected += ha->fw_dump_tmplt_size; - - num_entry_hdr = tmplt_hdr->num_of_entries; - ql4_printk(KERN_INFO, ha, "[%s]: starting data ptr: %p\n", - __func__, data_ptr); - ql4_printk(KERN_INFO, ha, - "[%s]: no of entry headers in Template: 0x%x\n", - __func__, num_entry_hdr); - ql4_printk(KERN_INFO, ha, "[%s]: Capture Mask obtained: 0x%x\n", - __func__, ha->fw_dump_capture_mask); - ql4_printk(KERN_INFO, ha, "[%s]: Total_data_size 0x%x, %d obtained\n", - __func__, ha->fw_dump_size, ha->fw_dump_size); - - /* Update current timestamp before taking dump */ - now = get_jiffies_64(); - timestamp = (u32)(jiffies_to_msecs(now) / 1000); - tmplt_hdr->driver_timestamp = timestamp; - - entry_hdr = (struct qla82xx_minidump_entry_hdr *) - (((uint8_t *)ha->fw_dump_tmplt_hdr) + - tmplt_hdr->first_entry_offset); - - /* Walk through the entry headers - validate/perform required action */ - for (i = 0; i < num_entry_hdr; i++) { - if (data_collected >= ha->fw_dump_size) { - ql4_printk(KERN_INFO, ha, - "Data collected: [0x%x], Total Dump size: [0x%x]\n", - data_collected, ha->fw_dump_size); - return rval; - } - - if (!(entry_hdr->d_ctrl.entry_capture_mask & - ha->fw_dump_capture_mask)) { - entry_hdr->d_ctrl.driver_flags |= - QLA82XX_DBG_SKIPPED_FLAG; - goto skip_nxt_entry; - } - - DEBUG2(ql4_printk(KERN_INFO, ha, - "Data collected: [0x%x], Dump size left:[0x%x]\n", - data_collected, - (ha->fw_dump_size - data_collected))); - - /* Decode the entry type and take required action to capture - * debug data - */ - switch (entry_hdr->entry_type) { - case QLA82XX_RDEND: - ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); - break; - case QLA82XX_CNTRL: - rval = qla4_8xxx_minidump_process_control(ha, - entry_hdr); - if (rval != QLA_SUCCESS) { - ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); - goto md_failed; - } - break; - case QLA82XX_RDCRB: - qla4_8xxx_minidump_process_rdcrb(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_RDMEM: - rval = qla4_8xxx_minidump_process_rdmem(ha, entry_hdr, - &data_ptr); - if (rval != QLA_SUCCESS) { - ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); - goto md_failed; - } - break; - case QLA82XX_BOARD: - case QLA82XX_RDROM: - qla4_8xxx_minidump_process_rdrom(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_L2DTG: - case QLA82XX_L2ITG: - case QLA82XX_L2DAT: - case QLA82XX_L2INS: - rval = qla4_8xxx_minidump_process_l2tag(ha, entry_hdr, - &data_ptr); - if (rval != QLA_SUCCESS) { - ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); - goto md_failed; - } - break; - case QLA82XX_L1DAT: - case QLA82XX_L1INS: - qla4_8xxx_minidump_process_l1cache(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_RDOCM: - qla4_8xxx_minidump_process_rdocm(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_RDMUX: - qla4_8xxx_minidump_process_rdmux(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_QUEUE: - qla4_8xxx_minidump_process_queue(ha, entry_hdr, - &data_ptr); - break; - case QLA82XX_RDNOP: - default: - ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); - break; - } - - data_collected = (uint8_t *)data_ptr - - ((uint8_t *)((uint8_t *)ha->fw_dump + - ha->fw_dump_tmplt_size)); -skip_nxt_entry: - /* next entry in the template */ - entry_hdr = (struct qla82xx_minidump_entry_hdr *) - (((uint8_t *)entry_hdr) + - entry_hdr->entry_size); - } - - if ((data_collected + ha->fw_dump_tmplt_size) != ha->fw_dump_size) { - ql4_printk(KERN_INFO, ha, - "Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n", - data_collected, ha->fw_dump_size); - goto md_failed; - } - - DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s Last entry: 0x%x\n", - __func__, i)); -md_failed: - return rval; -} - -/** - * qla4_8xxx_uevent_emit - Send uevent when the firmware dump is ready. - * @ha: pointer to adapter structure - **/ -static void qla4_8xxx_uevent_emit(struct scsi_qla_host *ha, u32 code) -{ - char event_string[40]; - char *envp[] = { event_string, NULL }; - - switch (code) { - case QL4_UEVENT_CODE_FW_DUMP: - snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", - ha->host_no); - break; - default: - /*do nothing*/ - break; - } - - kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp); -} - /** * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw * @ha: pointer to adapter structure @@ -2324,15 +1659,6 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha) qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION); qla4_8xxx_idc_unlock(ha); - if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) && - !test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) { - if (!qla4_8xxx_collect_md_data(ha)) { - qla4_8xxx_uevent_emit(ha, QL4_UEVENT_CODE_FW_DUMP); - } else { - ql4_printk(KERN_INFO, ha, "Unable to collect minidump\n"); - clear_bit(AF_82XX_FW_DUMPED, &ha->flags); - } - } rval = qla4_8xxx_try_start_fw(ha); qla4_8xxx_idc_lock(ha); @@ -2360,7 +1686,6 @@ static void qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha) { uint32_t dev_state, drv_state, drv_active; - uint32_t active_mask = 0xFFFFFFFF; unsigned long reset_timeout; ql4_printk(KERN_INFO, ha, @@ -2372,14 +1697,7 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha) qla4_8xxx_idc_lock(ha); } - if (!test_bit(AF_82XX_RST_OWNER, &ha->flags)) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "%s(%ld): reset acknowledged\n", - __func__, ha->host_no)); - qla4_8xxx_set_rst_ready(ha); - } else { - active_mask = (~(1 << (ha->func_num * 4))); - } + qla4_8xxx_set_rst_ready(ha); /* wait for 10 seconds for reset ack from all functions */ reset_timeout = jiffies + (ha->nx_reset_timeout * HZ); @@ -2391,24 +1709,12 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha) "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n", __func__, ha->host_no, drv_state, drv_active); - while (drv_state != (drv_active & active_mask)) { + while (drv_state != drv_active) { if (time_after_eq(jiffies, reset_timeout)) { - ql4_printk(KERN_INFO, ha, - "%s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n", - DRIVER_NAME, drv_state, drv_active); + printk("%s: RESET TIMEOUT!\n", DRIVER_NAME); break; } - /* - * When reset_owner times out, check which functions - * acked/did not ack - */ - if (test_bit(AF_82XX_RST_OWNER, &ha->flags)) { - ql4_printk(KERN_INFO, ha, - "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n", - __func__, ha->host_no, drv_state, - drv_active); - } qla4_8xxx_idc_unlock(ha); msleep(1000); qla4_8xxx_idc_lock(ha); @@ -2417,18 +1723,14 @@ qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha) drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); } - /* Clear RESET OWNER as we are not going to use it any further */ - clear_bit(AF_82XX_RST_OWNER, &ha->flags); - dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", dev_state, - dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); + ql4_printk(KERN_INFO, ha, "3:Device state is 0x%x = %s\n", dev_state, + dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); /* Force to DEV_COLD unless someone else is starting a reset */ if (dev_state != QLA82XX_DEV_INITIALIZING) { ql4_printk(KERN_INFO, ha, "HW State: COLD/RE-INIT\n"); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD); - qla4_8xxx_set_rst_ready(ha); } } @@ -2463,9 +1765,8 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) } dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", - dev_state, dev_state < MAX_STATES ? - qdev_state[dev_state] : "Unknown")); + ql4_printk(KERN_INFO, ha, "1:Device state is 0x%x = %s\n", dev_state, + dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); /* wait for 30 seconds for device to go ready */ dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ); @@ -2474,19 +1775,15 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) while (1) { if (time_after_eq(jiffies, dev_init_timeout)) { - ql4_printk(KERN_WARNING, ha, - "%s: Device Init Failed 0x%x = %s\n", - DRIVER_NAME, - dev_state, dev_state < MAX_STATES ? - qdev_state[dev_state] : "Unknown"); + ql4_printk(KERN_WARNING, ha, "Device init failed!\n"); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED); } dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); - ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", - dev_state, dev_state < MAX_STATES ? - qdev_state[dev_state] : "Unknown"); + ql4_printk(KERN_INFO, ha, + "2:Device state is 0x%x = %s\n", dev_state, + dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); /* NOTE: Make sure idc unlocked upon exit of switch statement */ switch (dev_state) { @@ -2887,7 +2184,6 @@ qla4_8xxx_isp_reset(struct scsi_qla_host *ha) ql4_printk(KERN_INFO, ha, "HW State: NEED RESET\n"); qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_NEED_RESET); - set_bit(AF_82XX_RST_OWNER, &ha->flags); } else ql4_printk(KERN_INFO, ha, "HW State: DEVICE INITIALIZING\n"); @@ -2899,10 +2195,8 @@ qla4_8xxx_isp_reset(struct scsi_qla_host *ha) qla4_8xxx_clear_rst_ready(ha); qla4_8xxx_idc_unlock(ha); - if (rval == QLA_SUCCESS) { - ql4_printk(KERN_INFO, ha, "Clearing AF_RECOVERY in qla4_8xxx_isp_reset\n"); + if (rval == QLA_SUCCESS) clear_bit(AF_FW_RECOVERY, &ha->flags); - } return rval; } diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nx.h b/trunk/drivers/scsi/qla4xxx/ql4_nx.h index 30258479f100..dc7500e47b8b 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_nx.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_nx.h @@ -792,196 +792,4 @@ struct crb_addr_pair { #define MIU_TEST_AGT_WRDATA_UPPER_LO (0x0b0) #define MIU_TEST_AGT_WRDATA_UPPER_HI (0x0b4) -/* Minidump related */ - -/* Entry Type Defines */ -#define QLA82XX_RDNOP 0 -#define QLA82XX_RDCRB 1 -#define QLA82XX_RDMUX 2 -#define QLA82XX_QUEUE 3 -#define QLA82XX_BOARD 4 -#define QLA82XX_RDOCM 6 -#define QLA82XX_PREGS 7 -#define QLA82XX_L1DTG 8 -#define QLA82XX_L1ITG 9 -#define QLA82XX_L1DAT 11 -#define QLA82XX_L1INS 12 -#define QLA82XX_L2DTG 21 -#define QLA82XX_L2ITG 22 -#define QLA82XX_L2DAT 23 -#define QLA82XX_L2INS 24 -#define QLA82XX_RDROM 71 -#define QLA82XX_RDMEM 72 -#define QLA82XX_CNTRL 98 -#define QLA82XX_RDEND 255 - -/* Opcodes for Control Entries. - * These Flags are bit fields. - */ -#define QLA82XX_DBG_OPCODE_WR 0x01 -#define QLA82XX_DBG_OPCODE_RW 0x02 -#define QLA82XX_DBG_OPCODE_AND 0x04 -#define QLA82XX_DBG_OPCODE_OR 0x08 -#define QLA82XX_DBG_OPCODE_POLL 0x10 -#define QLA82XX_DBG_OPCODE_RDSTATE 0x20 -#define QLA82XX_DBG_OPCODE_WRSTATE 0x40 -#define QLA82XX_DBG_OPCODE_MDSTATE 0x80 - -/* Driver Flags */ -#define QLA82XX_DBG_SKIPPED_FLAG 0x80 /* driver skipped this entry */ -#define QLA82XX_DBG_SIZE_ERR_FLAG 0x40 /* Entry vs Capture size - * mismatch */ - -/* Driver_code is for driver to write some info about the entry - * currently not used. - */ -struct qla82xx_minidump_entry_hdr { - uint32_t entry_type; - uint32_t entry_size; - uint32_t entry_capture_size; - struct { - uint8_t entry_capture_mask; - uint8_t entry_code; - uint8_t driver_code; - uint8_t driver_flags; - } d_ctrl; -}; - -/* Read CRB entry header */ -struct qla82xx_minidump_entry_crb { - struct qla82xx_minidump_entry_hdr h; - uint32_t addr; - struct { - uint8_t addr_stride; - uint8_t state_index_a; - uint16_t poll_timeout; - } crb_strd; - uint32_t data_size; - uint32_t op_count; - - struct { - uint8_t opcode; - uint8_t state_index_v; - uint8_t shl; - uint8_t shr; - } crb_ctrl; - - uint32_t value_1; - uint32_t value_2; - uint32_t value_3; -}; - -struct qla82xx_minidump_entry_cache { - struct qla82xx_minidump_entry_hdr h; - uint32_t tag_reg_addr; - struct { - uint16_t tag_value_stride; - uint16_t init_tag_value; - } addr_ctrl; - uint32_t data_size; - uint32_t op_count; - uint32_t control_addr; - struct { - uint16_t write_value; - uint8_t poll_mask; - uint8_t poll_wait; - } cache_ctrl; - uint32_t read_addr; - struct { - uint8_t read_addr_stride; - uint8_t read_addr_cnt; - uint16_t rsvd_1; - } read_ctrl; -}; - -/* Read OCM */ -struct qla82xx_minidump_entry_rdocm { - struct qla82xx_minidump_entry_hdr h; - uint32_t rsvd_0; - uint32_t rsvd_1; - uint32_t data_size; - uint32_t op_count; - uint32_t rsvd_2; - uint32_t rsvd_3; - uint32_t read_addr; - uint32_t read_addr_stride; -}; - -/* Read Memory */ -struct qla82xx_minidump_entry_rdmem { - struct qla82xx_minidump_entry_hdr h; - uint32_t rsvd[6]; - uint32_t read_addr; - uint32_t read_data_size; -}; - -/* Read ROM */ -struct qla82xx_minidump_entry_rdrom { - struct qla82xx_minidump_entry_hdr h; - uint32_t rsvd[6]; - uint32_t read_addr; - uint32_t read_data_size; -}; - -/* Mux entry */ -struct qla82xx_minidump_entry_mux { - struct qla82xx_minidump_entry_hdr h; - uint32_t select_addr; - uint32_t rsvd_0; - uint32_t data_size; - uint32_t op_count; - uint32_t select_value; - uint32_t select_value_stride; - uint32_t read_addr; - uint32_t rsvd_1; -}; - -/* Queue entry */ -struct qla82xx_minidump_entry_queue { - struct qla82xx_minidump_entry_hdr h; - uint32_t select_addr; - struct { - uint16_t queue_id_stride; - uint16_t rsvd_0; - } q_strd; - uint32_t data_size; - uint32_t op_count; - uint32_t rsvd_1; - uint32_t rsvd_2; - uint32_t read_addr; - struct { - uint8_t read_addr_stride; - uint8_t read_addr_cnt; - uint16_t rsvd_3; - } rd_strd; -}; - -#define QLA82XX_MINIDUMP_OCM0_SIZE (256 * 1024) -#define QLA82XX_MINIDUMP_L1C_SIZE (256 * 1024) -#define QLA82XX_MINIDUMP_L2C_SIZE 1572864 -#define QLA82XX_MINIDUMP_COMMON_STR_SIZE 0 -#define QLA82XX_MINIDUMP_FCOE_STR_SIZE 0 -#define QLA82XX_MINIDUMP_MEM_SIZE 0 -#define QLA82XX_MAX_ENTRY_HDR 4 - -struct qla82xx_minidump { - uint32_t md_ocm0_data[QLA82XX_MINIDUMP_OCM0_SIZE]; - uint32_t md_l1c_data[QLA82XX_MINIDUMP_L1C_SIZE]; - uint32_t md_l2c_data[QLA82XX_MINIDUMP_L2C_SIZE]; - uint32_t md_cs_data[QLA82XX_MINIDUMP_COMMON_STR_SIZE]; - uint32_t md_fcoes_data[QLA82XX_MINIDUMP_FCOE_STR_SIZE]; - uint32_t md_mem_data[QLA82XX_MINIDUMP_MEM_SIZE]; -}; - -#define MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE 0x129 -#define RQST_TMPLT_SIZE 0x0 -#define RQST_TMPLT 0x1 -#define MD_DIRECT_ROM_WINDOW 0x42110030 -#define MD_DIRECT_ROM_READ_BASE 0x42150000 -#define MD_MIU_TEST_AGT_CTRL 0x41000090 -#define MD_MIU_TEST_AGT_ADDR_LO 0x41000094 -#define MD_MIU_TEST_AGT_ADDR_HI 0x41000098 - -static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, - 0x410000AC, 0x410000B8, 0x410000BC }; #endif diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index cd15678f9ada..ee47820c30a6 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -68,34 +68,12 @@ MODULE_PARM_DESC(ql4xmaxqdepth, " Maximum queue depth to report for target devices.\n" "\t\t Default: 32."); -static int ql4xqfulltracking = 1; -module_param(ql4xqfulltracking, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ql4xqfulltracking, - " Enable or disable dynamic tracking and adjustment of\n" - "\t\t scsi device queue depth.\n" - "\t\t 0 - Disable.\n" - "\t\t 1 - Enable. (Default)"); - static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO; module_param(ql4xsess_recovery_tmo, int, S_IRUGO); MODULE_PARM_DESC(ql4xsess_recovery_tmo, " Target Session Recovery Timeout.\n" "\t\t Default: 120 sec."); -int ql4xmdcapmask = 0x1F; -module_param(ql4xmdcapmask, int, S_IRUGO); -MODULE_PARM_DESC(ql4xmdcapmask, - " Set the Minidump driver capture mask level.\n" - "\t\t Default is 0x1F.\n" - "\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F"); - -int ql4xenablemd = 1; -module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ql4xenablemd, - " Set to enable minidump.\n" - "\t\t 0 - disable minidump\n" - "\t\t 1 - enable minidump (Default)"); - static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); /* * SCSI host template entry points @@ -162,8 +140,6 @@ static int qla4xxx_slave_configure(struct scsi_device *device); static void qla4xxx_slave_destroy(struct scsi_device *sdev); static umode_t ql4_attr_is_visible(int param_type, int param); static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); -static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason); static struct qla4_8xxx_legacy_intr_set legacy_intr[] = QLA82XX_LEGACY_INTR_CONFIG; @@ -183,7 +159,6 @@ static struct scsi_host_template qla4xxx_driver_template = { .slave_configure = qla4xxx_slave_configure, .slave_alloc = qla4xxx_slave_alloc, .slave_destroy = qla4xxx_slave_destroy, - .change_queue_depth = qla4xxx_change_queue_depth, .this_id = -1, .cmd_per_lun = 3, @@ -1580,53 +1555,19 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) struct iscsi_session *sess; struct ddb_entry *ddb_entry; struct scsi_qla_host *ha; - unsigned long flags, wtime; - struct dev_db_entry *fw_ddb_entry = NULL; - dma_addr_t fw_ddb_entry_dma; - uint32_t ddb_state; - int ret; + unsigned long flags; DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); sess = cls_sess->dd_data; ddb_entry = sess->dd_data; ha = ddb_entry->ha; - fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - &fw_ddb_entry_dma, GFP_KERNEL); - if (!fw_ddb_entry) { - ql4_printk(KERN_ERR, ha, - "%s: Unable to allocate dma buffer\n", __func__); - goto destroy_session; - } - - wtime = jiffies + (HZ * LOGOUT_TOV); - do { - ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, - fw_ddb_entry, fw_ddb_entry_dma, - NULL, NULL, &ddb_state, NULL, - NULL, NULL); - if (ret == QLA_ERROR) - goto destroy_session; - - if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) || - (ddb_state == DDB_DS_SESSION_FAILED)) - goto destroy_session; - - schedule_timeout_uninterruptible(HZ); - } while ((time_after(wtime, jiffies))); - -destroy_session: qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); spin_lock_irqsave(&ha->hardware_lock, flags); qla4xxx_free_ddb(ha, ddb_entry); spin_unlock_irqrestore(&ha->hardware_lock, flags); - iscsi_session_teardown(cls_sess); - - if (fw_ddb_entry) - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - fw_ddb_entry, fw_ddb_entry_dma); } static struct iscsi_cls_conn * @@ -2279,9 +2220,6 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, ha->queues_dma); - if (ha->fw_dump) - vfree(ha->fw_dump); - ha->queues_len = 0; ha->queues = NULL; ha->queues_dma = 0; @@ -2291,8 +2229,6 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) ha->response_dma = 0; ha->shadow_regs = NULL; ha->shadow_regs_dma = 0; - ha->fw_dump = NULL; - ha->fw_dump_size = 0; /* Free srb pool. */ if (ha->srb_mempool) @@ -5087,8 +5023,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, set_bit(AF_INIT_DONE, &ha->flags); - qla4_8xxx_alloc_sysfs_attr(ha); - printk(KERN_INFO " QLogic iSCSI HBA Driver version: %s\n" " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", @@ -5215,7 +5149,6 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) iscsi_boot_destroy_kset(ha->boot_kset); qla4xxx_destroy_fw_ddb_session(ha); - qla4_8xxx_free_sysfs_attr(ha); scsi_remove_host(ha->host); @@ -5284,15 +5217,6 @@ static void qla4xxx_slave_destroy(struct scsi_device *sdev) scsi_deactivate_tcq(sdev, 1); } -static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, - int reason) -{ - if (!ql4xqfulltracking) - return -EOPNOTSUPP; - - return iscsi_change_queue_depth(sdev, qdepth, reason); -} - /** * qla4xxx_del_from_active_array - returns an active srb * @ha: Pointer to host adapter structure. diff --git a/trunk/drivers/scsi/qla4xxx/ql4_version.h b/trunk/drivers/scsi/qla4xxx/ql4_version.h index cc1cc3518b87..97b30c108e36 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_version.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.02.00-k17" +#define QLA4XXX_DRIVER_VERSION "5.02.00-k16" diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 6dfb9785d345..62ddfd31d4ce 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1378,19 +1378,16 @@ static int scsi_lld_busy(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost; + struct scsi_target *starget; if (!sdev) return 0; shost = sdev->host; + starget = scsi_target(sdev); - /* - * Ignore host/starget busy state. - * Since block layer does not have a concept of fairness across - * multiple queues, congestion of host/starget needs to be handled - * in SCSI layer. - */ - if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev)) + if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) || + scsi_target_is_busy(starget) || scsi_device_is_busy(sdev)) return 1; return 0; diff --git a/trunk/drivers/scsi/scsi_pm.c b/trunk/drivers/scsi/scsi_pm.c index d4201ded3b22..f661a41fa4c6 100644 --- a/trunk/drivers/scsi/scsi_pm.c +++ b/trunk/drivers/scsi/scsi_pm.c @@ -24,11 +24,8 @@ static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg) err = scsi_device_quiesce(to_scsi_device(dev)); if (err == 0) { drv = dev->driver; - if (drv && drv->suspend) { + if (drv && drv->suspend) err = drv->suspend(dev, msg); - if (err) - scsi_device_resume(to_scsi_device(dev)); - } } dev_dbg(dev, "scsi suspend: %d\n", err); return err; diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 2e5fe584aad3..01b03744f1f9 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -147,7 +147,7 @@ int scsi_complete_async_scans(void) do { if (list_empty(&scanning_hosts)) - goto out; + return 0; /* If we can't get memory immediately, that's OK. Just * sleep a little. Even if we never get memory, the async * scans will finish eventually. @@ -179,11 +179,8 @@ int scsi_complete_async_scans(void) } done: spin_unlock(&async_scan_lock); - kfree(data); - - out: - async_synchronize_full_domain(&scsi_sd_probe_domain); + kfree(data); return 0; } diff --git a/trunk/drivers/scsi/scsi_wait_scan.c b/trunk/drivers/scsi/scsi_wait_scan.c index ae7814874618..74708fcaf82f 100644 --- a/trunk/drivers/scsi/scsi_wait_scan.c +++ b/trunk/drivers/scsi/scsi_wait_scan.c @@ -12,7 +12,7 @@ #include #include -#include "scsi_priv.h" +#include static int __init wait_scan_init(void) { diff --git a/trunk/drivers/scsi/ufs/ufshcd.c b/trunk/drivers/scsi/ufs/ufshcd.c index 6a4fd00117ca..4e010b727818 100644 --- a/trunk/drivers/scsi/ufs/ufshcd.c +++ b/trunk/drivers/scsi/ufs/ufshcd.c @@ -1836,7 +1836,7 @@ ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id) err = pci_request_regions(pdev, UFSHCD); if (err < 0) { dev_err(&pdev->dev, "request regions failed\n"); - goto out_host_put; + goto out_disable; } hba->mmio_base = pci_ioremap_bar(pdev, 0); @@ -1925,9 +1925,8 @@ ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id) iounmap(hba->mmio_base); out_release_regions: pci_release_regions(pdev); -out_host_put: - scsi_host_put(host); out_disable: + scsi_host_put(host); pci_clear_master(pdev); pci_disable_device(pdev); out_error: diff --git a/trunk/drivers/tty/tty_mutex.c b/trunk/drivers/tty/tty_mutex.c index 67feac9e6ebb..69adc80c98cd 100644 --- a/trunk/drivers/tty/tty_mutex.c +++ b/trunk/drivers/tty/tty_mutex.c @@ -6,17 +6,11 @@ /* Legacy tty mutex glue */ -enum { - TTY_MUTEX_NORMAL, - TTY_MUTEX_NESTED, -}; - /* * Getting the big tty mutex. */ -static void __lockfunc tty_lock_nested(struct tty_struct *tty, - unsigned int subclass) +void __lockfunc tty_lock(struct tty_struct *tty) { if (tty->magic != TTY_MAGIC) { printk(KERN_ERR "L Bad %p\n", tty); @@ -24,12 +18,7 @@ static void __lockfunc tty_lock_nested(struct tty_struct *tty, return; } tty_kref_get(tty); - mutex_lock_nested(&tty->legacy_mutex, subclass); -} - -void __lockfunc tty_lock(struct tty_struct *tty) -{ - return tty_lock_nested(tty, TTY_MUTEX_NORMAL); + mutex_lock(&tty->legacy_mutex); } EXPORT_SYMBOL(tty_lock); @@ -54,11 +43,11 @@ void __lockfunc tty_lock_pair(struct tty_struct *tty, { if (tty < tty2) { tty_lock(tty); - tty_lock_nested(tty2, TTY_MUTEX_NESTED); + tty_lock(tty2); } else { if (tty2 && tty2 != tty) tty_lock(tty2); - tty_lock_nested(tty, TTY_MUTEX_NESTED); + tty_lock(tty); } } EXPORT_SYMBOL(tty_lock_pair); diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index 0c85fae37666..f4aadd15b613 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -145,6 +145,50 @@ struct dio { static struct kmem_cache *dio_cache __read_mostly; +static void __inode_dio_wait(struct inode *inode) +{ + wait_queue_head_t *wq = bit_waitqueue(&inode->i_state, __I_DIO_WAKEUP); + DEFINE_WAIT_BIT(q, &inode->i_state, __I_DIO_WAKEUP); + + do { + prepare_to_wait(wq, &q.wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(&inode->i_dio_count)) + schedule(); + } while (atomic_read(&inode->i_dio_count)); + finish_wait(wq, &q.wait); +} + +/** + * inode_dio_wait - wait for outstanding DIO requests to finish + * @inode: inode to wait for + * + * Waits for all pending direct I/O requests to finish so that we can + * proceed with a truncate or equivalent operation. + * + * Must be called under a lock that serializes taking new references + * to i_dio_count, usually by inode->i_mutex. + */ +void inode_dio_wait(struct inode *inode) +{ + if (atomic_read(&inode->i_dio_count)) + __inode_dio_wait(inode); +} +EXPORT_SYMBOL(inode_dio_wait); + +/* + * inode_dio_done - signal finish of a direct I/O requests + * @inode: inode the direct I/O happens on + * + * This is called once we've finished processing a direct I/O request, + * and is used to wake up callers waiting for direct I/O to be quiesced. + */ +void inode_dio_done(struct inode *inode) +{ + if (atomic_dec_and_test(&inode->i_dio_count)) + wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); +} +EXPORT_SYMBOL(inode_dio_done); + /* * How many pages are in the queue? */ diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index c474c1d7062b..6bc8761cc333 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -1748,50 +1748,3 @@ bool inode_owner_or_capable(const struct inode *inode) return false; } EXPORT_SYMBOL(inode_owner_or_capable); - -/* - * Direct i/o helper functions - */ -static void __inode_dio_wait(struct inode *inode) -{ - wait_queue_head_t *wq = bit_waitqueue(&inode->i_state, __I_DIO_WAKEUP); - DEFINE_WAIT_BIT(q, &inode->i_state, __I_DIO_WAKEUP); - - do { - prepare_to_wait(wq, &q.wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&inode->i_dio_count)) - schedule(); - } while (atomic_read(&inode->i_dio_count)); - finish_wait(wq, &q.wait); -} - -/** - * inode_dio_wait - wait for outstanding DIO requests to finish - * @inode: inode to wait for - * - * Waits for all pending direct I/O requests to finish so that we can - * proceed with a truncate or equivalent operation. - * - * Must be called under a lock that serializes taking new references - * to i_dio_count, usually by inode->i_mutex. - */ -void inode_dio_wait(struct inode *inode) -{ - if (atomic_read(&inode->i_dio_count)) - __inode_dio_wait(inode); -} -EXPORT_SYMBOL(inode_dio_wait); - -/* - * inode_dio_done - signal finish of a direct I/O requests - * @inode: inode the direct I/O happens on - * - * This is called once we've finished processing a direct I/O request, - * and is used to wake up callers waiting for direct I/O to be quiesced. - */ -void inode_dio_done(struct inode *inode) -{ - if (atomic_dec_and_test(&inode->i_dio_count)) - wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); -} -EXPORT_SYMBOL(inode_dio_done); diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index ad2775d3e219..23d170bc44f4 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -454,12 +454,6 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, return result; } -static void nfs_inode_dio_write_done(struct inode *inode) -{ - nfs_zap_mapping(inode, inode->i_mapping); - inode_dio_done(inode); -} - #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) { @@ -570,7 +564,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work) nfs_direct_write_reschedule(dreq); break; default: - nfs_inode_dio_write_done(dreq->inode); + nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping); nfs_direct_complete(dreq); } } @@ -587,7 +581,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work) static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) { - nfs_inode_dio_write_done(inode); + nfs_zap_mapping(inode, inode->i_mapping); nfs_direct_complete(dreq); } #endif @@ -772,16 +766,14 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, loff_t pos) { struct nfs_pageio_descriptor desc; - struct inode *inode = dreq->inode; ssize_t result = 0; size_t requested_bytes = 0; unsigned long seg; - nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE, + nfs_pageio_init_write(&desc, dreq->inode, FLUSH_COND_STABLE, &nfs_direct_write_completion_ops); desc.pg_dreq = dreq; get_dreq(dreq); - atomic_inc(&inode->i_dio_count); for (seg = 0; seg < nr_segs; seg++) { const struct iovec *vec = &iov[seg]; @@ -801,7 +793,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, * generic layer handle the completion. */ if (requested_bytes == 0) { - inode_dio_done(inode); nfs_direct_req_release(dreq); return result < 0 ? result : -EIO; } diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index e605d695dbcb..2f6f78c4b42d 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -418,10 +418,8 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) return 0; /* Write all dirty data */ - if (S_ISREG(inode->i_mode)) { - nfs_inode_dio_wait(inode); + if (S_ISREG(inode->i_mode)) nfs_wb_all(inode); - } fattr = nfs_alloc_fattr(); if (fattr == NULL) @@ -505,7 +503,6 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) /* Flush out writes to the server in order to update c/mtime. */ if (S_ISREG(inode->i_mode)) { - nfs_inode_dio_wait(inode); err = filemap_write_and_wait(inode->i_mapping); if (err) goto out; diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 18f99ef71343..1848a7275592 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -369,10 +369,6 @@ extern int nfs_migrate_page(struct address_space *, /* direct.c */ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, struct nfs_direct_req *dreq); -static inline void nfs_inode_dio_wait(struct inode *inode) -{ - inode_dio_wait(inode); -} /* nfs4proc.c */ extern void __nfs4_read_done_cb(struct nfs_read_data *); diff --git a/trunk/include/asm-generic/Kbuild b/trunk/include/asm-generic/Kbuild index 2c85a0f647b7..53f91b1ae53a 100644 --- a/trunk/include/asm-generic/Kbuild +++ b/trunk/include/asm-generic/Kbuild @@ -8,7 +8,6 @@ header-y += int-ll64.h header-y += ioctl.h header-y += ioctls.h header-y += ipcbuf.h -header-y += kvm_para.h header-y += mman-common.h header-y += mman.h header-y += msgbuf.h diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 598a5892ff2b..038076b27ea4 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -2453,6 +2453,8 @@ enum { }; void dio_end_io(struct bio *bio, int error); +void inode_dio_wait(struct inode *inode); +void inode_dio_done(struct inode *inode); ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, struct block_device *bdev, const struct iovec *iov, loff_t offset, @@ -2467,11 +2469,12 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb, offset, nr_segs, get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES); } +#else +static inline void inode_dio_wait(struct inode *inode) +{ +} #endif -void inode_dio_wait(struct inode *inode); -void inode_dio_done(struct inode *inode); - extern const struct file_operations generic_ro_fops; #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) diff --git a/trunk/include/linux/genetlink.h b/trunk/include/linux/genetlink.h index 7a114016ac7d..73c28dea10ae 100644 --- a/trunk/include/linux/genetlink.h +++ b/trunk/include/linux/genetlink.h @@ -110,9 +110,6 @@ extern int lockdep_genl_is_held(void); #define genl_dereference(p) \ rcu_dereference_protected(p, lockdep_genl_is_held()) -#define MODULE_ALIAS_GENL_FAMILY(family)\ - MODULE_ALIAS_NET_PF_PROTO_NAME(PF_NETLINK, NETLINK_GENERIC, "-family-" family) - #endif /* __KERNEL__ */ #endif /* __LINUX_GENERIC_NETLINK_H */ diff --git a/trunk/include/linux/net.h b/trunk/include/linux/net.h index e9ac2df079ba..2d7510f38934 100644 --- a/trunk/include/linux/net.h +++ b/trunk/include/linux/net.h @@ -313,8 +313,5 @@ extern int kernel_sock_shutdown(struct socket *sock, MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \ "-type-" __stringify(type)) -#define MODULE_ALIAS_NET_PF_PROTO_NAME(pf, proto, name) \ - MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \ - name) #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index d94cb1431519..e7fd468f7126 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -2795,15 +2795,15 @@ do { \ #define netif_info(priv, type, dev, fmt, args...) \ netif_level(info, priv, type, dev, fmt, ##args) -#if defined(CONFIG_DYNAMIC_DEBUG) +#if defined(DEBUG) +#define netif_dbg(priv, type, dev, format, args...) \ + netif_printk(priv, type, KERN_DEBUG, dev, format, ##args) +#elif defined(CONFIG_DYNAMIC_DEBUG) #define netif_dbg(priv, type, netdev, format, args...) \ do { \ if (netif_msg_##type(priv)) \ dynamic_netdev_dbg(netdev, format, ##args); \ } while (0) -#elif defined(DEBUG) -#define netif_dbg(priv, type, dev, format, args...) \ - netif_printk(priv, type, KERN_DEBUG, dev, format, ##args) #else #define netif_dbg(priv, type, dev, format, args...) \ ({ \ diff --git a/trunk/include/linux/power/charger-manager.h b/trunk/include/linux/power/charger-manager.h index 241065c9ce51..4f75e531c112 100644 --- a/trunk/include/linux/power/charger-manager.h +++ b/trunk/include/linux/power/charger-manager.h @@ -18,8 +18,6 @@ #include enum data_source { - CM_BATTERY_PRESENT, - CM_NO_BATTERY, CM_FUEL_GAUGE, CM_CHARGER_STAT, }; @@ -31,16 +29,6 @@ enum polling_modes { CM_POLL_CHARGING_ONLY, }; -enum cm_event_types { - CM_EVENT_UNKNOWN = 0, - CM_EVENT_BATT_FULL, - CM_EVENT_BATT_IN, - CM_EVENT_BATT_OUT, - CM_EVENT_EXT_PWR_IN_OUT, - CM_EVENT_CHG_START_STOP, - CM_EVENT_OTHERS, -}; - /** * struct charger_global_desc * @rtc_name: the name of RTC used to wake up the system from suspend. @@ -50,18 +38,11 @@ enum cm_event_types { * rtc_only_wakeup() returning false. * If the RTC given to CM is the only wakeup reason, * rtc_only_wakeup should return true. - * @assume_timer_stops_in_suspend: - * Assume that the jiffy timer stops in suspend-to-RAM. - * When enabled, CM does not rely on jiffies value in - * suspend_again and assumes that jiffies value does not - * change during suspend. */ struct charger_global_desc { char *rtc_name; bool (*rtc_only_wakeup)(void); - - bool assume_timer_stops_in_suspend; }; /** @@ -69,11 +50,6 @@ struct charger_global_desc { * @psy_name: the name of power-supply-class for charger manager * @polling_mode: * Determine which polling mode will be used - * @fullbatt_vchkdrop_ms: - * @fullbatt_vchkdrop_uV: - * Check voltage drop after the battery is fully charged. - * If it has dropped more than fullbatt_vchkdrop_uV after - * fullbatt_vchkdrop_ms, CM will restart charging. * @fullbatt_uV: voltage in microvolt * If it is not being charged and VBATT >= fullbatt_uV, * it is assumed to be full. @@ -100,8 +76,6 @@ struct charger_desc { enum polling_modes polling_mode; unsigned int polling_interval_ms; - unsigned int fullbatt_vchkdrop_ms; - unsigned int fullbatt_vchkdrop_uV; unsigned int fullbatt_uV; enum data_source battery_present; @@ -127,11 +101,6 @@ struct charger_desc { * @fuel_gauge: power_supply for fuel gauge * @charger_stat: array of power_supply for chargers * @charger_enabled: the state of charger - * @fullbatt_vchk_jiffies_at: - * jiffies at the time full battery check will occur. - * @fullbatt_vchk_uV: voltage in microvolt - * criteria for full battery - * @fullbatt_vchk_work: work queue for full battery check * @emergency_stop: * When setting true, stop charging * @last_temp_mC: the measured temperature in milli-Celsius @@ -152,10 +121,6 @@ struct charger_manager { bool charger_enabled; - unsigned long fullbatt_vchk_jiffies_at; - unsigned int fullbatt_vchk_uV; - struct delayed_work fullbatt_vchk_work; - int emergency_stop; int last_temp_mC; @@ -169,13 +134,14 @@ struct charger_manager { #ifdef CONFIG_CHARGER_MANAGER extern int setup_charger_manager(struct charger_global_desc *gd); extern bool cm_suspend_again(void); -extern void cm_notify_event(struct power_supply *psy, - enum cm_event_types type, char *msg); #else -static inline int setup_charger_manager(struct charger_global_desc *gd) -{ return 0; } -static inline bool cm_suspend_again(void) { return false; } -static inline void cm_notify_event(struct power_supply *psy, - enum cm_event_types type, char *msg) { } +static void __maybe_unused setup_charger_manager(struct charger_global_desc *gd) +{ } + +static bool __maybe_unused cm_suspend_again(void) +{ + return false; +} #endif + #endif /* _CHARGER_MANAGER_H */ diff --git a/trunk/include/linux/power/max17042_battery.h b/trunk/include/linux/power/max17042_battery.h index 89dd84f47c6e..e01b167e66f0 100644 --- a/trunk/include/linux/power/max17042_battery.h +++ b/trunk/include/linux/power/max17042_battery.h @@ -116,18 +116,6 @@ enum max17042_register { MAX17042_VFSOC = 0xFF, }; -/* Registers specific to max17047/50 */ -enum max17047_register { - MAX17047_QRTbl00 = 0x12, - MAX17047_FullSOCThr = 0x13, - MAX17047_QRTbl10 = 0x22, - MAX17047_QRTbl20 = 0x32, - MAX17047_V_empty = 0x3A, - MAX17047_QRTbl30 = 0x42, -}; - -enum max170xx_chip_type {MAX17042, MAX17047}; - /* * used for setting a register to a desired value * addr : address for a register @@ -156,7 +144,6 @@ struct max17042_config_data { u16 shdntimer; /* 0x03F */ /* App data */ - u16 full_soc_thresh; /* 0x13 */ u16 design_cap; /* 0x18 */ u16 ichgt_term; /* 0x1E */ @@ -175,10 +162,6 @@ struct max17042_config_data { u16 lavg_empty; /* 0x36 */ u16 dqacc; /* 0x45 */ u16 dpacc; /* 0x46 */ - u16 qrtbl00; /* 0x12 */ - u16 qrtbl10; /* 0x22 */ - u16 qrtbl20; /* 0x32 */ - u16 qrtbl30; /* 0x42 */ /* Cell technology from power_supply.h */ u16 cell_technology; diff --git a/trunk/include/linux/power_supply.h b/trunk/include/linux/power_supply.h index 3b912bee28d1..c38c13db8832 100644 --- a/trunk/include/linux/power_supply.h +++ b/trunk/include/linux/power_supply.h @@ -96,7 +96,6 @@ enum power_supply_property { POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_VOLTAGE_OCV, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_AVG, @@ -212,7 +211,7 @@ extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); extern int power_supply_set_battery_charged(struct power_supply *psy); -#ifdef CONFIG_POWER_SUPPLY +#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE) extern int power_supply_is_system_supplied(void); #else static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } @@ -262,7 +261,6 @@ static inline bool power_supply_is_watt_property(enum power_supply_property psp) case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: case POWER_SUPPLY_PROP_VOLTAGE_NOW: case POWER_SUPPLY_PROP_VOLTAGE_AVG: - case POWER_SUPPLY_PROP_VOLTAGE_OCV: case POWER_SUPPLY_PROP_POWER_NOW: return 1; default: diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index b534a1be540a..0e501714d47f 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -1896,6 +1896,8 @@ static inline int __skb_cow(struct sk_buff *skb, unsigned int headroom, { int delta = 0; + if (headroom < NET_SKB_PAD) + headroom = NET_SKB_PAD; if (headroom > skb_headroom(skb)) delta = headroom - skb_headroom(skb); diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 8197eadca819..bed833d9796a 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -60,7 +60,6 @@ struct dst_entry { #define DST_NOCOUNT 0x0020 #define DST_NOPEER 0x0040 #define DST_FAKE_RTABLE 0x0080 -#define DST_XFRM_TUNNEL 0x0100 short error; short obsolete; diff --git a/trunk/include/scsi/fcoe_sysfs.h b/trunk/include/scsi/fcoe_sysfs.h deleted file mode 100644 index 604cb9bb3e76..000000000000 --- a/trunk/include/scsi/fcoe_sysfs.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2011-2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Maintained at www.Open-FCoE.org - */ - -#ifndef FCOE_SYSFS -#define FCOE_SYSFS - -#include -#include -#include - -struct fcoe_ctlr_device; -struct fcoe_fcf_device; - -struct fcoe_sysfs_function_template { - void (*get_fcoe_ctlr_link_fail)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_vlink_fail)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_miss_fka)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_symb_err)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_err_block)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_fcs_error)(struct fcoe_ctlr_device *); - void (*get_fcoe_ctlr_mode)(struct fcoe_ctlr_device *); - void (*get_fcoe_fcf_selected)(struct fcoe_fcf_device *); - void (*get_fcoe_fcf_vlan_id)(struct fcoe_fcf_device *); -}; - -#define dev_to_ctlr(d) \ - container_of((d), struct fcoe_ctlr_device, dev) - -enum fip_conn_type { - FIP_CONN_TYPE_UNKNOWN, - FIP_CONN_TYPE_FABRIC, - FIP_CONN_TYPE_VN2VN, -}; - -struct fcoe_ctlr_device { - u32 id; - - struct device dev; - struct fcoe_sysfs_function_template *f; - - struct list_head fcfs; - char work_q_name[20]; - struct workqueue_struct *work_q; - char devloss_work_q_name[20]; - struct workqueue_struct *devloss_work_q; - struct mutex lock; - - int fcf_dev_loss_tmo; - enum fip_conn_type mode; - - /* expected in host order for displaying */ - struct fcoe_fc_els_lesb lesb; -}; - -static inline void *fcoe_ctlr_device_priv(const struct fcoe_ctlr_device *ctlr) -{ - return (void *)(ctlr + 1); -} - -/* fcf states */ -enum fcf_state { - FCOE_FCF_STATE_UNKNOWN, - FCOE_FCF_STATE_DISCONNECTED, - FCOE_FCF_STATE_CONNECTED, - FCOE_FCF_STATE_DELETED, -}; - -struct fcoe_fcf_device { - u32 id; - struct device dev; - struct list_head peers; - struct work_struct delete_work; - struct delayed_work dev_loss_work; - u32 dev_loss_tmo; - void *priv; - enum fcf_state state; - - u64 fabric_name; - u64 switch_name; - u32 fc_map; - u16 vfid; - u8 mac[ETH_ALEN]; - u8 priority; - u32 fka_period; - u8 selected; - u16 vlan_id; -}; - -#define dev_to_fcf(d) \ - container_of((d), struct fcoe_fcf_device, dev) -/* parentage should never be missing */ -#define fcoe_fcf_dev_to_ctlr_dev(x) \ - dev_to_ctlr((x)->dev.parent) -#define fcoe_fcf_device_priv(x) \ - ((x)->priv) - -struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, - struct fcoe_sysfs_function_template *f, - int priv_size); -void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *); -struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *, - struct fcoe_fcf_device *); -void fcoe_fcf_device_delete(struct fcoe_fcf_device *); - -int __init fcoe_sysfs_setup(void); -void __exit fcoe_sysfs_teardown(void); - -#endif /* FCOE_SYSFS */ diff --git a/trunk/include/scsi/libfcoe.h b/trunk/include/scsi/libfcoe.h index 22b07cc99808..cfdb55f0937e 100644 --- a/trunk/include/scsi/libfcoe.h +++ b/trunk/include/scsi/libfcoe.h @@ -29,7 +29,6 @@ #include #include #include -#include #define FCOE_MAX_CMD_LEN 16 /* Supported CDB length */ @@ -159,25 +158,9 @@ struct fcoe_ctlr { spinlock_t ctlr_lock; }; -/** - * fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr - * @cltr: The fcoe_ctlr whose private data will be returned - */ -static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr) -{ - return (void *)(ctlr + 1); -} - -#define fcoe_ctlr_to_ctlr_dev(x) \ - (struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1) - /** * struct fcoe_fcf - Fibre-Channel Forwarder * @list: list linkage - * @event_work: Work for FC Transport actions queue - * @event: The event to be processed - * @fip: The controller that the FCF was discovered on - * @fcf_dev: The associated fcoe_fcf_device instance * @time: system time (jiffies) when an advertisement was last received * @switch_name: WWN of switch from advertisement * @fabric_name: WWN of fabric from advertisement @@ -199,9 +182,6 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr) */ struct fcoe_fcf { struct list_head list; - struct work_struct event_work; - struct fcoe_ctlr *fip; - struct fcoe_fcf_device *fcf_dev; unsigned long time; u64 switch_name; @@ -218,9 +198,6 @@ struct fcoe_fcf { u8 fd_flags:1; }; -#define fcoe_fcf_to_fcf_dev(x) \ - ((x)->fcf_dev) - /** * struct fcoe_rport - VN2VN remote port * @time: time of create or last beacon packet received from node @@ -356,10 +333,6 @@ void fcoe_queue_timer(ulong lport); int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, struct fcoe_percpu_s *fps); -/* FCoE Sysfs helpers */ -void fcoe_fcf_get_selected(struct fcoe_fcf_device *); -void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *); - /** * struct netdev_list * A mapping from netdevice to fcoe_transport diff --git a/trunk/net/core/drop_monitor.c b/trunk/net/core/drop_monitor.c index ea5fb9fcc3f5..3252e7e0a005 100644 --- a/trunk/net/core/drop_monitor.c +++ b/trunk/net/core/drop_monitor.c @@ -468,4 +468,3 @@ module_exit(exit_net_drop_monitor); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Neil Horman "); -MODULE_ALIAS_GENL_FAMILY("NET_DM"); diff --git a/trunk/net/ipv4/esp4.c b/trunk/net/ipv4/esp4.c index cb982a61536f..89a47b35905d 100644 --- a/trunk/net/ipv4/esp4.c +++ b/trunk/net/ipv4/esp4.c @@ -459,22 +459,28 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); u32 align = max_t(u32, blksize, esp->padlen); - unsigned int net_adj; + u32 rem; + + mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); + rem = mtu & (align - 1); + mtu &= ~(align - 1); switch (x->props.mode) { - case XFRM_MODE_TRANSPORT: - case XFRM_MODE_BEET: - net_adj = sizeof(struct iphdr); - break; case XFRM_MODE_TUNNEL: - net_adj = 0; break; default: - BUG(); + case XFRM_MODE_TRANSPORT: + /* The worst case */ + mtu -= blksize - 4; + mtu += min_t(u32, blksize - 4, rem); + break; + case XFRM_MODE_BEET: + /* The worst case. */ + mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem); + break; } - return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) - - net_adj) & ~(align - 1)) + (net_adj - 2); + return mtu - 2; } static void esp4_err(struct sk_buff *skb, u32 info) diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index db1521fcda5b..1e62b7557b00 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -413,15 +413,19 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); u32 align = max_t(u32, blksize, esp->padlen); - unsigned int net_adj; + u32 rem; - if (x->props.mode != XFRM_MODE_TUNNEL) - net_adj = sizeof(struct ipv6hdr); - else - net_adj = 0; + mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); + rem = mtu & (align - 1); + mtu &= ~(align - 1); + + if (x->props.mode != XFRM_MODE_TUNNEL) { + u32 padsize = ((blksize - 1) & 7) + 1; + mtu -= blksize - padsize; + mtu += min_t(u32, blksize - padsize, rem); + } - return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) - - net_adj) & ~(align - 1)) + (net_adj - 2); + return mtu - 2; } static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 17b8c67998bb..d99fdc699625 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -1187,29 +1187,6 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; } -static void ip6_append_data_mtu(int *mtu, - int *maxfraglen, - unsigned int fragheaderlen, - struct sk_buff *skb, - struct rt6_info *rt) -{ - if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { - if (skb == NULL) { - /* first fragment, reserve header_len */ - *mtu = *mtu - rt->dst.header_len; - - } else { - /* - * this fragment is not first, the headers - * space is regarded as data space. - */ - *mtu = dst_mtu(rt->dst.path); - } - *maxfraglen = ((*mtu - fragheaderlen) & ~7) - + fragheaderlen - sizeof(struct frag_hdr); - } -} - int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int transhdrlen, @@ -1219,7 +1196,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct inet_cork *cork; - struct sk_buff *skb, *skb_prev = NULL; + struct sk_buff *skb; unsigned int maxfraglen, fragheaderlen; int exthdrlen; int dst_exthdrlen; @@ -1276,12 +1253,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, inet->cork.fl.u.ip6 = *fl6; np->cork.hop_limit = hlimit; np->cork.tclass = tclass; - if (rt->dst.flags & DST_XFRM_TUNNEL) - mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? - rt->dst.dev->mtu : dst_mtu(&rt->dst); - else - mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? - rt->dst.dev->mtu : dst_mtu(rt->dst.path); + mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? + rt->dst.dev->mtu : dst_mtu(&rt->dst); if (np->frag_size < mtu) { if (np->frag_size) mtu = np->frag_size; @@ -1377,27 +1350,25 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, unsigned int fraglen; unsigned int fraggap; unsigned int alloclen; + struct sk_buff *skb_prev; alloc_new_skb: + skb_prev = skb; + /* There's no room in the current skb */ - if (skb) - fraggap = skb->len - maxfraglen; + if (skb_prev) + fraggap = skb_prev->len - maxfraglen; else fraggap = 0; - /* update mtu and maxfraglen if necessary */ - if (skb == NULL || skb_prev == NULL) - ip6_append_data_mtu(&mtu, &maxfraglen, - fragheaderlen, skb, rt); - - skb_prev = skb; /* * If remaining data exceeds the mtu, * we know we need more fragment(s). */ datalen = length + fraggap; - if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen) - datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len; + datalen = maxfraglen - fragheaderlen; + + fraglen = datalen + fragheaderlen; if ((flags & MSG_MORE) && !(rt->dst.dev->features&NETIF_F_SG)) alloclen = mtu; @@ -1406,16 +1377,13 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, alloclen += dst_exthdrlen; - if (datalen != length + fraggap) { - /* - * this is not the last fragment, the trailer - * space is regarded as data space. - */ - datalen += rt->dst.trailer_len; - } - - alloclen += rt->dst.trailer_len; - fraglen = datalen + fragheaderlen; + /* + * The last fragment gets additional space at tail. + * Note: we overallocate on fragments with MSG_MODE + * because we have no idea if we're the last one. + */ + if (datalen == length + fraggap) + alloclen += rt->dst.trailer_len; /* * We just reserve space for fragment header. diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 70614e7affab..889f5d13d7ba 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -239,16 +239,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct inet_sock *inet = inet_sk(sk); struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *) uaddr; - int ret; + int ret = -EINVAL; int chk_addr_ret; - if (!sock_flag(sk, SOCK_ZAPPED)) - return -EINVAL; - if (addr_len < sizeof(struct sockaddr_l2tpip)) - return -EINVAL; - if (addr->l2tp_family != AF_INET) - return -EINVAL; - ret = -EADDRINUSE; read_lock_bh(&l2tp_ip_lock); if (__l2tp_ip_bind_lookup(&init_net, addr->l2tp_addr.s_addr, sk->sk_bound_dev_if, addr->l2tp_conn_id)) @@ -279,8 +272,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk_del_node_init(sk); write_unlock_bh(&l2tp_ip_lock); ret = 0; - sock_reset_flag(sk, SOCK_ZAPPED); - out: release_sock(sk); @@ -297,9 +288,6 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr; int rc; - if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */ - return -EINVAL; - if (addr_len < sizeof(*lsa)) return -EINVAL; @@ -323,14 +311,6 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len return rc; } -static int l2tp_ip_disconnect(struct sock *sk, int flags) -{ - if (sock_flag(sk, SOCK_ZAPPED)) - return 0; - - return udp_disconnect(sk, flags); -} - static int l2tp_ip_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { @@ -550,7 +530,7 @@ static struct proto l2tp_ip_prot = { .close = l2tp_ip_close, .bind = l2tp_ip_bind, .connect = l2tp_ip_connect, - .disconnect = l2tp_ip_disconnect, + .disconnect = udp_disconnect, .ioctl = udp_ioctl, .destroy = l2tp_ip_destroy_sock, .setsockopt = ip_setsockopt, diff --git a/trunk/net/l2tp/l2tp_ip6.c b/trunk/net/l2tp/l2tp_ip6.c index 35e1e4bde587..0291d8d85f30 100644 --- a/trunk/net/l2tp/l2tp_ip6.c +++ b/trunk/net/l2tp/l2tp_ip6.c @@ -258,10 +258,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) int addr_type; int err; - if (!sock_flag(sk, SOCK_ZAPPED)) - return -EINVAL; - if (addr->l2tp_family != AF_INET6) - return -EINVAL; if (addr_len < sizeof(*addr)) return -EINVAL; @@ -335,7 +331,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) sk_del_node_init(sk); write_unlock_bh(&l2tp_ip6_lock); - sock_reset_flag(sk, SOCK_ZAPPED); release_sock(sk); return 0; @@ -359,9 +354,6 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_type; int rc; - if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */ - return -EINVAL; - if (addr_len < sizeof(*lsa)) return -EINVAL; @@ -391,14 +383,6 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, return rc; } -static int l2tp_ip6_disconnect(struct sock *sk, int flags) -{ - if (sock_flag(sk, SOCK_ZAPPED)) - return 0; - - return udp_disconnect(sk, flags); -} - static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { @@ -705,7 +689,7 @@ static struct proto l2tp_ip6_prot = { .close = l2tp_ip6_close, .bind = l2tp_ip6_bind, .connect = l2tp_ip6_connect, - .disconnect = l2tp_ip6_disconnect, + .disconnect = udp_disconnect, .ioctl = udp_ioctl, .destroy = l2tp_ip6_destroy_sock, .setsockopt = ipv6_setsockopt, diff --git a/trunk/net/l2tp/l2tp_netlink.c b/trunk/net/l2tp/l2tp_netlink.c index ddc553e76671..8577264378fe 100644 --- a/trunk/net/l2tp/l2tp_netlink.c +++ b/trunk/net/l2tp/l2tp_netlink.c @@ -923,4 +923,5 @@ MODULE_AUTHOR("James Chapman "); MODULE_DESCRIPTION("L2TP netlink"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0"); -MODULE_ALIAS_GENL_FAMILY("l2tp"); +MODULE_ALIAS("net-pf-" __stringify(PF_NETLINK) "-proto-" \ + __stringify(NETLINK_GENERIC) "-type-" "l2tp"); diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 04c306308987..b3b3c264ff66 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -1522,8 +1522,6 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) * anymore. The timeout will be reset if the frame is ACKed by * the AP. */ - ifmgd->probe_send_count++; - if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { ifmgd->nullfunc_failed = false; ieee80211_send_nullfunc(sdata->local, sdata, 0); @@ -1540,6 +1538,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) 0, (u32) -1, true, false); } + ifmgd->probe_send_count++; ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); run_again(ifmgd, ifmgd->probe_timeout); if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 847215bb2a6f..5f827a6b0d8d 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, /* Don't calculate ACKs for QoS Frames with NoAck Policy set */ if (ieee80211_is_data_qos(hdr->frame_control) && - *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK) + *(ieee80211_get_qos_ctl(hdr)) | IEEE80211_QOS_CTL_ACK_POLICY_NOACK) dur = 0; else /* Time needed to transmit ACK diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index a44c6807df01..22f2216b397e 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -1371,12 +1371,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) } } - /* add back keys */ - list_for_each_entry(sdata, &local->interfaces, list) - if (ieee80211_sdata_running(sdata)) - ieee80211_enable_keys(sdata); - - wake_up: /* * Clear the WLAN_STA_BLOCK_BA flag so new aggregation * sessions can be established after a resume. @@ -1398,6 +1392,12 @@ int ieee80211_reconfig(struct ieee80211_local *local) mutex_unlock(&local->sta_mtx); } + /* add back keys */ + list_for_each_entry(sdata, &local->interfaces, list) + if (ieee80211_sdata_running(sdata)) + ieee80211_enable_keys(sdata); + + wake_up: ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); diff --git a/trunk/net/netlink/genetlink.c b/trunk/net/netlink/genetlink.c index 2cc7c1ee7690..8340ace837f2 100644 --- a/trunk/net/netlink/genetlink.c +++ b/trunk/net/netlink/genetlink.c @@ -836,7 +836,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) #ifdef CONFIG_MODULES if (res == NULL) { genl_unlock(); - request_module("net-pf-%d-proto-%d-family-%s", + request_module("net-pf-%d-proto-%d-type-%s", PF_NETLINK, NETLINK_GENERIC, name); genl_lock(); res = genl_family_find_byname(name); diff --git a/trunk/net/rds/ib.h b/trunk/net/rds/ib.h index 8d2b3d5a7c21..edfaaaf164eb 100644 --- a/trunk/net/rds/ib.h +++ b/trunk/net/rds/ib.h @@ -186,7 +186,8 @@ struct rds_ib_device { struct work_struct free_work; }; -#define ibdev_to_node(ibdev) dev_to_node(ibdev->dma_device) +#define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus) +#define ibdev_to_node(ibdev) pcidev_to_node(to_pci_dev(ibdev->dma_device)) #define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) /* bits for i_ack_flags */ diff --git a/trunk/net/wanrouter/Kconfig b/trunk/net/wanrouter/Kconfig index a157a2e64e18..61ceae0b9566 100644 --- a/trunk/net/wanrouter/Kconfig +++ b/trunk/net/wanrouter/Kconfig @@ -3,7 +3,7 @@ # config WAN_ROUTER - tristate "WAN router (DEPRECATED)" + tristate "WAN router" depends on EXPERIMENTAL ---help--- Wide Area Networks (WANs), such as X.25, frame relay and leased diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index ccfbd328a69d..c53e8f42aa75 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -1921,9 +1921,6 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, } ok: xfrm_pols_put(pols, drop_pols); - if (dst && dst->xfrm && - dst->xfrm->props.mode == XFRM_MODE_TUNNEL) - dst->flags |= DST_XFRM_TUNNEL; return dst; nopol: