* RE: [PATCH 2/3] powerpc/mpic: add global timer support
From: Wang Dongsheng-B40534 @ 2013-03-27 3:23 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <1364319099.469.6@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Wednesday, March 27, 2013 1:32 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Li Yang-R58472
> Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
>=20
> On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Saturday, March 23, 2013 6:30 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Li Yang-R58472
> > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > >
> > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wood Scott-B07421
> > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > To: Wang Dongsheng-B40534
> > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > linuxppc-dev@lists.ozlabs.org;
> > > > > Li Yang-R58472
> > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > > >
> > > > > BTW, the input clock frequency has been similarly scaled, yet
> > you
> > > > don't
> > > > > try to scrounge up that information to get further precision...
> > > > >
> > > > Let's go back patch, do you think the code is repeated?
> > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch,
> > there
> > > > will be no redundant code.
> > >
> > > I'd rather that branch be kept and the more complicated branch
> > deleted,
> > > and priv->timerfreq frequency be adjusted on initialization to
> > account
> > > for the scaler.
> >
> > static void convert_ticks_to_time(struct timer_group_priv *priv,
> > const u64 ticks, struct timeval *time) {
> > u64 tmp_sec;
> >
> > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > priv->timerfreq);
> > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> >
> > time->tv_usec =3D (__kernel_suseconds_t)
> > div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
> >
> > return;
> > }
> >
> > timer_group_get_freq() {
> > ...
> > if (priv->flags & FSL_GLOBAL_TIMER) {
> > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > priv->timerfreq /=3D div;
> > }
> > ...
> > }
> > Do you want to do that?
>=20
> if (priv->flags & FSL_GLOBAL_TIMER)
> priv->timerfreq /=3D 64;
>=20
> ...but otherwise yes.
Ok, I would like do this.
if (priv->flags & FSL_GLOBAL_TIMER) {
div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
priv->timerfreq /=3D div;
}
^ permalink raw reply
* [upstream] mtd/ifc: fix ifc driver memory release issue
From: Roy Zang @ 2013-03-27 12:25 UTC (permalink / raw)
To: linux-mtd; +Cc: Li Hao, scottwood, linuxppc-dev, dwmw2, Cao Yonghua
memory is allocated by devm_kzalloc, so release it using
devm_kfree() instead kfree();
Signed-off-by: Li Hao <b44421@freescale.com>
Signed-off-by: Cao Yonghua <b43619@freescale.com>
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
---
drivers/mtd/nand/fsl_ifc_nand.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index f1f7f12..b574ca4 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -908,7 +908,7 @@ static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv)
ifc_nand_ctrl->chips[priv->bank] = NULL;
dev_set_drvdata(priv->dev, NULL);
- kfree(priv);
+ devm_kfree(priv->dev, priv);
return 0;
}
@@ -974,6 +974,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev)
if (!ifc_nand_ctrl) {
dev_err(&dev->dev, "failed to allocate memory\n");
mutex_unlock(&fsl_ifc_nand_mutex);
+ devm_kfree(&dev->dev, priv);
return -ENOMEM;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH] powerpc: remove PReP
From: Paul Bolle @ 2013-03-27 10:47 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Rob Landley, Adam Belay,
Bjorn Helgaas, Florian Tobias Schandinat
Cc: linux-fbdev, linuxppc-dev, linux-kernel, linux-doc
In-Reply-To: <20130322042159.GC26908@concordia>
PPC_PREP is marked as BROKEN since v2.6.15. Remove all PReP specific
code now.
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
0) Suggested by Michael.
1) Sent as one patch. powerpc is the biggest chunk (if one includes the
doc changes). Is it easier if I split this into a number maintainer
specific patches? Ie, split into: powerpc, doc, pnp and fb.
2) None of this is tested. None! Since I'm not actually involved in
powerpc in any way, not everyone might consider me the first choice to
do this cleanup.
3) I removed two files in documentation that are almost entirely PReP
specific. The remaining lines looked uninteresting.
4) I grepped thoroughly for second order effects. I also grepped for
remaining references to PReP. This patch has all things I thought that
could be dropped. Perhaps doing
git grep -n PReP | grep -v -i -e rewritten -e dougan
might still reveal, to those familiar with PReP, a few places of
outdated stuff.
Documentation/powerpc/00-INDEX | 4 --
Documentation/powerpc/sound.txt | 81 ---------------------------------
Documentation/powerpc/zImage_layout.txt | 47 -------------------
arch/powerpc/Kconfig | 8 ++--
arch/powerpc/include/asm/dma.h | 5 --
arch/powerpc/include/asm/io.h | 4 --
arch/powerpc/include/asm/processor.h | 9 +---
arch/powerpc/kernel/setup-common.c | 6 ---
arch/powerpc/platforms/Kconfig | 3 +-
arch/powerpc/platforms/prep/Kconfig | 23 ----------
drivers/pnp/pnpbios/core.c | 9 +---
drivers/video/cirrusfb.c | 62 +++++--------------------
12 files changed, 19 insertions(+), 242 deletions(-)
delete mode 100644 Documentation/powerpc/sound.txt
delete mode 100644 Documentation/powerpc/zImage_layout.txt
delete mode 100644 arch/powerpc/platforms/prep/Kconfig
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index 5620fb5..dd9e928 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -14,10 +14,6 @@ hvcs.txt
- IBM "Hypervisor Virtual Console Server" Installation Guide
mpc52xx.txt
- Linux 2.6.x on MPC52xx family
-sound.txt
- - info on sound support under Linux/PPC
-zImage_layout.txt
- - info on the kernel images for Linux/PPC
qe_firmware.txt
- describes the layout of firmware binaries for the Freescale QUICC
Engine and the code that parses and uploads the microcode therein.
diff --git a/Documentation/powerpc/sound.txt b/Documentation/powerpc/sound.txt
deleted file mode 100644
index df23d95..0000000
--- a/Documentation/powerpc/sound.txt
+++ /dev/null
@@ -1,81 +0,0 @@
- Information about PowerPC Sound support
-=====================================================================
-
-Please mail me (Cort Dougan, cort@fsmlabs.com) if you have questions,
-comments or corrections.
-
-Last Change: 6.16.99
-
-This just covers sound on the PReP and CHRP systems for now and later
-will contain information on the PowerMac's.
-
-Sound on PReP has been tested and is working with the PowerStack and IBM
-Power Series onboard sound systems which are based on the cs4231(2) chip.
-The sound options when doing the make config are a bit different from
-the default, though.
-
-The I/O base, irq and dma lines that you enter during the make config
-are ignored and are set when booting according to the machine type.
-This is so that one binary can be used for Motorola and IBM machines
-which use different values and isn't allowed by the driver, so things
-are hacked together in such a way as to allow this information to be
-set automatically on boot.
-
-1. Motorola PowerStack PReP machines
-
- Enable support for "Crystal CS4232 based (PnP) cards" and for the
- Microsoft Sound System. The MSS isn't used, but some of the routines
- that the CS4232 driver uses are in it.
-
- Although the options you set are ignored and determined automatically
- on boot these are included for information only:
-
- (830) CS4232 audio I/O base 530, 604, E80 or F40
- (10) CS4232 audio IRQ 5, 7, 9, 11, 12 or 15
- (6) CS4232 audio DMA 0, 1 or 3
- (7) CS4232 second (duplex) DMA 0, 1 or 3
-
- This will allow simultaneous record and playback, as 2 different dma
- channels are used.
-
- The sound will be all left channel and very low volume since the
- auxiliary input isn't muted by default. I had the changes necessary
- for this in the kernel but the sound driver maintainer didn't want
- to include them since it wasn't common in other machines. To fix this
- you need to mute it using a mixer utility of some sort (if you find one
- please let me know) or by patching the driver yourself and recompiling.
-
- There is a problem on the PowerStack 2's (PowerStack Pro's) using a
- different irq/drq than the kernel expects. Unfortunately, I don't know
- which irq/drq it is so if anyone knows please email me.
-
- Midi is not supported since the cs4232 driver doesn't support midi yet.
-
-2. IBM PowerPersonal PReP machines
-
- I've only tested sound on the Power Personal Series of IBM workstations
- so if you try it on others please let me know the result. I'm especially
- interested in the 43p's sound system, which I know nothing about.
-
- Enable support for "Crystal CS4232 based (PnP) cards" and for the
- Microsoft Sound System. The MSS isn't used, but some of the routines
- that the CS4232 driver uses are in it.
-
- Although the options you set are ignored and determined automatically
- on boot these are included for information only:
-
- (530) CS4232 audio I/O base 530, 604, E80 or F40
- (5) CS4232 audio IRQ 5, 7, 9, 11, 12 or 15
- (1) CS4232 audio DMA 0, 1 or 3
- (7) CS4232 second (duplex) DMA 0, 1 or 3
- (330) CS4232 MIDI I/O base 330, 370, 3B0 or 3F0
- (9) CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15
-
- This setup does _NOT_ allow for recording yet.
-
- Midi is not supported since the cs4232 driver doesn't support midi yet.
-
-2. IBM CHRP
-
- I have only tested this on the 43P-150. Build the kernel with the cs4232
- set as a module and load the module with irq=9 dma=1 dma2=2 io=0x550
diff --git a/Documentation/powerpc/zImage_layout.txt b/Documentation/powerpc/zImage_layout.txt
deleted file mode 100644
index 048e015..0000000
--- a/Documentation/powerpc/zImage_layout.txt
+++ /dev/null
@@ -1,47 +0,0 @@
- Information about the Linux/PPC kernel images
-=====================================================================
-
-Please mail me (Cort Dougan, cort@fsmlabs.com) if you have questions,
-comments or corrections.
-
-This document is meant to answer several questions I've had about how
-the PReP system boots and how Linux/PPC interacts with that mechanism.
-It would be nice if we could have information on how other architectures
-boot here as well. If you have anything to contribute, please
-let me know.
-
-
-1. PReP boot file
-
- This is the file necessary to boot PReP systems from floppy or
- hard drive. The firmware reads the PReP partition table entry
- and will load the image accordingly.
-
- To boot the zImage, copy it onto a floppy with dd if=zImage of=/dev/fd0h1440
- or onto a PReP hard drive partition with dd if=zImage of=/dev/sda4
- assuming you've created a PReP partition (type 0x41) with fdisk on
- /dev/sda4.
-
- The layout of the image format is:
-
- 0x0 +------------+
- | | PReP partition table entry
- | |
- 0x400 +------------+
- | | Bootstrap program code + data
- | |
- | |
- +------------+
- | | compressed kernel, elf header removed
- +------------+
- | | initrd (if loaded)
- +------------+
- | | Elf section table for bootstrap program
- +------------+
-
-
-2. MBX boot file
-
- The MBX boards can load an elf image, and relocate it to the
- proper location in memory - it copies the image to the location it was
- linked at.
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ea5bb04..bc0a44f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -647,14 +647,14 @@ menu "Bus options"
config ISA
bool "Support for ISA-bus hardware"
- depends on PPC_PREP || PPC_CHRP
+ depends on PPC_CHRP
select PPC_I8259
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
inside your box. If you have an Apple machine, say N here; if you
- have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If
- you have an embedded board, consult your board documentation.
+ have an IBM RS/6000 or pSeries machine, say Y. If you have an
+ embedded board, consult your board documentation.
config ZONE_DMA
bool
@@ -969,7 +969,7 @@ config TASK_SIZE_BOOL
config TASK_SIZE
hex "Size of user task space" if TASK_SIZE_BOOL
- default "0x80000000" if PPC_PREP || PPC_8xx
+ default "0x80000000" if PPC_8xx
default "0xc0000000"
config CONSISTENT_SIZE_BOOL
diff --git a/arch/powerpc/include/asm/dma.h b/arch/powerpc/include/asm/dma.h
index f6813e9..a5c6d83 100644
--- a/arch/powerpc/include/asm/dma.h
+++ b/arch/powerpc/include/asm/dma.h
@@ -16,10 +16,6 @@
*
* None of this really applies for Power Macintoshes. There is
* basically just enough here to get kernel/dma.c to compile.
- *
- * There may be some comments or restrictions made here which are
- * not valid for the PReP platform. Take what you read
- * with a grain of salt.
*/
#include <asm/io.h>
@@ -57,7 +53,6 @@
* - page registers for 5-7 don't use data bit 0, represent 128K pages
* - page registers for 0-3 use bit 0, represent 64K pages
*
- * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory.
* On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing.
* Note that addresses loaded into registers must be _physical_ addresses,
* not logical addresses (which may differ if paging is active).
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index f94ef42..dd15e5e 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -15,10 +15,6 @@
extern int check_legacy_ioport(unsigned long base_port);
#define I8042_DATA_REG 0x60
#define FDC_BASE 0x3f0
-/* only relevant for PReP */
-#define _PIDXR 0x279
-#define _PNPWRP 0xa79
-#define PNPBIOS_BASE 0xf000
#if defined(CONFIG_PPC64) && defined(CONFIG_PCI)
extern struct pci_dev *isa_bridge_pcidev;
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 7ff9eaa..0a4cc5d 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -40,7 +40,7 @@
* -- BenH.
*/
-/* PREP sub-platform types see residual.h for these */
+/* PREP sub-platform types. Unused */
#define _PREP_Motorola 0x01 /* motorola prep */
#define _PREP_Firm 0x02 /* firmworks prep */
#define _PREP_IBM 0x00 /* ibm prep */
@@ -56,13 +56,6 @@
extern int _chrp_type;
-#ifdef CONFIG_PPC_PREP
-
-/* what kind of prep workstation we are */
-extern int _prep_type;
-
-#endif /* CONFIG_PPC_PREP */
-
#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */
/*
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index bdc499c..63d051f 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -621,12 +621,6 @@ int check_legacy_ioport(unsigned long base_port)
case FDC_BASE: /* FDC1 */
np = of_find_node_by_type(NULL, "fdc");
break;
-#ifdef CONFIG_PPC_PREP
- case _PIDXR:
- case _PNPWRP:
- case PNPBIOS_BASE:
- /* implement me */
-#endif
default:
/* ipmi is supposed to fail here */
break;
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 52de8bc..9089ae7 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -6,7 +6,6 @@ source "arch/powerpc/platforms/chrp/Kconfig"
source "arch/powerpc/platforms/512x/Kconfig"
source "arch/powerpc/platforms/52xx/Kconfig"
source "arch/powerpc/platforms/powermac/Kconfig"
-source "arch/powerpc/platforms/prep/Kconfig"
source "arch/powerpc/platforms/maple/Kconfig"
source "arch/powerpc/platforms/pasemi/Kconfig"
source "arch/powerpc/platforms/ps3/Kconfig"
@@ -233,7 +232,7 @@ endmenu
config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
- depends on 6xx && (PPC_PREP || PPC_PMAC)
+ depends on 6xx && PPC_PMAC
help
Some versions of the PPC601 (the first PowerPC chip) have bugs which
mean that extra synchronization instructions are required near
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
deleted file mode 100644
index 1547f66..0000000
--- a/arch/powerpc/platforms/prep/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-config PPC_PREP
- bool "PowerPC Reference Platform (PReP) based machines"
- depends on 6xx && BROKEN
- select HAVE_PCSPKR_PLATFORM
- select MPIC
- select PPC_I8259
- select PPC_INDIRECT_PCI
- select PPC_UDBG_16550
- select PPC_NATIVE
- default n
-
-config PREP_RESIDUAL
- bool "Support for PReP Residual Data"
- depends on PPC_PREP
- help
- Some PReP systems have residual data passed to the kernel by the
- firmware. This allows detection of memory size, devices present and
- other useful pieces of information. Sometimes this information is
- not present or incorrect, in which case it could lead to the machine
- behaving incorrectly. If this happens, either disable PREP_RESIDUAL
- or pass the 'noresidual' option to the kernel.
-
- If you are running a PReP system, say Y here, otherwise say N.
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 5d66e55..9b86a01 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -513,10 +513,6 @@ static int __init pnpbios_init(void)
{
int ret;
-#if defined(CONFIG_PPC)
- if (check_legacy_ioport(PNPBIOS_BASE))
- return -ENODEV;
-#endif
if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table) ||
paravirt_enabled()) {
printk(KERN_INFO "PnPBIOS: Disabled\n");
@@ -570,10 +566,7 @@ fs_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
struct task_struct *task;
-#if defined(CONFIG_PPC)
- if (check_legacy_ioport(PNPBIOS_BASE))
- return 0;
-#endif
+
if (pnpbios_disabled)
return 0;
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index c3dbbe6..97db3ba 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -53,12 +53,6 @@
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
#endif
-#ifdef CONFIG_PPC_PREP
-#include <asm/machdep.h>
-#define isPReP machine_is(prep)
-#else
-#define isPReP 0
-#endif
#include <video/vga.h>
#include <video/cirrus.h>
@@ -557,30 +551,18 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
break;
case 16:
- if (isPReP) {
- var->red.offset = 2;
- var->green.offset = -3;
- var->blue.offset = 8;
- } else {
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- }
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
var->red.length = 5;
var->green.length = 6;
var->blue.length = 5;
break;
case 24:
- if (isPReP) {
- var->red.offset = 0;
- var->green.offset = 8;
- var->blue.offset = 16;
- } else {
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- }
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
@@ -1874,17 +1856,6 @@ static void cirrusfb_imageblit(struct fb_info *info,
}
}
-#ifdef CONFIG_PPC_PREP
-#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
-#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
-static void get_prep_addrs(unsigned long *display, unsigned long *registers)
-{
- *display = PREP_VIDEO_BASE;
- *registers = (unsigned long) PREP_IO_BASE;
-}
-
-#endif /* CONFIG_PPC_PREP */
-
#ifdef CONFIG_PCI
static int release_io_ports;
@@ -2139,21 +2110,12 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
dev_dbg(info->device, " base address 1 is 0x%Lx\n",
(unsigned long long)pdev->resource[1].start);
- if (isPReP) {
- pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
-#ifdef CONFIG_PPC_PREP
- get_prep_addrs(&board_addr, &info->fix.mmio_start);
-#endif
- /* PReP dies if we ioremap the IO registers, but it works w/out... */
- cinfo->regbase = (char __iomem *) info->fix.mmio_start;
- } else {
- dev_dbg(info->device,
- "Attempt to get PCI info for Cirrus Graphics Card\n");
- get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
- /* FIXME: this forces VGA. alternatives? */
- cinfo->regbase = NULL;
- cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
- }
+ dev_dbg(info->device,
+ "Attempt to get PCI info for Cirrus Graphics Card\n");
+ get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
+ /* FIXME: this forces VGA. alternatives? */
+ cinfo->regbase = NULL;
+ cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
board_addr, info->fix.mmio_start);
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] powerpc: drop even more unused Kconfig symbols
From: Paul Bolle @ 2013-03-27 10:51 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1363864206.1390.117.camel@x61.thuisdomein>
On Thu, 2013-03-21 at 12:10 +0100, Paul Bolle wrote:
> diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
> index 79d2225..9eea710 100644
> --- a/arch/powerpc/platforms/wsp/Kconfig
> +++ b/arch/powerpc/platforms/wsp/Kconfig
> @@ -29,7 +29,3 @@ config PPC_CHROMA
> default y
>
> endmenu
> -
> -config PPC_A2_DD2
> - bool "Support for DD2 based A2/WSP systems"
> - depends on PPC_A2
This part was not included in the "powerpc: remove PReP" follow up
patch. Should I resend separately?
Paul Bolle
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Geert Uytterhoeven @ 2013-03-27 12:05 UTC (permalink / raw)
To: Paul Bolle
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev,
Adam Belay
In-Reply-To: <1364381223.1345.18.camel@x61.thuisdomein>
On Wed, Mar 27, 2013 at 11:47 AM, Paul Bolle <pebolle@tiscali.nl> wrote:
> 3) I removed two files in documentation that are almost entirely PReP
> specific. The remaining lines looked uninteresting.
> --- a/Documentation/powerpc/sound.txt
> +++ /dev/null
> -2. IBM CHRP
> -
> - I have only tested this on the 43P-150. Build the kernel with the cs4232
> - set as a module and load the module with irq=9 dma=1 dma2=2 io=0x550
This section is CHRP-specific. The cs4232 driver also worked on the
CHRP LongTrail.
But I don't remember if the parameter values above also applied to LongTrail.
I do remember it didn't work without specifing the right parameters, so you
probably want to keep this section.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Paul Bolle @ 2013-03-27 12:42 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev,
Adam Belay
In-Reply-To: <CAMuHMdVs-Xxu9e=8WZbTBXE1_+iYOBKODgj9_EKmVbZA3z=8JA@mail.gmail.com>
On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
> This section is CHRP-specific. The cs4232 driver also worked on the
> CHRP LongTrail.
> But I don't remember if the parameter values above also applied to LongTrail.
> I do remember it didn't work without specifing the right parameters, so you
> probably want to keep this section.
My reasoning was quite simply that this file was 14 years old so that
probably nobody is using that stuff anymore. Are people actually using
CHRP (whatever that is)? Anyhow, cs4232 is mentioned in some other files
too:
$ git grep -l -n cs4232 Documentation/
Documentation/powerpc/sound.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/alsa-parameters.txt
Documentation/sound/oss/Introduction
Documentation/sound/oss/Tropez+
Could these few lines be dumped in one of these (except
powerpc/sound.txt, of course)?
Paul Bolle
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Paul Bolle @ 2013-03-27 12:55 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-fbdev, Florian Tobias Schandinat, linux-doc, linux-kernel,
Paul Mackerras, Rob Landley, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1364388152.1345.29.camel@x61.thuisdomein>
By the way, I get bounces from Adam's address:
> I'm sorry to have to inform you that your message could not
> be delivered to one or more recipients. It's attached below.
>
> For further assistance, please send mail to <postmaster>
>
> If you do so, please include this problem report. You can
> delete your own text from the attached returned message.
>
> <abelay@mit.edu>: 550 5.1.1 <abelay@mit.edu>... User unknown
(It's now removed from the CC line.) Does anyone know what's going on
here?
Paul Bolle
^ permalink raw reply
* Re: [PATCHv2 1/3] pci: added pcie_get_speed_cap_mask function
From: Benjamin Herrenschmidt @ 2013-03-27 15:25 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: David Airlie, linux-pci@vger.kernel.org, DRI mailing list,
Alex Deucher, Thadeu Cascardo, Lucas Kannebley Tavares,
Brian King, linuxppc-dev
In-Reply-To: <CAErSpo4rc=8mYgwuTO6693QCQJ9nsPsxmh7YAwxMygiVrPQR0A@mail.gmail.com>
On Tue, 2013-03-26 at 12:39 -0600, Bjorn Helgaas wrote:
> But we also know pdev is a PCIe device, and I think a PCIe device on a
> root bus must be a "Root Complex Integrated Endpoint" (PCIe spec sec
> 1.3.2.3). Such a device does not have a link at all, so there's no
> point in fiddling with its link speed.
This is where our IBM hypervisor makes things murky. It doesn't expose
the PCIe parents (basically somewhat makes PCIe look like PCI except we
still have the PCIe caps on the child devices, just no access to the
parent device).
It's garbage but can't be fixed (would break AIX :-)
However we might be able to populate the bus->max_bus_speed from some
architecture specific quirk and have radeon use that.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Gary Thomas @ 2013-03-27 15:24 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1364388152.1345.29.camel@x61.thuisdomein>
On 2013-03-27 06:42, Paul Bolle wrote:
> On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
>> This section is CHRP-specific. The cs4232 driver also worked on the
>> CHRP LongTrail.
>> But I don't remember if the parameter values above also applied to LongTrail.
>> I do remember it didn't work without specifing the right parameters, so you
>> probably want to keep this section.
>
> My reasoning was quite simply that this file was 14 years old so that
> probably nobody is using that stuff anymore. Are people actually using
> CHRP (whatever that is)? Anyhow, cs4232 is mentioned in some other files
Common Hardware Reference Platform - see
http://en.wikipedia.org/wiki/Common_Hardware_Reference_Platform
> too:
> $ git grep -l -n cs4232 Documentation/
> Documentation/powerpc/sound.txt
> Documentation/sound/alsa/ALSA-Configuration.txt
> Documentation/sound/alsa/alsa-parameters.txt
> Documentation/sound/oss/Introduction
> Documentation/sound/oss/Tropez+
>
> Could these few lines be dumped in one of these (except
> powerpc/sound.txt, of course)?
>
Seeing this stuff go marks the end of an era (the PreP and CHRP
platforms were some of the very first devices to run Linux back
in 1995...) I just sent my last one to the recycler a few months
back :-(
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Re: [PATCH 1/7 v2] KVM: PPC: e500: Expose MMU registers via ONE_REG
From: Alexander Graf @ 2013-03-27 15:58 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-2-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> MMU registers were exposed to user-space using sregs interface. Add =
them
> to ONE_REG interface and use kvmppc_get_one_reg/kvmppc_set_one_reg =
delegation
> interface introduced by book3s.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Restrict set_one_reg operation for MMU registers to HW values
>=20
> Documentation/virtual/kvm/api.txt | 11 +++++
> arch/powerpc/include/uapi/asm/kvm.h | 17 +++++++
> arch/powerpc/kvm/44x.c | 12 +++++
> arch/powerpc/kvm/booke.c | 83 =
++++++++++++++++++++--------------
> arch/powerpc/kvm/e500.c | 14 ++++++
> arch/powerpc/kvm/e500.h | 4 ++
> arch/powerpc/kvm/e500_mmu.c | 84 =
+++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/e500mc.c | 14 ++++++
> 8 files changed, 205 insertions(+), 34 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index 976eb65..1a76663 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1792,6 +1792,17 @@ registers, find a list below:
> PPC | KVM_REG_PPC_TSR | 32
> PPC | KVM_REG_PPC_OR_TSR | 32
> PPC | KVM_REG_PPC_CLEAR_TSR | 32
> + PPC | KVM_REG_PPC_MAS0 | 32
> + PPC | KVM_REG_PPC_MAS1 | 32
> + PPC | KVM_REG_PPC_MAS2 | 64
> + PPC | KVM_REG_PPC_MAS7_3 | 64
> + PPC | KVM_REG_PPC_MAS4 | 32
> + PPC | KVM_REG_PPC_MAS6 | 32
> + PPC | KVM_REG_PPC_MMUCFG | 32
> + PPC | KVM_REG_PPC_TLB0CFG | 32
> + PPC | KVM_REG_PPC_TLB1CFG | 32
> + PPC | KVM_REG_PPC_TLB2CFG | 32
> + PPC | KVM_REG_PPC_TLB3CFG | 32
>=20
> ARM registers are mapped using the lower 32 bits. The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index ef072b1..777dc81 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -422,4 +422,21 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_CLEAR_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
> #define KVM_REG_PPC_TCR (KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x89)
> #define KVM_REG_PPC_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 =
| 0x8a)
> +
> +/* MMU registers */
> +#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
> +#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
> +#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8d)
> +#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
> +#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8f)
> +#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
> +#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
> +/*
> + * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed =
only using
> + * KVM_CAP_SW_TLB ioctl
> + */
> +#define KVM_REG_PPC_TLB0CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
> +#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
> +#define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
> +#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..2f5c6b6 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -124,6 +124,18 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + return -EINVAL;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + return -EINVAL;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_44x *vcpu_44x;
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 58057d6..c67e99f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1412,111 +1412,126 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct =
kvm_vcpu *vcpu,
>=20
> int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> - int r =3D -EINVAL;
> + int r =3D 0;
> + union kvmppc_one_reg val;
> + int size;
> + long int i;
> +
> + size =3D one_reg_size(reg->id);
> + if (size > sizeof(val))
> + return -EINVAL;
>=20
> switch (reg->id) {
> case KVM_REG_PPC_IAC1:
> case KVM_REG_PPC_IAC2:
> case KVM_REG_PPC_IAC3:
> case KVM_REG_PPC_IAC4: {
> - int iac =3D reg->id - KVM_REG_PPC_IAC1;
> - r =3D copy_to_user((u64 __user *)(long)reg->addr,
> - &vcpu->arch.dbg_reg.iac[iac], =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_IAC1;
> + val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
Please split this into a separate patch. You're merely cleaning up =
existing code here, not adding new functionality as the patch =
description says.
> break;
> }
> case KVM_REG_PPC_DAC1:
> case KVM_REG_PPC_DAC2: {
> - int dac =3D reg->id - KVM_REG_PPC_DAC1;
> - r =3D copy_to_user((u64 __user *)(long)reg->addr,
> - &vcpu->arch.dbg_reg.dac[dac], =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_DAC1;
> + val =3D get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
> break;
> }
> case KVM_REG_PPC_EPR: {
> u32 epr =3D get_guest_epr(vcpu);
> - r =3D put_user(epr, (u32 __user *)(long)reg->addr);
> + val =3D get_reg_val(reg->id, epr);
> break;
> }
> #if defined(CONFIG_64BIT)
> case KVM_REG_PPC_EPCR:
> - r =3D put_user(vcpu->arch.epcr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.epcr);
> break;
> #endif
> case KVM_REG_PPC_TCR:
> - r =3D put_user(vcpu->arch.tcr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.tcr);
> break;
> case KVM_REG_PPC_TSR:
> - r =3D put_user(vcpu->arch.tsr, (u32 __user =
*)(long)reg->addr);
> + val =3D get_reg_val(reg->id, vcpu->arch.tsr);
> break;
> default:
> + r =3D kvmppc_get_one_reg(vcpu, reg->id, &val);
> break;
> }
> +
> + if (r)
> + return r;
> +
> + if (copy_to_user((char __user *)(unsigned long)reg->addr, &val, =
size))
> + r =3D -EFAULT;
> +
> return r;
> }
>=20
> int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct =
kvm_one_reg *reg)
> {
> - int r =3D -EINVAL;
> + int r =3D 0;
> + union kvmppc_one_reg val;
> + int size;
> + long int i;
> +
> + size =3D one_reg_size(reg->id);
> + if (size > sizeof(val))
> + return -EINVAL;
> +
> + if (copy_from_user(&val, (char __user *)(unsigned =
long)reg->addr, size))
> + return -EFAULT;
>=20
> switch (reg->id) {
> case KVM_REG_PPC_IAC1:
> case KVM_REG_PPC_IAC2:
> case KVM_REG_PPC_IAC3:
> case KVM_REG_PPC_IAC4: {
> - int iac =3D reg->id - KVM_REG_PPC_IAC1;
> - r =3D copy_from_user(&vcpu->arch.dbg_reg.iac[iac],
> - (u64 __user *)(long)reg->addr, =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_IAC1;
> + vcpu->arch.dbg_reg.iac[i] =3D set_reg_val(reg->id, val);
> break;
> }
> case KVM_REG_PPC_DAC1:
> case KVM_REG_PPC_DAC2: {
> - int dac =3D reg->id - KVM_REG_PPC_DAC1;
> - r =3D copy_from_user(&vcpu->arch.dbg_reg.dac[dac],
> - (u64 __user *)(long)reg->addr, =
sizeof(u64));
> + i =3D reg->id - KVM_REG_PPC_DAC1;
> + vcpu->arch.dbg_reg.dac[i] =3D set_reg_val(reg->id, val);
> break;
> }
> case KVM_REG_PPC_EPR: {
> - u32 new_epr;
> - r =3D get_user(new_epr, (u32 __user *)(long)reg->addr);
> - if (!r)
> - kvmppc_set_epr(vcpu, new_epr);
> + u32 new_epr =3D set_reg_val(reg->id, val);
> + kvmppc_set_epr(vcpu, new_epr);
> break;
> }
> #if defined(CONFIG_64BIT)
> case KVM_REG_PPC_EPCR: {
> - u32 new_epcr;
> - r =3D get_user(new_epcr, (u32 __user *)(long)reg->addr);
> - if (r =3D=3D 0)
> - kvmppc_set_epcr(vcpu, new_epcr);
> + u32 new_epcr =3D set_reg_val(reg->id, val);
> + kvmppc_set_epcr(vcpu, new_epcr);
What about the sanity check?
> break;
> }
> #endif
> case KVM_REG_PPC_OR_TSR: {
> - u32 tsr_bits;
> - r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> + u32 tsr_bits =3D set_reg_val(reg->id, val);
> kvmppc_set_tsr_bits(vcpu, tsr_bits);
> break;
> }
> case KVM_REG_PPC_CLEAR_TSR: {
> - u32 tsr_bits;
> - r =3D get_user(tsr_bits, (u32 __user *)(long)reg->addr);
> + u32 tsr_bits =3D set_reg_val(reg->id, val);
> kvmppc_clr_tsr_bits(vcpu, tsr_bits);
> break;
> }
> case KVM_REG_PPC_TSR: {
> - u32 tsr;
> - r =3D get_user(tsr, (u32 __user *)(long)reg->addr);
> + u32 tsr =3D set_reg_val(reg->id, val);
> kvmppc_set_tsr(vcpu, tsr);
> break;
> }
> case KVM_REG_PPC_TCR: {
> - u32 tcr;
> - r =3D get_user(tcr, (u32 __user *)(long)reg->addr);
> + u32 tcr =3D set_reg_val(reg->id, val);
> kvmppc_set_tcr(vcpu, tcr);
> break;
> }
> default:
> + r =3D kvmppc_set_one_reg(vcpu, reg->id, &val);
> break;
> }
> +
> return r;
> }
>=20
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..ce6b73c 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -425,6 +425,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_e500 *vcpu_e500;
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 33db48a..b73ca7a 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct =
kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
> int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs =
*sregs);
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val);
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val);
>=20
> #ifdef CONFIG_KVM_E500V2
> unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index 5c44759..68c2b00 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -596,6 +596,90 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu =
*vcpu, struct kvm_sregs *sregs)
> return 0;
> }
>=20
> +int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D 0;
> + long int i;
> +
> + switch (id) {
> + case KVM_REG_PPC_MAS0:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas0);
Missing breaks?
Alex
> + case KVM_REG_PPC_MAS1:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas1);
> + case KVM_REG_PPC_MAS2:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas2);
> + case KVM_REG_PPC_MAS7_3:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas7_3);
> + case KVM_REG_PPC_MAS4:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas4);
> + case KVM_REG_PPC_MAS6:
> + *val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> + case KVM_REG_PPC_MMUCFG:
> + *val =3D get_reg_val(id, vcpu->arch.mmucfg);
> + case KVM_REG_PPC_TLB0CFG:
> + case KVM_REG_PPC_TLB1CFG:
> + case KVM_REG_PPC_TLB2CFG:
> + case KVM_REG_PPC_TLB3CFG:
> + i =3D id - KVM_REG_PPC_TLB0CFG;
> + *val =3D get_reg_val(id, vcpu->arch.tlbcfg[i]);
> + default:
> + r =3D -EINVAL;
> + break;
> + }
> +
> + return r;
> +}
> +
> +int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D 0;
> + long int i;
> +
> + switch (id) {
> + case KVM_REG_PPC_MAS0:
> + vcpu->arch.shared->mas0 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS1:
> + vcpu->arch.shared->mas1 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS2:
> + vcpu->arch.shared->mas2 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS7_3:
> + vcpu->arch.shared->mas7_3 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS4:
> + vcpu->arch.shared->mas4 =3D set_reg_val(id, *val);
> + break;
> + case KVM_REG_PPC_MAS6:
> + vcpu->arch.shared->mas6 =3D set_reg_val(id, *val);
> + break;
> + /* Only allow MMU registers to be set to the config supported by =
KVM */
> + case KVM_REG_PPC_MMUCFG: {
> + if (set_reg_val(id, *val) !=3D vcpu->arch.mmucfg)
> + r =3D -EINVAL;
> + break;
> + }
> + case KVM_REG_PPC_TLB0CFG:
> + case KVM_REG_PPC_TLB1CFG:
> + case KVM_REG_PPC_TLB2CFG:
> + case KVM_REG_PPC_TLB3CFG: {
> + /* MMU geometry (N_ENTRY/ASSOC) can be set only using =
SW_TLB */
> + i =3D id - KVM_REG_PPC_TLB0CFG;
> + if (set_reg_val(id, *val) !=3D vcpu->arch.tlbcfg[i])
> + r =3D -EINVAL;
> + break;
> + }
> + default:
> + r =3D -EINVAL;
> + break;
> + }
> +
> + return r;
> +}
> +
> int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
> struct kvm_config_tlb *cfg)
> {
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..ab073a8 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -255,6 +255,20 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, =
struct kvm_sregs *sregs)
> return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
>=20
> +int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_get_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> +int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
> + union kvmppc_one_reg *val)
> +{
> + int r =3D kvmppc_set_one_reg_e500_tlb(vcpu, id, val);
> + return r;
> +}
> +
> struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int =
id)
> {
> struct kvmppc_vcpu_e500 *vcpu_e500;
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] powerpc: remove PReP
From: Benjamin Herrenschmidt @ 2013-03-27 15:27 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Paul Bolle, Florian Tobias Schandinat, linux-doc, linux-fbdev,
linux-kernel, Paul Mackerras, Rob Landley, Bjorn Helgaas,
linuxppc-dev, Adam Belay
In-Reply-To: <CAMuHMdVs-Xxu9e=8WZbTBXE1_+iYOBKODgj9_EKmVbZA3z=8JA@mail.gmail.com>
On Wed, 2013-03-27 at 13:05 +0100, Geert Uytterhoeven wrote:
> On Wed, Mar 27, 2013 at 11:47 AM, Paul Bolle <pebolle@tiscali.nl> wrote:
> > 3) I removed two files in documentation that are almost entirely PReP
> > specific. The remaining lines looked uninteresting.
>
> > --- a/Documentation/powerpc/sound.txt
> > +++ /dev/null
>
> > -2. IBM CHRP
> > -
> > - I have only tested this on the 43P-150. Build the kernel with the cs4232
> > - set as a module and load the module with irq=9 dma=1 dma2=2 io=0x550
>
> This section is CHRP-specific. The cs4232 driver also worked on the
> CHRP LongTrail.
> But I don't remember if the parameter values above also applied to LongTrail.
> I do remember it didn't work without specifing the right parameters, so you
> probably want to keep this section.
Isn't LongTrail support LongDead ? Can we still boot these things at
all ? Anybody still has a functional one ?
Cheers,
Ben.
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply
* Re: [PATCHv2 1/3] pci: added pcie_get_speed_cap_mask function
From: Bjorn Helgaas @ 2013-03-27 16:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: David Airlie, linux-pci@vger.kernel.org, DRI mailing list,
Alex Deucher, Thadeu Cascardo, Lucas Kannebley Tavares,
Brian King, linuxppc-dev
In-Reply-To: <1364397928.11644.41.camel@pasglop>
On Wed, Mar 27, 2013 at 9:25 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Tue, 2013-03-26 at 12:39 -0600, Bjorn Helgaas wrote:
>> But we also know pdev is a PCIe device, and I think a PCIe device on a
>> root bus must be a "Root Complex Integrated Endpoint" (PCIe spec sec
>> 1.3.2.3). Such a device does not have a link at all, so there's no
>> point in fiddling with its link speed.
>
> This is where our IBM hypervisor makes things murky. It doesn't expose
> the PCIe parents (basically somewhat makes PCIe look like PCI except we
> still have the PCIe caps on the child devices, just no access to the
> parent device).
Interesting. I wonder if we'll trip over this anywhere else, e.g.,
ASPM or other link-related things. I guess we'll just have to see if
anything else breaks.
> It's garbage but can't be fixed (would break AIX :-)
>
> However we might be able to populate the bus->max_bus_speed from some
> architecture specific quirk and have radeon use that.
That sounds like a good solution to me. It seems like it's really an
arch-specific deviation from the spec, so it'd be nice to have an
arch-specific solution for it.
Bjorn
^ permalink raw reply
* Re: [PATCH 2/3] powerpc/mpic: add global timer support
From: Scott Wood @ 2013-03-27 17:11 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, Gala Kumar-B11780,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBB72D@039-SN2MPN1-022.039d.mgd.msft.net>
On 03/26/2013 10:23:38 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Wednesday, March 27, 2013 1:32 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Li Yang-R58472
> > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> >
> > On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Saturday, March 23, 2013 6:30 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Li Yang-R58472
> > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > >
> > > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Wood Scott-B07421
> > > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > > To: Wang Dongsheng-B40534
> > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > Li Yang-R58472
> > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer =20
> support
> > > > > >
> > > > > > BTW, the input clock frequency has been similarly scaled, =20
> yet
> > > you
> > > > > don't
> > > > > > try to scrounge up that information to get further =20
> precision...
> > > > > >
> > > > > Let's go back patch, do you think the code is repeated?
> > > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch,
> > > there
> > > > > will be no redundant code.
> > > >
> > > > I'd rather that branch be kept and the more complicated branch
> > > deleted,
> > > > and priv->timerfreq frequency be adjusted on initialization to
> > > account
> > > > for the scaler.
> > >
> > > static void convert_ticks_to_time(struct timer_group_priv *priv,
> > > const u64 ticks, struct timeval *time) {
> > > u64 tmp_sec;
> > >
> > > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > > priv->timerfreq);
> > > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> > >
> > > time->tv_usec =3D (__kernel_suseconds_t)
> > > div_u64((ticks - tmp_sec) * 1000000, =20
> priv->timerfreq);
> > >
> > > return;
> > > }
> > >
> > > timer_group_get_freq() {
> > > ...
> > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > > priv->timerfreq /=3D div;
> > > }
> > > ...
> > > }
> > > Do you want to do that?
> >
> > if (priv->flags & FSL_GLOBAL_TIMER)
> > priv->timerfreq /=3D 64;
> >
> > ...but otherwise yes.
> Ok, I would like do this.
>=20
> if (priv->flags & FSL_GLOBAL_TIMER) {
> div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> priv->timerfreq /=3D div;
Why? What do you get out of that obfuscation?
-Scott=
^ permalink raw reply
* Re: [PATCH 4/7 v2] KVM: PPC: e500: Add support for EPTCFG register
From: Alexander Graf @ 2013-03-27 17:21 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-5-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> EPTCFG register defined by E.PT is accessed unconditionally by Linux =
guests
> in the presence of MAV 2.0. Support it now.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Use has_feature() function
>=20
> Documentation/virtual/kvm/api.txt | 1 +
> arch/powerpc/include/asm/kvm_host.h | 1 +
> arch/powerpc/include/uapi/asm/kvm.h | 1 +
> arch/powerpc/kvm/e500.h | 5 +++++
> arch/powerpc/kvm/e500_emulate.c | 9 +++++++++
> arch/powerpc/kvm/e500_mmu.c | 11 +++++++++++
> 6 files changed, 28 insertions(+), 0 deletions(-)
>=20
> diff --git a/Documentation/virtual/kvm/api.txt =
b/Documentation/virtual/kvm/api.txt
> index f045377..a1f2200 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1807,6 +1807,7 @@ registers, find a list below:
> PPC | KVM_REG_PPC_TLB1PS | 32
> PPC | KVM_REG_PPC_TLB2PS | 32
> PPC | KVM_REG_PPC_TLB3PS | 32
> + PPC | KVM_REG_PPC_EPTCFG | 32
>=20
> ARM registers are mapped using the lower 32 bits. The upper 16 of =
that
> is the register group type, or coprocessor number:
> diff --git a/arch/powerpc/include/asm/kvm_host.h =
b/arch/powerpc/include/asm/kvm_host.h
> index 3b6cee3..8a48e68 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,6 +504,7 @@ struct kvm_vcpu_arch {
> u32 tlbcfg[4];
> u32 tlbps[4];
> u32 mmucfg;
> + u32 eptcfg;
> u32 epr;
> u32 crit_save;
> struct kvmppc_booke_debug_reg dbg_reg;
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h =
b/arch/powerpc/include/uapi/asm/kvm.h
> index 7cfd13f..9d7fbf0 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -443,4 +443,5 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
> #define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
> #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
> +#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index 795934d..6cfc669 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -24,6 +24,7 @@
> #include <asm/tlb.h>
>=20
> #define VCPU_FTR_MMU_V2 0
> +#define VCPU_FTR_E_PT 1
>=20
> #define E500_PID_NUM 3
> #define E500_TLB_NUM 2
> @@ -309,6 +310,10 @@ static inline bool has_feature(const struct =
kvm_vcpu *vcpu,
> case VCPU_FTR_MMU_V2:
> has_ftr =3D ((vcpu->arch.mmucfg & MMUCFG_MAVN) =3D=3D =
MMUCFG_MAVN_V2);
> break;
> + case VCPU_FTR_E_PT:
> + has_ftr =3D ((vcpu->arch.tlbcfg[1] & TLBnCFG_IND) &&
> + (vcpu->arch.tlbcfg[0] & TLBnCFG_PT));
> + break;
> default:
> has_ftr =3D false;
> }
> diff --git a/arch/powerpc/kvm/e500_emulate.c =
b/arch/powerpc/kvm/e500_emulate.c
> index 12b8de2..b10a012 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -317,6 +317,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu =
*vcpu, int sprn, ulong *spr_val)
> case SPRN_MMUCFG:
> *spr_val =3D vcpu->arch.mmucfg;
> break;
> + case SPRN_EPTCFG:
> + if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
> + return EMULATE_FAIL;
> + /*
> + * Legacy Linux guests access EPTCFG register even if =
the E.PT
> + * category is disabled in the VM. Give them a chance to =
live.
> + */
> + *spr_val =3D vcpu->arch.eptcfg;
> + break;
>=20
> /* extra exceptions */
> case SPRN_IVOR32:
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index e354fa1..cf60db1 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -617,6 +617,8 @@ int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> *val =3D get_reg_val(id, vcpu->arch.shared->mas6);
> case KVM_REG_PPC_MMUCFG:
> *val =3D get_reg_val(id, vcpu->arch.mmucfg);
> + case KVM_REG_PPC_EPTCFG:
> + *val =3D get_reg_val(id, vcpu->arch.eptcfg);
> case KVM_REG_PPC_TLB0CFG:
> case KVM_REG_PPC_TLB1CFG:
> case KVM_REG_PPC_TLB2CFG:
> @@ -668,6 +670,10 @@ int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu =
*vcpu, u64 id,
> r =3D -EINVAL;
> break;
> }
> + case KVM_REG_PPC_EPTCFG:
> + if (set_reg_val(id, *val) !=3D vcpu->arch.eptcfg)
> + r =3D -EINVAL;
> + break;
> case KVM_REG_PPC_TLB0CFG:
> case KVM_REG_PPC_TLB1CFG:
> case KVM_REG_PPC_TLB2CFG:
> @@ -861,6 +867,11 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + if (has_feature(vcpu, VCPU_FTR_E_PT))
> + vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
Can't we just always set it to 0?
Alex
> + else
> + vcpu->arch.eptcfg =3D 0;
> +
> vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> }
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Alexander Graf @ 2013-03-27 17:23 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-6-git-send-email-mihai.caraman@freescale.com>
On 26.03.2013, at 23:05, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =
entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
>=20
> arch/powerpc/kvm/e500_mmu.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
> if (has_feature(vcpu, VCPU_FTR_E_PT))
> vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
> else
> vcpu->arch.eptcfg =3D 0;
>=20
> + /* Guest mmu emulation currently doesn't handle E.PT */
> + vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> + vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;
Can we make this conditional on bits in EPTCFG? Then by initializing it =
to 0 today, we always mask PT/IND out, but later when we support EPT, we =
only have to set the bit in EPTCFG and everyone's happy?
Alex
> +
> vcpu->arch.tlbps[0] =3D mfspr(SPRN_TLB0PS);
> vcpu->arch.tlbps[1] =3D mfspr(SPRN_TLB1PS);
> }
> --=20
> 1.7.4.1
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 04/22] block: Convert bio_for_each_segment() to bvec_iter
From: Kent Overstreet @ 2013-03-27 17:39 UTC (permalink / raw)
To: axboe, linux-kernel, linux-fsdevel, dm-devel
Cc: Jeremy Fitzhardinge, Herton Ronaldo Krzesinski, Jan Kara,
Ed L. Cashin, neilb, Kent Overstreet, support, Paul Clements,
virtualization, Keith Busch, linux-mm, Quoc-Son Anh,
Paul Mackerras, James E.J. Bottomley, Stephen Hemminger,
Joshua Morris, Nick Piggin, devel, linux-s390, xen-devel,
Jerome Marchand, Mike Snitzer, linux-scsi, Minchan Kim,
Sebastian Ott, Philip Kelleher, Steven Whitehouse, cluster-devel,
Geert Uytterhoeven, Asai Thambi S P, Lars Ellenberg, Sam Bradshaw,
Nitin Gupta, cbe-oss-dev, nbd-general, Sage Weil,
Konrad Rzeszutek Wilk, Heiko Carstens, DL-MPTFusionLinux,
Chris Metcalf, linux-raid, Martin Schwidefsky, linux-m68k,
Alexander Viro, Selvan Mani, ceph-devel, drbd-user,
Nagalakshmi Nandigama, Yehuda Sadeh, Alex Elder, Seth Jennings,
Martin K. Petersen, Geoff Levand, Jiri Kosina, Darrick J. Wong,
Jim Paris, Sreekanth Reddy, Vivek Goyal, Greg Kroah-Hartman, tj,
linux390, Andrew Morton, linuxppc-dev, Guo Chao, Matthew Wilcox
In-Reply-To: <1364405992-28424-1-git-send-email-koverstreet@google.com>
More prep work for immutable biovecs - with immutable bvecs drivers
won't be able to use the biovec directly, they'll need to use helpers
that take into account bio->bi_iter.bi_bvec_done.
This updates callers for the new usage without changing the
implementation yet.
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "Ed L. Cashin" <ecashin@coraid.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Lars Ellenberg <drbd-dev@lists.linbit.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Paul Clements <Paul.Clements@steeleye.com>
Cc: Jim Paris <jim@jtan.com>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Yehuda Sadeh <yehuda@inktank.com>
Cc: Sage Weil <sage@inktank.com>
Cc: Alex Elder <elder@inktank.com>
Cc: ceph-devel@vger.kernel.org
Cc: Joshua Morris <josh.h.morris@us.ibm.com>
Cc: Philip Kelleher <pjk1939@linux.vnet.ibm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Neil Brown <neilb@suse.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
Cc: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Cc: support@lsi.com
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Kent Overstreet <koverstreet@google.com>
Cc: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Guo Chao <yan@linux.vnet.ibm.com>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Quoc-Son Anh <quoc-sonx.anh@intel.com>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Jerome Marchand <jmarchan@redhat.com>
Cc: Seth Jennings <sjenning@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mike Snitzer <snitzer@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-m68k@lists.linux-m68k.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: drbd-user@lists.linbit.com
Cc: nbd-general@lists.sourceforge.net
Cc: cbe-oss-dev@lists.ozlabs.org
Cc: xen-devel@lists.xensource.com
Cc: virtualization@lists.linux-foundation.org
Cc: linux-raid@vger.kernel.org
Cc: linux-s390@vger.kernel.org
Cc: DL-MPTFusionLinux@lsi.com
Cc: linux-scsi@vger.kernel.org
Cc: devel@driverdev.osuosl.org
Cc: linux-fsdevel@vger.kernel.org
Cc: cluster-devel@redhat.com
Cc: linux-mm@kvack.org
---
arch/m68k/emu/nfblock.c | 11 ++++---
arch/powerpc/sysdev/axonram.c | 18 +++++------
block/blk-merge.c | 45 ++++++++++++++-------------
drivers/block/aoe/aoecmd.c | 16 +++++-----
drivers/block/brd.c | 12 ++++----
drivers/block/drbd/drbd_main.c | 27 +++++++++--------
drivers/block/drbd/drbd_receiver.c | 13 ++++----
drivers/block/drbd/drbd_worker.c | 8 ++---
drivers/block/floppy.c | 12 ++++----
drivers/block/loop.c | 23 +++++++-------
drivers/block/mtip32xx/mtip32xx.c | 13 ++++----
drivers/block/nbd.c | 12 ++++----
drivers/block/nvme.c | 27 +++++++++--------
drivers/block/ps3vram.c | 10 +++---
drivers/block/rbd.c | 36 +++++++++++-----------
drivers/block/rsxx/dma.c | 11 ++++---
drivers/block/xen-blkfront.c | 14 ++++-----
drivers/md/md.c | 16 +++++-----
drivers/md/raid5.c | 12 ++++----
drivers/s390/block/dcssblk.c | 14 ++++-----
drivers/s390/block/xpram.c | 10 +++---
drivers/scsi/mpt2sas/mpt2sas_transport.c | 31 ++++++++++---------
drivers/scsi/mpt3sas/mpt3sas_transport.c | 31 ++++++++++---------
drivers/staging/zram/zram_drv.c | 19 ++++++------
fs/bio-integrity.c | 30 +++++++++---------
fs/bio.c | 16 +++++-----
fs/gfs2/lops.c | 10 +++---
include/linux/bio.h | 25 ++++++++-------
include/linux/blkdev.h | 7 +++--
mm/bounce.c | 52 +++++++++++++++-----------------
30 files changed, 296 insertions(+), 285 deletions(-)
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 9070d6c..d2b260c 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -62,17 +62,18 @@ struct nfhd_device {
static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
- struct bio_vec *bvec;
- int i, dir, len, shift;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+ int dir, len, shift;
sector_t sec = bio->bi_iter.bi_sector;
dir = bio_data_dir(bio);
shift = dev->bshift;
- bio_for_each_segment(bvec, bio, i) {
- len = bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- bvec_to_phys(bvec));
+ bvec_to_phys(&bvec));
sec += len;
}
bio_endio(bio, 0);
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index f33bcba..47b6b9f 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -109,28 +109,28 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
unsigned long phys_mem, phys_end;
void *user_mem;
- struct bio_vec *vec;
+ struct bio_vec vec;
unsigned int transfered;
- unsigned short idx;
+ struct bvec_iter iter;
phys_mem = bank->io_addr + (bio->bi_iter.bi_sector <<
AXON_RAM_SECTOR_SHIFT);
phys_end = bank->io_addr + bank->size;
transfered = 0;
- bio_for_each_segment(vec, bio, idx) {
- if (unlikely(phys_mem + vec->bv_len > phys_end)) {
+ bio_for_each_segment(vec, bio, iter) {
+ if (unlikely(phys_mem + vec.bv_len > phys_end)) {
bio_io_error(bio);
return;
}
- user_mem = page_address(vec->bv_page) + vec->bv_offset;
+ user_mem = page_address(vec.bv_page) + vec.bv_offset;
if (bio_data_dir(bio) == READ)
- memcpy(user_mem, (void *) phys_mem, vec->bv_len);
+ memcpy(user_mem, (void *) phys_mem, vec.bv_len);
else
- memcpy((void *) phys_mem, user_mem, vec->bv_len);
+ memcpy((void *) phys_mem, user_mem, vec.bv_len);
- phys_mem += vec->bv_len;
- transfered += vec->bv_len;
+ phys_mem += vec.bv_len;
+ transfered += vec.bv_len;
}
bio_endio(bio, 0);
}
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 5b04c25..cd15b38 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -12,10 +12,11 @@
static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio)
{
- struct bio_vec *bv, *bvprv = NULL;
- int cluster, i, high, highprv = 1;
+ struct bio_vec bv, bvprv;
+ int cluster, high, highprv = 1;
unsigned int seg_size, nr_phys_segs;
struct bio *fbio, *bbio;
+ struct bvec_iter iter;
if (!bio)
return 0;
@@ -25,25 +26,25 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
seg_size = 0;
nr_phys_segs = 0;
for_each_bio(bio) {
- bio_for_each_segment(bv, bio, i) {
+ bio_for_each_segment(bv, bio, iter) {
/*
* the trick here is making sure that a high page is
* never considered part of another segment, since that
* might change with the bounce page.
*/
- high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
+ high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
if (high || highprv)
goto new_segment;
if (cluster) {
- if (seg_size + bv->bv_len
+ if (seg_size + bv.bv_len
> queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
+ if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
+ if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv))
goto new_segment;
- seg_size += bv->bv_len;
+ seg_size += bv.bv_len;
bvprv = bv;
continue;
}
@@ -54,7 +55,7 @@ new_segment:
nr_phys_segs++;
bvprv = bv;
- seg_size = bv->bv_len;
+ seg_size = bv.bv_len;
highprv = high;
}
bbio = bio;
@@ -110,21 +111,21 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
return 0;
}
-static void
+static inline void
__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
- struct scatterlist *sglist, struct bio_vec **bvprv,
+ struct scatterlist *sglist, struct bio_vec *bvprv,
struct scatterlist **sg, int *nsegs, int *cluster)
{
int nbytes = bvec->bv_len;
- if (*bvprv && *cluster) {
+ if (*sg && *cluster) {
if ((*sg)->length + nbytes > queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec))
+ if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec))
+ if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
goto new_segment;
(*sg)->length += nbytes;
@@ -150,7 +151,7 @@ new_segment:
sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
(*nsegs)++;
}
- *bvprv = bvec;
+ *bvprv = *bvec;
}
/*
@@ -160,7 +161,7 @@ new_segment:
int blk_rq_map_sg(struct request_queue *q, struct request *rq,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct req_iterator iter;
struct scatterlist *sg;
int nsegs, cluster;
@@ -171,10 +172,9 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
/*
* for each bio in rq
*/
- bvprv = NULL;
sg = NULL;
rq_for_each_segment(bvec, rq, iter) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in rq */
@@ -223,18 +223,17 @@ EXPORT_SYMBOL(blk_rq_map_sg);
int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct scatterlist *sg;
int nsegs, cluster;
- unsigned long i;
+ struct bvec_iter iter;
nsegs = 0;
cluster = blk_queue_cluster(q);
- bvprv = NULL;
sg = NULL;
- bio_for_each_segment(bvec, bio, i) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ bio_for_each_segment(bvec, bio, iter) {
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in bio */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 80e5d65..63acfa1 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -887,12 +887,12 @@ rqbiocnt(struct request *r)
static void
bio_pageinc(struct bio *bio)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
struct page *page;
- int i;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- page = bv->bv_page;
+ bio_for_each_segment(bv, bio, iter) {
+ page = bv.bv_page;
/* Non-zero page count for non-head members of
* compound pages is no longer allowed by the kernel,
* but this has never been seen here.
@@ -909,11 +909,11 @@ bio_pageinc(struct bio *bio)
static void
bio_pagedec(struct bio *bio)
{
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i)
- atomic_dec(&bv->bv_page->_count);
+ bio_for_each_segment(bv, bio, iter)
+ atomic_dec(&bv.bv_page->_count);
}
static void
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index ddf2b79..0f3a3bb 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -328,9 +328,9 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
struct block_device *bdev = bio->bi_bdev;
struct brd_device *brd = bdev->bd_disk->private_data;
int rw;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
sector_t sector;
- int i;
+ struct bvec_iter iter;
int err = -EIO;
sector = bio->bi_iter.bi_sector;
@@ -347,10 +347,10 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
if (rw == READA)
rw = READ;
- bio_for_each_segment(bvec, bio, i) {
- unsigned int len = bvec->bv_len;
- err = brd_do_bvec(brd, bvec->bv_page, len,
- bvec->bv_offset, rw, sector);
+ bio_for_each_segment(bvec, bio, iter) {
+ unsigned int len = bvec.bv_len;
+ err = brd_do_bvec(brd, bvec.bv_page, len,
+ bvec.bv_offset, rw, sector);
if (err)
break;
sector += len >> SECTOR_SHIFT;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e98da67..e90074c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1537,15 +1537,17 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_no_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_no_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter)
+ ? 0 : MSG_MORE);
if (err)
return err;
}
@@ -1554,15 +1556,16 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter) ? 0 : MSG_MORE);
if (err)
return err;
}
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index bd27a65..7735ce0 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1593,9 +1593,10 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
sector_t sector, int data_size)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *bio;
- int dgs, err, i, expect;
+ int dgs, err, expect;
void *dig_in = mdev->tconn->int_dig_in;
void *dig_vv = mdev->tconn->int_dig_vv;
@@ -1615,11 +1616,11 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
bio = req->master_bio;
D_ASSERT(sector == bio->bi_iter.bi_sector);
- bio_for_each_segment(bvec, bio, i) {
- void *mapped = kmap(bvec->bv_page) + bvec->bv_offset;
- expect = min_t(int, data_size, bvec->bv_len);
+ bio_for_each_segment(bvec, bio, iter) {
+ void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
+ expect = min_t(int, data_size, bvec.bv_len);
err = drbd_recv_all_warn(mdev->tconn, mapped, expect);
- kunmap(bvec->bv_page);
+ kunmap(bvec.bv_page);
if (err)
return err;
data_size -= expect;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 424dc7b..f961a3b 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -312,8 +312,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
{
struct hash_desc desc;
struct scatterlist sg;
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
desc.tfm = tfm;
desc.flags = 0;
@@ -321,8 +321,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
sg_init_table(&sg, 1);
crypto_hash_init(&desc);
- bio_for_each_segment(bvec, bio, i) {
- sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
crypto_hash_update(&desc, &sg, sg.length);
}
crypto_hash_final(&desc, digest);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index f09fb23..ffea352 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2351,7 +2351,7 @@ static void rw_interrupt(void)
/* Compute maximal contiguous buffer size. */
static int buffer_chain_size(void)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
int size;
struct req_iterator iter;
char *base;
@@ -2360,10 +2360,10 @@ static int buffer_chain_size(void)
size = 0;
rq_for_each_segment(bv, current_req, iter) {
- if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+ if (page_address(bv.bv_page) + bv.bv_offset != base + size)
break;
- size += bv->bv_len;
+ size += bv.bv_len;
}
return size >> 9;
@@ -2389,7 +2389,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{
int remaining; /* number of transferred 512-byte sectors */
- struct bio_vec *bv;
+ struct bio_vec bv;
char *buffer;
char *dma_buffer;
int size;
@@ -2427,10 +2427,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
if (!remaining)
break;
- size = bv->bv_len;
+ size = bv.bv_len;
SUPBOUND(size, remaining);
- buffer = page_address(bv->bv_page) + bv->bv_offset;
+ buffer = page_address(bv.bv_page) + bv.bv_offset;
if (dma_buffer + size >
floppy_track_buffer + (max_buffer_sectors << 10) ||
dma_buffer < floppy_track_buffer) {
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2e4e0be..cd4a90e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -286,9 +286,10 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
{
int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
struct page *page);
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct page *page = NULL;
- int i, ret = 0;
+ int ret = 0;
if (lo->transfer != transfer_none) {
page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
@@ -300,11 +301,11 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
do_lo_send = do_lo_send_direct_write;
}
- bio_for_each_segment(bvec, bio, i) {
- ret = do_lo_send(lo, bvec, pos, page);
+ bio_for_each_segment(bvec, bio, iter) {
+ ret = do_lo_send(lo, &bvec, pos, page);
if (ret < 0)
break;
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
if (page) {
kunmap(page);
@@ -390,20 +391,20 @@ do_lo_receive(struct loop_device *lo,
static int
lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
ssize_t s;
- int i;
- bio_for_each_segment(bvec, bio, i) {
- s = do_lo_receive(lo, bvec, bsize, pos);
+ bio_for_each_segment(bvec, bio, iter) {
+ s = do_lo_receive(lo, &bvec, bsize, pos);
if (s < 0)
return s;
- if (s != bvec->bv_len) {
+ if (s != bvec.bv_len) {
zero_fill_bio(bio);
break;
}
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
return 0;
}
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 85b9f12..daf84a3 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3731,7 +3731,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
{
struct driver_data *dd = queue->queuedata;
struct scatterlist *sg;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int nents = 0;
int tag = 0;
@@ -3782,11 +3783,11 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
}
/* Create the scatter list for this bio. */
- bio_for_each_segment(bvec, bio, nents) {
- sg_set_page(&sg[nents],
- bvec->bv_page,
- bvec->bv_len,
- bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg[nents++],
+ bvec.bv_page,
+ bvec.bv_len,
+ bvec.bv_offset);
}
/* Issue the read/write. */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 7fecc78..c426d18 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -271,7 +271,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (nbd_cmd(req) == NBD_CMD_WRITE) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
/*
* we are really probing at internals to determine
* whether to set MSG_MORE or not...
@@ -281,8 +281,8 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (!rq_iter_last(req, iter))
flags = MSG_MORE;
dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
- result = sock_send_bvec(nbd, bvec, flags);
+ nbd->disk->disk_name, req, bvec.bv_len);
+ result = sock_send_bvec(nbd, &bvec, flags);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk),
"Send data failed (result %d)\n",
@@ -378,10 +378,10 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
nbd->disk->disk_name, req);
if (nbd_cmd(req) == NBD_CMD_READ) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
rq_for_each_segment(bvec, req, iter) {
- result = sock_recv_bvec(nbd, bvec);
+ result = sock_recv_bvec(nbd, &bvec);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
result);
@@ -389,7 +389,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
return req;
}
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
+ nbd->disk->disk_name, req, bvec.bv_len);
}
}
return req;
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index bc97493..faddcf3 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -380,7 +380,7 @@ static void bio_completion(struct nvme_dev *dev, void *ctx,
nvme_free_iod(dev, iod);
if (status) {
bio_endio(bio, -EIO);
- } else if (bio->bi_vcnt > bio->bi_iter.bi_idx) {
+ } else if (bio->bi_iter.bi_size) {
requeue_bio(dev, bio);
} else {
bio_endio(bio, 0);
@@ -476,33 +476,34 @@ static int nvme_setup_prps(struct nvme_dev *dev,
static int nvme_map_bio(struct device *dev, struct nvme_iod *iod,
struct bio *bio, enum dma_data_direction dma_dir, int psegs)
{
- struct bio_vec *bvec, *bvprv = NULL;
+ struct bio_vec bvec, bvprv;
+ struct bvec_iter iter;
struct scatterlist *sg = NULL;
- int i, old_idx, length = 0, nsegs = 0;
+ int length = 0, nsegs = 0, first = 1;
sg_init_table(iod->sg, psegs);
- old_idx = bio->bi_iter.bi_idx;
- bio_for_each_segment(bvec, bio, i) {
- if (bvprv && BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
- sg->length += bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) {
+ sg->length += bvec.bv_len;
} else {
- if (bvprv && BIOVEC_NOT_VIRT_MERGEABLE(bvprv, bvec))
+ if (!first && BIOVEC_NOT_VIRT_MERGEABLE(&bvprv, &bvec))
break;
sg = sg ? sg + 1 : iod->sg;
- sg_set_page(sg, bvec->bv_page, bvec->bv_len,
- bvec->bv_offset);
+ sg_set_page(sg, bvec.bv_page,
+ bvec.bv_len, bvec.bv_offset);
nsegs++;
}
- length += bvec->bv_len;
+ length += bvec.bv_len;
bvprv = bvec;
+ first = 0;
}
- bio->bi_iter.bi_idx = i;
iod->nents = nsegs;
sg_mark_end(sg);
if (dma_map_sg(dev, iod->sg, iod->nents, dma_dir) == 0) {
- bio->bi_iter.bi_idx = old_idx;
return -ENOMEM;
}
+
+ bio->bi_iter = iter;
return length;
}
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 75e112d..c30864d 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -555,14 +555,14 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
const char *op = write ? "write" : "read";
loff_t offset = bio->bi_sector << 9;
int error = 0;
- struct bio_vec *bvec;
- unsigned int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *next;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
/* PS3 is ppc64, so we don't handle highmem */
- char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
- size_t len = bvec->bv_len, retlen;
+ char *ptr = page_address(bvec.bv_page) + bvec.bv_offset;
+ size_t len = bvec.bv_len, retlen;
dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op,
len, offset);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 8115eb2..d1e4fd8 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -898,22 +898,22 @@ static void bio_chain_put(struct bio *chain)
*/
static void zero_bio_chain(struct bio *chain, int start_ofs)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
unsigned long flags;
void *buf;
- int i;
int pos = 0;
while (chain) {
- bio_for_each_segment(bv, chain, i) {
- if (pos + bv->bv_len > start_ofs) {
+ bio_for_each_segment(bv, chain, iter) {
+ if (pos + bv.bv_len > start_ofs) {
int remainder = max(start_ofs - pos, 0);
- buf = bvec_kmap_irq(bv, &flags);
+ buf = bvec_kmap_irq(&bv, &flags);
memset(buf + remainder, 0,
- bv->bv_len - remainder);
+ bv.bv_len - remainder);
bvec_kunmap_irq(buf, &flags);
}
- pos += bv->bv_len;
+ pos += bv.bv_len;
}
chain = chain->bi_next;
@@ -929,11 +929,11 @@ static struct bio *bio_clone_range(struct bio *bio_src,
unsigned int len,
gfp_t gfpmask)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
+ struct bvec_iter end_iter;
unsigned int resid;
- unsigned short idx;
unsigned int voff;
- unsigned short end_idx;
unsigned short vcnt;
struct bio *bio;
@@ -952,22 +952,22 @@ static struct bio *bio_clone_range(struct bio *bio_src,
/* Find first affected segment... */
resid = offset;
- bio_for_each_segment(bv, bio_src, idx) {
- if (resid < bv->bv_len)
+ bio_for_each_segment(bv, bio_src, iter) {
+ if (resid < bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
voff = resid;
/* ...and the last affected segment */
resid += len;
- __bio_for_each_segment(bv, bio_src, end_idx, idx) {
- if (resid <= bv->bv_len)
+ __bio_for_each_segment(bv, bio_src, end_iter, iter) {
+ if (resid <= bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
- vcnt = end_idx - idx + 1;
+ vcnt = end_iter.bi_idx = iter.bi_idx + 1;
/* Build the clone */
@@ -985,7 +985,7 @@ static struct bio *bio_clone_range(struct bio *bio_src,
* Copy over our part of the bio_vec, then update the first
* and last (or only) entries.
*/
- memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[idx],
+ memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[iter.bi_idx],
vcnt * sizeof (struct bio_vec));
bio->bi_io_vec[0].bv_offset += voff;
if (vcnt > 1) {
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index 81d92cb..3b35bb6 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -638,7 +638,8 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
void *cb_data)
{
struct list_head dma_list[RSXX_MAX_TARGETS];
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long long addr8;
unsigned int laddr;
unsigned int bv_len;
@@ -676,9 +677,9 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
bv_len -= RSXX_HW_BLK_SIZE;
}
} else {
- bio_for_each_segment(bvec, bio, i) {
- bv_len = bvec->bv_len;
- bv_off = bvec->bv_offset;
+ bio_for_each_segment(bvec, bio, iter) {
+ bv_len = bvec.bv_len;
+ bv_off = bvec.bv_offset;
while (bv_len > 0) {
tgt = rsxx_get_dma_tgt(card, addr8);
@@ -690,7 +691,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
st = rsxx_queue_dma(card, &dma_list[tgt],
bio_data_dir(bio),
dma_off, dma_len,
- laddr, bvec->bv_page,
+ laddr, bvec.bv_page,
bv_off, cb, cb_data);
if (st)
goto bvec_err;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index c3dae2e..ce5d5ad 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -844,7 +844,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
struct blkif_response *bret)
{
int i = 0;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
struct req_iterator iter;
unsigned long flags;
char *bvec_data;
@@ -859,18 +859,18 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
* to be sure we are copying the data from the right shared page.
*/
rq_for_each_segment(bvec, s->request, iter) {
- BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
- if (bvec->bv_offset < offset)
+ BUG_ON((bvec.bv_offset + bvec.bv_len) > PAGE_SIZE);
+ if (bvec.bv_offset < offset)
i++;
BUG_ON(i >= s->req.u.rw.nr_segments);
shared_data = kmap_atomic(
pfn_to_page(s->grants_used[i]->pfn));
- bvec_data = bvec_kmap_irq(bvec, &flags);
- memcpy(bvec_data, shared_data + bvec->bv_offset,
- bvec->bv_len);
+ bvec_data = bvec_kmap_irq(&bvec, &flags);
+ memcpy(bvec_data, shared_data + bvec.bv_offset,
+ bvec.bv_len);
bvec_kunmap_irq(bvec_data, &flags);
kunmap_atomic(shared_data);
- offset = bvec->bv_offset + bvec->bv_len;
+ offset = bvec.bv_offset + bvec.bv_len;
}
}
/* Add the persistent grant into the list of free grants */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4fae0aa..2421ccf 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -186,8 +186,8 @@ void md_trim_bio(struct bio *bio, int offset, int size)
* the given offset and size.
* This requires adjusting bi_sector, bi_size, and bi_io_vec
*/
- int i;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int sofar = 0;
size <<= 9;
@@ -209,14 +209,14 @@ void md_trim_bio(struct bio *bio, int offset, int size)
bio->bi_iter.bi_idx = 0;
}
/* Make sure vcnt and last bv are not too big */
- bio_for_each_segment(bvec, bio, i) {
- if (sofar + bvec->bv_len > size)
- bvec->bv_len = size - sofar;
- if (bvec->bv_len == 0) {
- bio->bi_vcnt = i;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (sofar + bvec.bv_len > size)
+ bvec.bv_len = size - sofar;
+ if (bvec.bv_len == 0) {
+ bio->bi_vcnt = iter.bi_idx;
break;
}
- sofar += bvec->bv_len;
+ sofar += bvec.bv_len;
}
}
EXPORT_SYMBOL_GPL(md_trim_bio);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a98cbbe..53e3a9e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -720,9 +720,9 @@ static struct dma_async_tx_descriptor *
async_copy_data(int frombio, struct bio *bio, struct page *page,
sector_t sector, struct dma_async_tx_descriptor *tx)
{
- struct bio_vec *bvl;
+ struct bio_vec bvl;
+ struct bvec_iter iter;
struct page *bio_page;
- int i;
int page_offset;
struct async_submit_ctl submit;
enum async_tx_flags flags = 0;
@@ -736,8 +736,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
flags |= ASYNC_TX_FENCE;
init_async_submit(&submit, flags, tx, NULL, NULL, NULL);
- bio_for_each_segment(bvl, bio, i) {
- int len = bvl->bv_len;
+ bio_for_each_segment(bvl, bio, iter) {
+ int len = bvl.bv_len;
int clen;
int b_offset = 0;
@@ -753,8 +753,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
clen = len;
if (clen > 0) {
- b_offset += bvl->bv_offset;
- bio_page = bvl->bv_page;
+ b_offset += bvl.bv_offset;
+ bio_page = bvl.bv_page;
if (frombio)
tx = async_memcpy(page, bio_page, page_offset,
b_offset, clen, &submit);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index bcebfba..3621e5a 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -812,12 +812,12 @@ static void
dcssblk_make_request(struct request_queue *q, struct bio *bio)
{
struct dcssblk_dev_info *dev_info;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long index;
unsigned long page_addr;
unsigned long source_addr;
unsigned long bytes_done;
- int i;
bytes_done = 0;
dev_info = bio->bi_bdev->bd_disk->private_data;
@@ -848,21 +848,21 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
}
index = (bio->bi_iter.bi_sector >> 3);
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- page_address(bvec->bv_page) + bvec->bv_offset;
+ page_address(bvec.bv_page) + bvec.bv_offset;
source_addr = dev_info->start + (index<<12) + bytes_done;
if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
// More paranoia.
goto fail;
if (bio_data_dir(bio) == READ) {
memcpy((void*)page_addr, (void*)source_addr,
- bvec->bv_len);
+ bvec.bv_len);
} else {
memcpy((void*)source_addr, (void*)page_addr,
- bvec->bv_len);
+ bvec.bv_len);
}
- bytes_done += bvec->bv_len;
+ bytes_done += bvec.bv_len;
}
bio_endio(bio, 0);
return;
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 0330859..c478839 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -184,11 +184,11 @@ static unsigned long xpram_highest_page_index(void)
static void xpram_make_request(struct request_queue *q, struct bio *bio)
{
xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned int index;
unsigned long page_addr;
unsigned long bytes;
- int i;
if ((bio->bi_iter.bi_sector & 7) != 0 ||
(bio->bi_iter.bi_size & 4095) != 0)
@@ -200,10 +200,10 @@ static void xpram_make_request(struct request_queue *q, struct bio *bio)
if ((bio->bi_iter.bi_sector >> 3) > 0xffffffffU - xdev->offset)
goto fail;
index = (bio->bi_iter.bi_sector >> 3) + xdev->offset;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- kmap(bvec->bv_page) + bvec->bv_offset;
- bytes = bvec->bv_len;
+ kmap(bvec.bv_page) + bvec.bv_offset;
+ bytes = bvec.bv_len;
if ((page_addr & 4095) != 0 || (bytes & 4095) != 0)
/* More paranoia. */
goto fail;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 193e7ae..2c2e01e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -1898,7 +1898,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1913,7 +1913,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
@@ -1952,11 +1953,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2103,19 +2104,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 87ca2b7..dd15b2d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -1881,7 +1881,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1895,7 +1895,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n",
@@ -1935,11 +1936,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2064,19 +2065,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 4d395a5..cd0ed36 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -367,9 +367,10 @@ static void update_position(u32 *index, int *offset, struct bio_vec *bvec)
static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
{
- int i, offset;
+ int offset;
u32 index;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
switch (rw) {
case READ:
@@ -384,33 +385,33 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
offset = (bio->bi_iter.bi_sector &
(SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int max_transfer_size = PAGE_SIZE - offset;
- if (bvec->bv_len > max_transfer_size) {
+ if (bvec.bv_len > max_transfer_size) {
/*
* zram_bvec_rw() can only make operation on a single
* zram page. Split the bio vector.
*/
struct bio_vec bv;
- bv.bv_page = bvec->bv_page;
+ bv.bv_page = bvec.bv_page;
bv.bv_len = max_transfer_size;
- bv.bv_offset = bvec->bv_offset;
+ bv.bv_offset = bvec.bv_offset;
if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
goto out;
- bv.bv_len = bvec->bv_len - max_transfer_size;
+ bv.bv_len = bvec.bv_len - max_transfer_size;
bv.bv_offset += max_transfer_size;
if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
goto out;
} else
- if (zram_bvec_rw(zram, bvec, index, offset, bio, rw)
+ if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
< 0)
goto out;
- update_position(&index, &offset, bvec);
+ update_position(&index, &offset, &bvec);
}
set_bit(BIO_UPTODATE, &bio->bi_flags);
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index f824c30..4220b96 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -299,25 +299,26 @@ static void bio_integrity_generate(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_iter.bi_sector;
- unsigned int i, sectors, total;
+ unsigned int sectors, total;
void *prot_buf = bio->bi_integrity->bip_buf;
total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
bi->generate_fn(&bix);
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
@@ -441,19 +442,20 @@ static int bio_integrity_verify(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_integrity->bip_sector;
- unsigned int i, sectors, total, ret;
+ unsigned int sectors, total, ret;
void *prot_buf = bio->bi_integrity->bip_buf;
ret = total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
@@ -464,7 +466,7 @@ static int bio_integrity_verify(struct bio *bio)
return ret;
}
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
diff --git a/fs/bio.c b/fs/bio.c
index 8543f85..400f90c 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -472,13 +472,13 @@ EXPORT_SYMBOL(bio_alloc_bioset);
void zero_fill_bio(struct bio *bio)
{
unsigned long flags;
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- char *data = bvec_kmap_irq(bv, &flags);
- memset(data, 0, bv->bv_len);
- flush_dcache_page(bv->bv_page);
+ bio_for_each_segment(bv, bio, iter) {
+ char *data = bvec_kmap_irq(&bv, &flags);
+ memset(data, 0, bv.bv_len);
+ flush_dcache_page(bv.bv_page);
bvec_kunmap_irq(data, &flags);
}
}
@@ -1676,10 +1676,10 @@ void bio_check_pages_dirty(struct bio *bio)
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
void bio_flush_dcache_pages(struct bio *bi)
{
- int i;
struct bio_vec *bvec;
+ struct bvec_iter iter;
- bio_for_each_segment(bvec, bi, i)
+ bio_for_each_segment(bvec, bi, iter)
flush_dcache_page(bvec->bv_page);
}
EXPORT_SYMBOL(bio_flush_dcache_pages);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 7b2399b..fa9fceb 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -203,19 +203,19 @@ static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
static void gfs2_end_log_write(struct bio *bio, int error)
{
struct gfs2_sbd *sdp = bio->bi_private;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct page *page;
- int i;
if (error) {
sdp->sd_log_error = error;
fs_err(sdp, "Error %d writing to log\n", error);
}
- bio_for_each_segment(bvec, bio, i) {
- page = bvec->bv_page;
+ bio_for_each_segment(bvec, bio, iter) {
+ page = bvec.bv_page;
if (page_has_buffers(page))
- gfs2_end_log_write_bh(sdp, bvec, error);
+ gfs2_end_log_write_bh(sdp, &bvec, error);
else
mempool_free(page, gfs2_page_pool);
}
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 580c9ae..a31bcd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -61,6 +61,8 @@
* various member access, note that bio_data should of course not be used
* on highmem page vectors
*/
+#define bio_iovec_iter(bio, iter) ((bio)->bi_io_vec[(iter).bi_idx])
+
#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)]))
#define __bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_iter.bi_idx)
#define bio_iovec(bio) (*__bio_iovec(bio))
@@ -134,15 +136,6 @@ static inline void *bio_data(struct bio *bio)
#define bio_io_error(bio) bio_endio((bio), -EIO)
/*
- * drivers should not use the __ version unless they _really_ know what
- * they're doing
- */
-#define __bio_for_each_segment(bvl, bio, i, start_idx) \
- for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \
- i < (bio)->bi_vcnt; \
- bvl++, i++)
-
-/*
* drivers should _never_ use the all version - the bio may have been split
* before it got to the driver and the driver won't own all of it
*/
@@ -151,10 +144,16 @@ static inline void *bio_data(struct bio *bio)
bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
i++)
-#define bio_for_each_segment(bvl, bio, i) \
- for (i = (bio)->bi_iter.bi_idx; \
- bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
- i++)
+#define __bio_for_each_segment(bvl, bio, iter, start) \
+ for (iter = (start); \
+ bvl = bio_iovec_iter((bio), (iter)), \
+ (iter).bi_idx < (bio)->bi_vcnt; \
+ (iter).bi_idx++)
+
+#define bio_for_each_segment(bvl, bio, iter) \
+ __bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
+
+#define bio_iter_last(bio, iter) ((iter).bi_idx == (bio)->bi_vcnt - 1)
/*
* get a reference to a bio, so it won't disappear. the intended use is
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 89d89c7..f589ed3 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -699,7 +699,7 @@ struct rq_map_data {
};
struct req_iterator {
- int i;
+ struct bvec_iter iter;
struct bio *bio;
};
@@ -712,10 +712,11 @@ struct req_iterator {
#define rq_for_each_segment(bvl, _rq, _iter) \
__rq_for_each_bio(_iter.bio, _rq) \
- bio_for_each_segment(bvl, _iter.bio, _iter.i)
+ bio_for_each_segment(bvl, _iter.bio, _iter.iter)
#define rq_iter_last(rq, _iter) \
- (_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1)
+ (_iter.bio->bi_next == NULL && \
+ bio_iter_last(_iter.bio, _iter.iter))
#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
# error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform"
diff --git a/mm/bounce.c b/mm/bounce.c
index f5326b2..deaf1b0 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -98,27 +98,24 @@ int init_emergency_isa_pool(void)
static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
{
unsigned char *vfrom;
- struct bio_vec *tovec, *fromvec;
- int i;
-
- bio_for_each_segment(tovec, to, i) {
- fromvec = from->bi_io_vec + i;
-
- /*
- * not bounced
- */
- if (tovec->bv_page == fromvec->bv_page)
- continue;
-
- /*
- * fromvec->bv_offset and fromvec->bv_len might have been
- * modified by the block layer, so use the original copy,
- * bounce_copy_vec already uses tovec->bv_len
- */
- vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
+ struct bio_vec tovec, *fromvec = from->bi_io_vec;
+ struct bvec_iter iter;
+
+ bio_for_each_segment(tovec, to, iter) {
+ if (tovec.bv_page != fromvec->bv_page) {
+ /*
+ * fromvec->bv_offset and fromvec->bv_len might have
+ * been modified by the block layer, so use the original
+ * copy, bounce_copy_vec already uses tovec->bv_len
+ */
+ vfrom = page_address(fromvec->bv_page) +
+ tovec.bv_offset;
+
+ bounce_copy_vec(&tovec, vfrom);
+ flush_dcache_page(tovec.bv_page);
+ }
- bounce_copy_vec(tovec, vfrom);
- flush_dcache_page(tovec->bv_page);
+ fromvec++;
}
}
@@ -184,8 +181,8 @@ static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
struct page *page;
struct backing_dev_info *bdi;
struct address_space *mapping;
- struct bio_vec *from;
- int i;
+ struct bio_vec from;
+ struct bvec_iter iter;
if (bio_data_dir(bio) != WRITE)
return 0;
@@ -197,8 +194,8 @@ static int must_snapshot_stable_pages(struct request_queue *q, struct bio *bio)
* Based on the first page that has a valid mapping, decide whether or
* not we have to employ bounce buffering to guarantee stable pages.
*/
- bio_for_each_segment(from, bio, i) {
- page = from->bv_page;
+ bio_for_each_segment(from, bio, iter) {
+ page = from.bv_page;
mapping = page_mapping(page);
if (!mapping)
continue;
@@ -220,11 +217,12 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
{
struct bio *bio;
int rw = bio_data_dir(*bio_orig);
- struct bio_vec *to, *from;
+ struct bio_vec *to, from;
+ struct bvec_iter iter;
unsigned i;
- bio_for_each_segment(from, *bio_orig, i)
- if (page_to_pfn(from->bv_page) > queue_bounce_pfn(q))
+ bio_for_each_segment(from, *bio_orig, iter)
+ if (page_to_pfn(from.bv_page) > queue_bounce_pfn(q))
goto bounce;
return;
--
1.8.1.3
^ permalink raw reply related
* Re: [PATCH 5/7 v2] KVM: PPC: e500: Remove E.PT and E.HV.LRAT categories from VCPUs
From: Scott Wood @ 2013-03-27 17:50 UTC (permalink / raw)
To: Mihai Caraman; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1364335512-28426-6-git-send-email-mihai.caraman@freescale.com>
On 03/26/2013 05:05:10 PM, Mihai Caraman wrote:
> Embedded.Page Table (E.PT) category in VMs requires indirect tlb =20
> entries
> emulation which is not supported yet. Configure TLBnCFG to remove E.PT
> and E.HV.LRAT categories from VCPUs.
>=20
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> ---
> v2:
> - Remove E.HV.LRAT from vcpus
>=20
> arch/powerpc/kvm/e500_mmu.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c
> index cf60db1..0d2a293 100644
> --- a/arch/powerpc/kvm/e500_mmu.c
> +++ b/arch/powerpc/kvm/e500_mmu.c
> @@ -867,11 +867,17 @@ static int vcpu_mmu_init(struct kvm_vcpu *vcpu,
> vcpu->arch.tlbcfg[1] |=3D params[1].ways << TLBnCFG_ASSOC_SHIFT;
>=20
> if (has_feature(vcpu, VCPU_FTR_MMU_V2)) {
> + vcpu->arch.mmucfg &=3D ~MMUCFG_LRAT;
> +
> if (has_feature(vcpu, VCPU_FTR_E_PT))
> vcpu->arch.eptcfg =3D mfspr(SPRN_EPTCFG);
> else
> vcpu->arch.eptcfg =3D 0;
>=20
> + /* Guest mmu emulation currently doesn't handle E.PT */
> + vcpu->arch.tlbcfg[0] &=3D ~TLBnCFG_PT;
> + vcpu->arch.tlbcfg[1] &=3D ~TLBnCFG_IND;
You're clearing these bits *after* calling has_feature() -- doesn't =20
has_feature() depend on those bits being cleared to not advertise E_PT =20
support?
-Scott=
^ permalink raw reply
* Re: [PATCH 3/3] cpufreq: Add cpufreq driver for Freescale e500mc SOCs
From: Kim Phillips @ 2013-03-27 19:32 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: rjw, linuxppc-dev, cpufreq, linux-pm
In-Reply-To: <1364265391-26077-3-git-send-email-Yuantian.Tang@freescale.com>
On Tue, 26 Mar 2013 10:36:31 +0800
<Yuantian.Tang@freescale.com> wrote:
> +static int __init ppc_corenet_cpufreq_init(void)
> +{
> + int ret = 0;
> + struct device_node *np;
> + const struct of_device_id *match;
> +
> + np = of_find_matching_node(NULL, node_matches);
> + if (!np)
> + return -ENODEV;
> +
> + match = of_match_node(node_matches, np);
> + freq_data.cpus_per_cluster = (long)match->data;
> + mutex_init(&freq_data.cpufreq_lock);
> + of_node_put(np);
> +
> + ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> + if (ret)
> + return ret;
> +
> + pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +
> + return ret;
> +}
> +
> +static void __exit ppc_corenet_cpufreq_exit(void)
> +{
> + cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +}
> +
> +module_init(ppc_corenet_cpufreq_init);
> +module_exit(ppc_corenet_cpufreq_exit);
this needs to be a module_platform_driver.
Kim
^ permalink raw reply
* Re: [PATCH 2/3] x86/mm/numa: use setup_nr_node_ids() instead of opencoding.
From: H. Peter Anvin @ 2013-03-27 19:32 UTC (permalink / raw)
To: Yinghai Lu
Cc: Cody P Schafer, linux-kernel, linux-mm, Ingo Molnar,
Paul Mackerras, Andrew Morton, linuxppc-dev, Thomas Gleixner
In-Reply-To: <CAE9FiQVSPdCqaLKapG4DJ1CXtPKb8F29=s_-e9OLpXP7yG1XTA@mail.gmail.com>
On 03/26/2013 10:56 AM, Yinghai Lu wrote:
>
> For 1 and 2,
>
> Acked-by: Yinghai Lu <yinghai@kernel.org>
>
Similarly:
Acked-by: H. Peter Anvin <hpa@linux.intel.com>
-hpa
^ permalink raw reply
* Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
From: Scott Wood @ 2013-03-27 20:25 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, Gala Kumar-B11780,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Zhao Chenhui-B35336
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EBB71C@039-SN2MPN1-022.039d.mgd.msft.net>
On 03/26/2013 10:21:04 PM, Wang Dongsheng-B40534 wrote:
>=20
>=20
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Wednesday, March 27, 2013 1:36 AM
> > To: Wang Dongsheng-B40534
> > Cc: Wood Scott-B07421; Gala Kumar-B11780; =20
> linuxppc-dev@lists.ozlabs.org;
> > Zhao Chenhui-B35336; Li Yang-R58472
> > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
> >
> > On 03/25/2013 10:27:24 PM, Wang Dongsheng-B40534 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Wood Scott-B07421
> > > > Sent: Saturday, March 23, 2013 6:11 AM
> > > > To: Wang Dongsheng-B40534
> > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > linuxppc-dev@lists.ozlabs.org;
> > > > Zhao Chenhui-B35336; Li Yang-R58472
> > > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup =20
> support
> > > >
> > > > On 03/22/2013 12:46:24 AM, Wang Dongsheng-B40534 wrote:
> > > > > Under what case is unsafe, please make sense.
> > > >
> > > > char buffer[1] =3D { '5' };
> > > > write(fd, &buffer, 1);
> > > >
> > > > What comes after that '5' byte in the pointer you pass to =20
> kstrtol?
> > > >
> > > The buffer is userspace. It will fall in the kernel space.
> > > Kernel will get a free page, and copy the buffer to page.
> > > This page has been cleared before copy to page.
> > > The page has already have null-terminated.
> >
> > It doesn't allocate a whole page, it uses kmalloc (not kzalloc!). =20
> Even
> > if kzalloc were used, a larger user buffer could be the exact size =20
> of the
> > region that was allocated.
> >
> > See memdup_user() in mm/util.c
> >
> Did you miss something?
> See fill_write_buffer() in fs/sysfs/file.c. It's used =20
> get_zeroed_page()...
OK, I was looking at fs/sysfs/bin.c which is something slightly =20
different.
fill_write_buffer() forces the size to be no more than "PAGE_SIZE - 1" =20
so we know there's a terminator.
Perhaps kernel/rtmutex-tester.c and kernel/time/clocksource.c are =20
similarly confused?
-Scott=
^ permalink raw reply
* Re: [PATCH] powerpc: drop even more unused Kconfig symbols
From: Michael Ellerman @ 2013-03-28 0:31 UTC (permalink / raw)
To: Paul Bolle; +Cc: linuxppc-dev, linux-kernel, Paul Mackerras
In-Reply-To: <1364381495.1345.21.camel@x61.thuisdomein>
On Wed, Mar 27, 2013 at 11:51:35AM +0100, Paul Bolle wrote:
> On Thu, 2013-03-21 at 12:10 +0100, Paul Bolle wrote:
> > diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
> > index 79d2225..9eea710 100644
> > --- a/arch/powerpc/platforms/wsp/Kconfig
> > +++ b/arch/powerpc/platforms/wsp/Kconfig
> > @@ -29,7 +29,3 @@ config PPC_CHROMA
> > default y
> >
> > endmenu
> > -
> > -config PPC_A2_DD2
> > - bool "Support for DD2 based A2/WSP systems"
> > - depends on PPC_A2
>
> This part was not included in the "powerpc: remove PReP" follow up
> patch. Should I resend separately?
Yes thanks.
It was added in commit a1d0d98 "Add WSP platform" but should not have
been, it was to support bringup hacks that were never merged upstream.
cheers
^ permalink raw reply
* RE: [PATCH 2/3] powerpc/mpic: add global timer support
From: Wang Dongsheng-B40534 @ 2013-03-28 2:29 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <1364404295.31930.1@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 28, 2013 1:12 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Li Yang-R58472
> Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
>=20
> On 03/26/2013 10:23:38 PM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Wednesday, March 27, 2013 1:32 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Li Yang-R58472
> > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > >
> > > On 03/25/2013 10:29:58 PM, Wang Dongsheng-B40534 wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wood Scott-B07421
> > > > > Sent: Saturday, March 23, 2013 6:30 AM
> > > > > To: Wang Dongsheng-B40534
> > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > linuxppc-dev@lists.ozlabs.org;
> > > > > Li Yang-R58472
> > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer support
> > > > >
> > > > > On 03/22/2013 01:14:51 AM, Wang Dongsheng-B40534 wrote:
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Wood Scott-B07421
> > > > > > > Sent: Thursday, March 21, 2013 7:00 AM
> > > > > > > To: Wang Dongsheng-B40534
> > > > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > > > linuxppc-dev@lists.ozlabs.org;
> > > > > > > Li Yang-R58472
> > > > > > > Subject: Re: [PATCH 2/3] powerpc/mpic: add global timer
> > support
> > > > > > >
> > > > > > > BTW, the input clock frequency has been similarly scaled,
> > yet
> > > > you
> > > > > > don't
> > > > > > > try to scrounge up that information to get further
> > precision...
> > > > > > >
> > > > > > Let's go back patch, do you think the code is repeated?
> > > > > > I will remove "if (!(priv->flags & FSL_GLOBAL_TIMER))" branch,
> > > > there
> > > > > > will be no redundant code.
> > > > >
> > > > > I'd rather that branch be kept and the more complicated branch
> > > > deleted,
> > > > > and priv->timerfreq frequency be adjusted on initialization to
> > > > account
> > > > > for the scaler.
> > > >
> > > > static void convert_ticks_to_time(struct timer_group_priv *priv,
> > > > const u64 ticks, struct timeval *time) {
> > > > u64 tmp_sec;
> > > >
> > > > time->tv_sec =3D (__kernel_time_t)div_u64(ticks,
> > > > priv->timerfreq);
> > > > tmp_sec =3D (u64)time->tv_sec * (u64)priv->timerfreq;
> > > >
> > > > time->tv_usec =3D (__kernel_suseconds_t)
> > > > div_u64((ticks - tmp_sec) * 1000000,
> > priv->timerfreq);
> > > >
> > > > return;
> > > > }
> > > >
> > > > timer_group_get_freq() {
> > > > ...
> > > > if (priv->flags & FSL_GLOBAL_TIMER) {
> > > > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > > > priv->timerfreq /=3D div;
> > > > }
> > > > ...
> > > > }
> > > > Do you want to do that?
> > >
> > > if (priv->flags & FSL_GLOBAL_TIMER)
> > > priv->timerfreq /=3D 64;
> > >
> > > ...but otherwise yes.
> > Ok, I would like do this.
> >
> > if (priv->flags & FSL_GLOBAL_TIMER) {
> > div =3D (1 << (MPIC_TIMER_TCR_CLKDIV_64 >> 8)) * 8;
> > priv->timerfreq /=3D div;
>=20
> Why? What do you get out of that obfuscation?
>=20
Change MPIC_TIMER_TCR_CLKDIV_64 to MPIC_TIMER_TCR_CLKDIV
/* Clock Ratio
* Divide by 64 0x00000300
* Divide by 32 0x00000200
* Divide by 16 0x00000100
* Divide by 8 0x00000000 (Hardware default div)
*/
#define MPIC_TIMER_TCR_CLKDIV 0x00000300
timer_group_init() {
...
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
...
}
mpic_timer_resume() {
...
/* Init FSL timer hardware */
if (priv->flags & FSL_GLOBAL_TIMER)
setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
...
}
Because macro is friendly, and other functions also used the macro.
^ permalink raw reply
* RE: [PATCH 3/3] cpufreq: Add cpufreq driver for Freescale e500mc SOCs
From: Tang Yuantian-B29983 @ 2013-03-28 3:02 UTC (permalink / raw)
To: Phillips Kim-R1AAHA
Cc: rjw@sisk.pl, linuxppc-dev@lists.ozlabs.org,
cpufreq@vger.kernel.org, linux-pm@vger.kernel.org
In-Reply-To: <20130327143236.7cb4613b78ad18d79bfbcc57@freescale.com>
> > + return ret;
> > +
> > + pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> > +
> > + return ret;
> > +}
> > +
> > +static void __exit ppc_corenet_cpufreq_exit(void) {
> > + cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +}
> > +
> > +module_init(ppc_corenet_cpufreq_init);
> > +module_exit(ppc_corenet_cpufreq_exit);
>=20
> this needs to be a module_platform_driver.
>=20
The compatible string is used for clock driver.
This driver can not be a platform_driver.
-Yuantian
^ permalink raw reply
* RE: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
From: Wang Dongsheng-B40534 @ 2013-03-28 3:09 UTC (permalink / raw)
To: Wood Scott-B07421
Cc: Gala Kumar-B11780, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Zhao Chenhui-B35336
In-Reply-To: <1364415959.31930.16@snotra>
> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Thursday, March 28, 2013 4:26 AM
> To: Wang Dongsheng-B40534
> Cc: Wood Scott-B07421; Gala Kumar-B11780; linuxppc-dev@lists.ozlabs.org;
> Zhao Chenhui-B35336; Li Yang-R58472
> Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
>=20
> On 03/26/2013 10:21:04 PM, Wang Dongsheng-B40534 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Wednesday, March 27, 2013 1:36 AM
> > > To: Wang Dongsheng-B40534
> > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > linuxppc-dev@lists.ozlabs.org;
> > > Zhao Chenhui-B35336; Li Yang-R58472
> > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup support
> > >
> > > On 03/25/2013 10:27:24 PM, Wang Dongsheng-B40534 wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Wood Scott-B07421
> > > > > Sent: Saturday, March 23, 2013 6:11 AM
> > > > > To: Wang Dongsheng-B40534
> > > > > Cc: Wood Scott-B07421; Gala Kumar-B11780;
> > > > linuxppc-dev@lists.ozlabs.org;
> > > > > Zhao Chenhui-B35336; Li Yang-R58472
> > > > > Subject: Re: [PATCH 3/3] powerpc/fsl: add MPIC timer wakeup
> > support
> > > > >
> > > > > On 03/22/2013 12:46:24 AM, Wang Dongsheng-B40534 wrote:
> > > > > > Under what case is unsafe, please make sense.
> > > > >
> > > > > char buffer[1] =3D { '5' };
> > > > > write(fd, &buffer, 1);
> > > > >
> > > > > What comes after that '5' byte in the pointer you pass to
> > kstrtol?
> > > > >
> > > > The buffer is userspace. It will fall in the kernel space.
> > > > Kernel will get a free page, and copy the buffer to page.
> > > > This page has been cleared before copy to page.
> > > > The page has already have null-terminated.
> > >
> > > It doesn't allocate a whole page, it uses kmalloc (not kzalloc!).
> > Even
> > > if kzalloc were used, a larger user buffer could be the exact size
> > of the
> > > region that was allocated.
> > >
> > > See memdup_user() in mm/util.c
> > >
> > Did you miss something?
> > See fill_write_buffer() in fs/sysfs/file.c. It's used
> > get_zeroed_page()...
>=20
> OK, I was looking at fs/sysfs/bin.c which is something slightly different=
.
>=20
> fill_write_buffer() forces the size to be no more than "PAGE_SIZE - 1"
> so we know there's a terminator.
>=20
> Perhaps kernel/rtmutex-tester.c and kernel/time/clocksource.c are
> similarly confused?
>=20
Yes. But its depends on file->f_op.
See vfs_write in fs/read_write.c.
^ permalink raw reply
* [PATCH 2/2 v2] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
From: Yuantian.Tang @ 2013-03-28 9:55 UTC (permalink / raw)
To: rjw; +Cc: linux-pm, viresh.kumar, cpufreq, Tang Yuantian, linuxppc-dev
From: Tang Yuantian <yuantian.tang@freescale.com>
Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs
which are capable of changing the frequency of CPU dynamically
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v2:
- change the per_cpu variable to point type
- fixed other issues
drivers/cpufreq/Kconfig.powerpc | 10 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/ppc-corenet-cpufreq.c | 255 ++++++++++++++++++++++++++++++++++
3 files changed, 266 insertions(+)
create mode 100644 drivers/cpufreq/ppc-corenet-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index e76992f..3a0d8d0 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
help
This adds support for frequency switching on Maple 970FX
Evaluation Board and compatible boards (IBM JS2x blades).
+
+config PPC_CORENET_CPUFREQ
+ tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
+ depends on PPC_E500MC && OF && COMMON_CLK
+ select CPU_FREQ_TABLE
+ select CLK_PPC_CORENET
+ help
+ This adds the CPUFreq driver support for Freescale e500mc,
+ e5500 and e6500 series SoCs which are capable of changing
+ the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..2416559 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
##################################################################################
# PowerPC platform drivers
obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o
+obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
new file mode 100644
index 0000000..a50ab5a
--- /dev/null
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/**
+ * struct cpufreq_data - cpufreq driver data
+ * @cpus_per_cluster: CPU numbers per cluster
+ * @cpufreq_lock: the mutex lock
+ */
+struct cpufreq_data {
+ int cpus_per_cluster;
+ struct mutex cpufreq_lock;
+};
+
+/**
+ * struct cpu_data - per CPU data struct
+ * @clk: the clk data of CPU
+ * @parent: the parent node of clock of cpu
+ * @table: frequency table point
+ */
+struct cpu_data {
+ struct clk *clk;
+ struct device_node *parent;
+ struct cpufreq_frequency_table *table;
+};
+
+static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
+static struct cpufreq_data freq_data;
+
+static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
+{
+ struct cpu_data *data = per_cpu(cpu_data, cpu);
+
+ return clk_get_rate(data->clk) / 1000;
+}
+
+/* reduce the duplicated frequency in frequency table */
+static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
+ int count)
+{
+ int i, j;
+
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
+ freq_table[j].frequency !=
+ freq_table[i].frequency)
+ continue;
+
+ freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ break;
+ }
+ }
+}
+
+static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned int cpu = policy->cpu;
+ struct device_node *np;
+ int i, count;
+ struct clk *clk;
+ struct cpufreq_frequency_table *table;
+ struct cpu_data *data;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(struct cpu_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = of_clk_get(np, 0);
+ data->parent = of_parse_phandle(np, "clocks", 0);
+ if (!data->parent) {
+ pr_err("%s: could not get clock information\n", __func__);
+ goto err_nomem2;
+ }
+
+ count = of_property_count_strings(data->parent, "clock-names");
+
+ table = kcalloc(count + 1,
+ sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
+ if (!table) {
+ pr_err("%s: no memory\n", __func__);
+ goto err_nomem2;
+ }
+
+ for (i = cpu; i < freq_data.cpus_per_cluster + cpu; i++)
+ cpumask_set_cpu(i, policy->cpus);
+
+ for (i = 0; i < count; i++) {
+ table[i].index = i;
+ clk = of_clk_get(data->parent, i);
+ table[i].frequency = clk_get_rate(clk) / 1000;
+ }
+ freq_table_redup(table, count);
+ table[i].frequency = CPUFREQ_TABLE_END;
+
+ data->table = table;
+ per_cpu(cpu_data, cpu) = data;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = corenet_cpufreq_get_speed(policy->cpu);
+
+ /* set the min and max frequency properly */
+ i = cpufreq_frequency_table_cpuinfo(policy, table);
+ if (i) {
+ pr_err("invalid frequency table: %d\n", i);
+ goto err_nomem1;
+ }
+ cpufreq_frequency_table_get_attr(table, cpu);
+
+ return 0;
+
+err_nomem1:
+ kfree(table);
+err_nomem2:
+ per_cpu(cpu_data, cpu) = NULL;
+ kfree(data);
+
+ return -ENODEV;
+}
+
+static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ kfree(data->table);
+ kfree(data);
+
+ return 0;
+}
+
+static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *table;
+
+ table = per_cpu(cpu_data, policy->cpu)->table;
+
+ return cpufreq_frequency_table_verify(policy, table);
+}
+
+static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned int new;
+ struct clk *parent;
+ int ret;
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_target(policy, data->table,
+ target_freq, relation, &new);
+
+ if (policy->cur == data->table[new].frequency)
+ return 0;
+
+ freqs.old = policy->cur;
+ freqs.new = data->table[new].frequency;
+ freqs.cpu = policy->cpu;
+
+ mutex_lock(&freq_data.cpufreq_lock);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ parent = of_clk_get(data->parent, new);
+ ret = clk_set_parent(data->clk, parent);
+ if (ret) {
+ mutex_unlock(&freq_data.cpufreq_lock);
+ return ret;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&freq_data.cpufreq_lock);
+
+ return 0;
+}
+
+static struct freq_attr *corenet_cpu_clks_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
+ .name = "ppc_cpufreq",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = corenet_cpufreq_cpu_init,
+ .exit = __exit_p(corenet_cpufreq_cpu_exit),
+ .verify = corenet_cpufreq_verify,
+ .target = corenet_cpufreq_target,
+ .get = corenet_cpufreq_get_speed,
+ .attr = corenet_cpu_clks_attr,
+};
+
+static const struct of_device_id node_matches[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
+ { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
+ {}
+};
+
+static int __init ppc_corenet_cpufreq_init(void)
+{
+ int ret = 0;
+ struct device_node *np;
+ const struct of_device_id *match;
+
+ np = of_find_matching_node(NULL, node_matches);
+ if (!np)
+ return -ENODEV;
+
+ match = of_match_node(node_matches, np);
+ freq_data.cpus_per_cluster = (unsigned long)match->data;
+ mutex_init(&freq_data.cpufreq_lock);
+ of_node_put(np);
+
+ ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+ if (ret)
+ return ret;
+
+ pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+
+ return ret;
+}
+module_init(ppc_corenet_cpufreq_init);
+
+static void __exit ppc_corenet_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+}
+module_exit(ppc_corenet_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
--
1.8.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox