All of lore.kernel.org
 help / color / mirror / Atom feed
* No Subject
@ 2000-11-19 20:02 jingai
  0 siblings, 0 replies; 409+ messages in thread
From: jingai @ 2000-11-19 20:02 UTC (permalink / raw)
  To: linuxppc-dev


This may not be the appropriate list to post this on, but since it
does work on my x86 box at work, here goes...

I'm having trouble burning multisession discs with cdrdao.  My
TOC file is as follows:

CD_ROM_XA
TRACK AUDIO
FILE "audio.raw" 0

TRACK MODE2_FORM1
DATAFILE "data.raw"

And the command line:

cdrdao write --multi --device 1,4,0 my.toc

Here is the output from cdrdao:

Cdrdao version 1.1.3 - (C) Andreas Mueller <mueller@daneb.ping.de>
  SCSI interface library - (C) Joerg Schilling
  L-EC encoding library - (C) Heiko Eissfeldt
  Paranoia DAE library - (C) Monty

1,4,0: YAMAHA CRW6416S  Rev: 1.0c
Using driver: Generic SCSI-3/MMC - Version 1.0 (data) (options 0x0000)

Starting write simulation at speed 6...
Pausing 10 seconds - hit CTRL-C to abort.
Process can be aborted with QUIT signal (usually CTRL-\).
Using POSIX real time scheduling.
Executing power calibration...
cdrdao: No such device or address. Cannot set SG_SET_TIMEOUT.

It is apparently failing on the power calibration, but with the same
CD writer at work, it does not fail here.

My second problem happens both on x86 and PowerPC.  If I
specify the --multi option to cdrdao, it fails shortly after the
burn begins (it does write some data to the disc though) with
a buffer underrun.  If I omit the --multi option, it burns fine
on x86.  Seeing as I am trying to burn a multisession disc,
it's kind of necessary (I think?) to specify the --multi
option.

Both boxes are running Debian woody and kernel 2.2.18pre21.

Any help would be greatly appreciated.

Regards,
Jonathan


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No Subject
@ 2001-08-24 22:16 abraxas2
  0 siblings, 0 replies; 409+ messages in thread
From: abraxas2 @ 2001-08-24 22:16 UTC (permalink / raw)
  To: linux-kernel

hi everybody,

i have implemented an improved linux ntfs driver.

the following changes have been done :

- full deletion support
- full hardlink support
- support for multiple mft records
- support for chmod, rename, truncate, df, du, ...
- implemented new tools ntchmod, ntlink, ntrm, ntundel (undeletion)
  there is a NT port of the tools, too
- fixed a bunch of FIXME's and another bunch of bugs

the kernel part of the sources increased almost to the double.

one of the performed tests was a complete linux kernel build on a
ntfs volume. without any complaints by chkdsk.


this is currently for kernel 2.2.x.

work is in progress for the following items :
- support for kernel 2.4.x
- support for symlinks, device files and chown/chgrp
- full support for compressed files

if you are interested, please send me an email. please indicate if you
want only the kernel part or the complete sources.

Abraxas

<abraxas2@findhere.com>



^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 19:26 Pawel Kot
@ 2002-08-03 21:45 ` Alan Cox
  2002-08-03 21:58   ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 409+ messages in thread
From: Alan Cox @ 2002-08-03 21:45 UTC (permalink / raw)
  To: Pawel Kot
  Cc: Marcelo Tosatti, Linux Kernel Mailing List,
	Bartlomiej Zolnierkiewicz

On Sat, 2002-08-03 at 20:26, Pawel Kot wrote:
> What helped me was using fixup_device_piix() from -ac in
> ide_scan_pcidev(). My controler's ID is DEVID_ICH3M.
> It is used in a different, more generic way in -ac, so I don't post the
> patch.
> 
> Alan, Marcelo: is there any chance that this change will be ported from
> -ac in 2.4.20?

I plan to send Marcelo all the IDE updates. Note btw the checking of the
return value on pci_enable_device is critical - some old kernels hang on
boot with crappy bioses through not checking.

What I begin to the think the right answer is, is to relax the IDE fixup
block in the i386 kernel boot up. Right now we avoid assigning
unassigned resources for IDE controllers. Clearly we should be doing so.


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 21:45 ` No Subject Alan Cox
@ 2002-08-03 21:58   ` Bartlomiej Zolnierkiewicz
  2002-08-03 22:16     ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 409+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2002-08-03 21:58 UTC (permalink / raw)
  To: Alan Cox; +Cc: Pawel Kot, Marcelo Tosatti, andre, Linux Kernel Mailing List


On 3 Aug 2002, Alan Cox wrote:

> On Sat, 2002-08-03 at 20:26, Pawel Kot wrote:
> > What helped me was using fixup_device_piix() from -ac in
> > ide_scan_pcidev(). My controler's ID is DEVID_ICH3M.
> > It is used in a different, more generic way in -ac, so I don't post the
> > patch.
> >
> > Alan, Marcelo: is there any chance that this change will be ported from
> > -ac in 2.4.20?
>
> I plan to send Marcelo all the IDE updates. Note btw the checking of the
> return value on pci_enable_device is critical - some old kernels hang on
> boot with crappy bioses through not checking.

Of course it is critical :-).

> What I begin to the think the right answer is, is to relax the IDE fixup
> block in the i386 kernel boot up. Right now we avoid assigning
> unassigned resources for IDE controllers. Clearly we should be doing so.

I think so.
Andre what do you think?

And one more thing in ide-pci.c:ide_setup_pci_device() after explicitly
enabling device's IOs we may need to update dev->resource and we don't
do this (we place chipset in native mode so i.e. on VIA base addresses
are just showing up). How to update them?

Regards
--
Bartlomiej


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 21:58   ` Bartlomiej Zolnierkiewicz
@ 2002-08-03 22:16     ` Bartlomiej Zolnierkiewicz
  2002-08-03 23:38       ` Alan Cox
  0 siblings, 1 reply; 409+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2002-08-03 22:16 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Alan Cox, Pawel Kot, Marcelo Tosatti, andre,
	Linux Kernel Mailing List


On Sat, 3 Aug 2002, Bartlomiej Zolnierkiewicz wrote:

>
> On 3 Aug 2002, Alan Cox wrote:
>
> > On Sat, 2002-08-03 at 20:26, Pawel Kot wrote:
> > > What helped me was using fixup_device_piix() from -ac in
> > > ide_scan_pcidev(). My controler's ID is DEVID_ICH3M.
> > > It is used in a different, more generic way in -ac, so I don't post the
> > > patch.
> > >
> > > Alan, Marcelo: is there any chance that this change will be ported from
> > > -ac in 2.4.20?
> >
> > I plan to send Marcelo all the IDE updates. Note btw the checking of the
> > return value on pci_enable_device is critical - some old kernels hang on
> > boot with crappy bioses through not checking.
>
> Of course it is critical :-).
>
> > What I begin to the think the right answer is, is to relax the IDE fixup
> > block in the i386 kernel boot up. Right now we avoid assigning
> > unassigned resources for IDE controllers. Clearly we should be doing so.
>
> I think so.
> Andre what do you think?

Just rethough it. What if chipset is in compatibility mode?
Like VIA with base addresses set to 0?

(please note I am not a PCI resource menagament expert ;-)

> And one more thing in ide-pci.c:ide_setup_pci_device() after explicitly
> enabling device's IOs we may need to update dev->resource and we don't
> do this (we place chipset in native mode so i.e. on VIA base addresses
> are just showing up). How to update them?
>
> Regards
> --
> Bartlomiej


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 23:38       ` Alan Cox
@ 2002-08-03 22:53         ` Bartlomiej Zolnierkiewicz
  2002-08-04 13:28           ` Henning P. Schmiedehausen
  2002-08-03 23:27         ` Petr Vandrovec
  1 sibling, 1 reply; 409+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2002-08-03 22:53 UTC (permalink / raw)
  To: Alan Cox
  Cc: Pawel Kot, Marcelo Tosatti, Andre Hedrick,
	Linux Kernel Mailing List


On 4 Aug 2002, Alan Cox wrote:

> On Sat, 2002-08-03 at 23:16, Bartlomiej Zolnierkiewicz wrote:
> > Just rethough it. What if chipset is in compatibility mode?
> > Like VIA with base addresses set to 0?
>
> If we found a register that was marked as unassigned with a size then we
> would map it to a PCI address. That would go for BAR0-3 on any PCI IDE
> device attached to the south bridge.
>
> What problems does that cause for the VIA stuff ?

In compatibility mode IDE chipsets have IO at legacy ISA ports and
PCI_BASE_ADDRESS0-3 are set to them or to zero (at least on VIA).
And they can't be programmed to any other ports (unless native mode).

I am just asking if it can cause some problems.

--
Bartlomiej


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 23:38       ` Alan Cox
  2002-08-03 22:53         ` Bartlomiej Zolnierkiewicz
@ 2002-08-03 23:27         ` Petr Vandrovec
  1 sibling, 0 replies; 409+ messages in thread
From: Petr Vandrovec @ 2002-08-03 23:27 UTC (permalink / raw)
  To: Alan Cox
  Cc: Bartlomiej Zolnierkiewicz, Pawel Kot, Marcelo Tosatti,
	Andre Hedrick, Linux Kernel Mailing List

On Sun, Aug 04, 2002 at 12:38:00AM +0100, Alan Cox wrote:
> On Sat, 2002-08-03 at 23:16, Bartlomiej Zolnierkiewicz wrote:
> > Just rethough it. What if chipset is in compatibility mode?
> > Like VIA with base addresses set to 0?
> 
> If we found a register that was marked as unassigned with a size then we
> would map it to a PCI address. That would go for BAR0-3 on any PCI IDE
> device attached to the south bridge.
> 
> What problems does that cause for the VIA stuff ?

We must read PCI config register 9 (programming interface), and check its value.

If r9 & 0x05 == 0x05, we can program BARs. 

Otherwise if r9 & 0x0A != 0x0A, we must not touch hardware: it supports 
only legacy 0x1F0/0x170 assignment (PCI-IDE spec says that BAR0-BAR3
can be either hardwired to zero, or it can be writeable, but written
value must be ignored).

If r9 & 0x0A == 0x0A, we must write r9 | 0x05 to PCI config register 9,
and then (after verifying that write suceeded... it does not suceed
in VMware, for example...) we must (re)program BARs.

Worst problem is that (some) VIA chips have BAR0-BAR3 writeable,
but are programmed to ignore them by BIOS (as IRQ14/IRQ15 routing is
not available when in native mode). Current kernel code will believe
that device was relocated, but reality will be different, because of device
ignores BAR0-BAR3 value until programming interface is modified.
					Best regards,
						Petr Vandrovec
						vandrove@vc.cvut.cz


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 22:16     ` Bartlomiej Zolnierkiewicz
@ 2002-08-03 23:38       ` Alan Cox
  2002-08-03 22:53         ` Bartlomiej Zolnierkiewicz
  2002-08-03 23:27         ` Petr Vandrovec
  0 siblings, 2 replies; 409+ messages in thread
From: Alan Cox @ 2002-08-03 23:38 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Pawel Kot, Marcelo Tosatti, Andre Hedrick,
	Linux Kernel Mailing List

On Sat, 2002-08-03 at 23:16, Bartlomiej Zolnierkiewicz wrote:
> Just rethough it. What if chipset is in compatibility mode?
> Like VIA with base addresses set to 0?

If we found a register that was marked as unassigned with a size then we
would map it to a PCI address. That would go for BAR0-3 on any PCI IDE
device attached to the south bridge.

What problems does that cause for the VIA stuff ?


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-03 22:53         ` Bartlomiej Zolnierkiewicz
@ 2002-08-04 13:28           ` Henning P. Schmiedehausen
  2002-08-04 15:40             ` Daniela Engert
  0 siblings, 1 reply; 409+ messages in thread
From: Henning P. Schmiedehausen @ 2002-08-04 13:28 UTC (permalink / raw)
  To: linux-kernel

Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> writes:

>On 4 Aug 2002, Alan Cox wrote:

>> On Sat, 2002-08-03 at 23:16, Bartlomiej Zolnierkiewicz wrote:
>> > Just rethough it. What if chipset is in compatibility mode?
>> > Like VIA with base addresses set to 0?
>>
>> If we found a register that was marked as unassigned with a size then we
>> would map it to a PCI address. That would go for BAR0-3 on any PCI IDE
>> device attached to the south bridge.
>>
>> What problems does that cause for the VIA stuff ?

>In compatibility mode IDE chipsets have IO at legacy ISA ports and
>PCI_BASE_ADDRESS0-3 are set to them or to zero (at least on VIA).
>And they can't be programmed to any other ports (unless native mode).

Hi,

this sounds like a problem that I have with the ServerWorks OSB5
chipset. I actually have PCI_BASE_ADDRESS0-3 at 0 and
PCI_BASE_ADDRESS4 = 0x3a0.

Does this hold true here, too? Or is this VIA specific?

	Regards
		Henning


-- 
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen       -- Geschaeftsfuehrer
INTERMETA - Gesellschaft fuer Mehrwertdienste mbH     hps@intermeta.de

Am Schwabachgrund 22  Fon.: 09131 / 50654-0   info@intermeta.de
D-91054 Buckenhof     Fax.: 09131 / 50654-20   

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-04 13:28           ` Henning P. Schmiedehausen
@ 2002-08-04 15:40             ` Daniela Engert
  0 siblings, 0 replies; 409+ messages in thread
From: Daniela Engert @ 2002-08-04 15:40 UTC (permalink / raw)
  To: hps@intermeta.de, linux-kernel@vger.kernel.org

On Sun, 4 Aug 2002 13:28:46 +0000 (UTC), Henning P. Schmiedehausen
wrote:

>Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> writes:
>>On 4 Aug 2002, Alan Cox wrote:
>>> On Sat, 2002-08-03 at 23:16, Bartlomiej Zolnierkiewicz wrote:

>>> > Just rethough it. What if chipset is in compatibility mode?
>>> > Like VIA with base addresses set to 0?
>>>
>>> If we found a register that was marked as unassigned with a size then we
>>> would map it to a PCI address. That would go for BAR0-3 on any PCI IDE
>>> device attached to the south bridge.
>
>>In compatibility mode IDE chipsets have IO at legacy ISA ports and
>>PCI_BASE_ADDRESS0-3 are set to them or to zero (at least on VIA).
>>And they can't be programmed to any other ports (unless native mode).

>this sounds like a problem that I have with the ServerWorks OSB5
>chipset. I actually have PCI_BASE_ADDRESS0-3 at 0 and
>PCI_BASE_ADDRESS4 = 0x3a0.
>
>Does this hold true here, too? Or is this VIA specific?

PCI IDE controller chips in compatibility mode may exhibit the
following BAR0-3 values (sorted by likelihood of occurance):

most likely:  BAR0-3 are all zero
rare       :  BAR0-3 show the legacy IDE port values
very rare  :  BAR0-3 contain garbage

In fact, the best strategy is to *ignore* BAR0-3 in compatibility mode
because they have no meaning then!

Ciao,
  Dani



^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2002-08-05 13:08 Christos Kartsaklis
@ 2002-08-05 14:53 ` Alan Cox
  0 siblings, 0 replies; 409+ messages in thread
From: Alan Cox @ 2002-08-05 14:53 UTC (permalink / raw)
  To: Christos Kartsaklis; +Cc: linux-kernel

Red Hat put out an errata for the 2.4.7-10 kernel a long time ago. It
fixes numerous problems and indirect bugs as a result. Can you try that
first of all


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2003-02-21 13:43 News Admin
@ 2003-02-21 15:01 ` Alan Cox
  0 siblings, 0 replies; 409+ messages in thread
From: Alan Cox @ 2003-02-21 15:01 UTC (permalink / raw)
  To: News Admin; +Cc: Linux Kernel Mailing List

On Fri, 2003-02-21 at 13:43, News Admin wrote:
> $ gcc -v
> Reading specs from /usr/lib/gcc-lib/i386-linux/3.2.3/specs
> Configured with: ../src/configure -v
> --enable-languages=c,c++,java,f77,proto,pascal,objc,ada --prefix=/usr
> --mandir=/usr/share/man --infodir=/usr/share/info
> --with-gxx-include-dir=/usr/include/c++/3.2 --enable-shared
> --with-system-zlib --enable-nls --without-included-gettext
> --enable-__cxa_atexit --enable-clocale=gnu --enable-java-gc=boehm
> --enable-objc-gc i386-linux
> Thread model: posix
> gcc version 3.2.3 20030210 (Debian prerelease)

How about using a released gcc compiler not a snapshot. gcc 3.2.1
and 3.2.2 appear to work fine. According to the FSF there is no
gcc 3.2.3 yet, so it isn't suprising a snapshot would have bugs


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
       [not found] <Pine.GSO.4.58.0401251223440.20527@waterleaf.sonytel.be>
@ 2004-01-25 13:02 ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 409+ messages in thread
From: Benjamin Herrenschmidt @ 2004-01-25 13:02 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Paul Mackerras, Tom Rini, Linux/PPC Development


On Sun, 2004-01-25 at 22:31, Geert Uytterhoeven wrote:
> 	Hi,
>
> This patch converts <asm/hydra.h> to use explicit-sized types.
> It also applies to 2.4.

Don't you want to port the Hydra code to use the macio infrastructure ?

It would probably require defining the LongTrail as a _MACH_Pmac or
hacking enough of pmac_feature to grok it, but that doesn't seem to
bad actually...

Ben.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2004-02-22 17:51 redzic fadil
@ 2004-02-22 20:54 ` Ludootje
  0 siblings, 0 replies; 409+ messages in thread
From: Ludootje @ 2004-02-22 20:54 UTC (permalink / raw)
  To: redzic fadil; +Cc: linux-kernel

On Sun, 2004-02-22 at 17:51, redzic fadil wrote:
> hello
> 
> 
> I hope I don't disturb,
> 
> 
> I have tried to compile the hello.c module under kernel 2.6.3.
> And I'd like to insert the hello.o module in the kernel.
> But this doesn't work with kernel 2.6.3 .
> 
> I have compiled this module with kernel 2.4.* and it is well.


See http://lwn.net/Articles/21817 for porting hello world.
(or http://lwn.net/Articles/driver-porting for the entire article)

Ludootje


^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2004-07-16 16:54 Hermann Gottschalk
@ 2004-07-16 16:59 ` Jesse Stockall
  0 siblings, 0 replies; 409+ messages in thread
From: Jesse Stockall @ 2004-07-16 16:59 UTC (permalink / raw)
  To: Hermann Gottschalk; +Cc: linux-kernel

On Fri, 2004-07-16 at 12:54, Hermann Gottschalk wrote:
> unsubscribe

Please follow the instructions at the bottom of every message.

Jesse

> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2004-12-14 16:49 Andi Kleen
@ 2004-12-15 23:50 ` Alan Cox
  0 siblings, 0 replies; 409+ messages in thread
From: Alan Cox @ 2004-12-15 23:50 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Keir.Fraser, Christian.Limpach, Steven.Hand, Ian.Pratt, akpm,
	Linux Kernel Mailing List, riel

The Xen interface seems to me better described that most of the kernel
interfaces and has more papers written on it. I would rather see
arch/xen and public exposure and use of the platform before considering
major redesigns. The s390 people have proved we can remove/fold arch
directories effectively and after original implementation without
problems.

I'm not convinced by your arguments about arch/xen although I am long
term in favour because I'd like see it easy to build a kernel which can
be used without Xen and can switch into Xen guest mode on Xen loading.

Alan


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
@ 2005-05-19  6:23 ` SACAH
  2005-05-19  6:23 ` Chen, Zhen Y (Zhen)
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: SACAH @ 2005-05-19  6:23 UTC (permalink / raw)
  To: lm-sensors

Giday, I am tring to write a little program is Assembly, that will get my CPU's temperature, I have read a lot of documents about SMBus, and how to access it, the address etc, but I can get my programs to work, I have an Asus A7V, running SMBProbe reveals my chip set being VIA VT82C686A.  I would like to later expand my program to do my motherboard temp too, and fan speed etc, so if you know of any urls that would help me find those things that would also be greatly apprechiated.  I dont understand C at all, and I dont have Linux to be able to play with your source and work it out from that, 


Any help you may have would be greatly apprechiated.

Thanks
?ACAH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20011207/54c6eb50/attachment.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
  2005-05-19  6:23 ` SACAH
@ 2005-05-19  6:23 ` Chen, Zhen Y (Zhen)
  2005-05-19  6:23 ` Gyimesi Attila
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Chen, Zhen Y (Zhen) @ 2005-05-19  6:23 UTC (permalink / raw)
  To: lm-sensors

hi,
I ran the sensor package on my redhat 6.2, IBM xserver systems. 
It has a sensor chip somewhere. But the tool couldn't find a match.

Looks like: 0x30, 0x31, 0x64 are the chips that can't be determined by
the tool. 
0x50, 0x53. 0x57 are eeprom chips. 
 
I don't know for sure if the sensor is on the i2c bus, neither i could
identify the chip name and model.
I wonder if you can help  me out. 
thanks
zhen 

OUTPUT from SENSORS_DETECTY:

[root@definity1 detect]# ./sensors-detect
 This program will help you to determine which I2C/SMBus modules you
need to
 load to use lm_sensors most effectively.
 You need to have done a `make install', issued a `depmod -a' and made
sure
 `/etc/conf.modules' (or `/etc/modules.conf') contains the appropriate
 module path before you can use some functions of this utility. Read
 doc/modules for more information.
 Also, you need to be `root', or at least have access to the /dev/i2c-*
files
 for some things. You can use prog/mkdev/mkdev.sh to create these /dev
files
 if you do not have them already.
 If you have patched your kernel and have some drivers built-in you can
 safely answer NO if asked to load some modules. In this case, things
may
 seem a bit confusing, but they will still work.
 
 We can start with probing for (PCI) I2C or SMBus adapters.
 You do not need any special privileges for this.
 Do you want to probe now? (YES/no): y
Probing for PCI bus adapters...
Sorry, no PCI bus adapters found.
 We will now try to load each adapter module in turn.
 Do you now want to be prompted for non-detectable adapters? (yes/NO): y
Load `i2c-elektor' (say NO if built into your kernel)? (YES/no): y
Module loaded succesfully.
Load `i2c-elv' (say NO if built into your kernel)? (YES/no): y
/lib/modules/2.2.17-14.1s13smp/misc/i2c-elv.o: init_module: Device or
resource busy
/lib/modules/2.2.17-14.1s13smp/misc/i2c-elv.o: insmod
/lib/modules/2.2.17-14.1s13smp/
misc/i2c-elv.o failed
/lib/modules/2.2.17-14.1s13smp/misc/i2c-elv.o: insmod i2c-elv failed
Loading failed ()... skipping.
Load `i2c-philips-par' (say NO if built into your kernel)? (YES/no): y
Module loaded succesfully.
Load `i2c-velleman' (say NO if built into your kernel)? (YES/no): n
 To continue, we need module `i2c-dev' to be loaded.
 If it is built-in into your kernel, you can safely skip this.
i2c-dev is already loaded.
 We are now going to do the adapter probings. Some adapters may hang
halfway
 through; we can't really help that. Also, some chips will be double
detected;
 we choose the one with the highest confidence value in that case.
 If you found that the adapter hung after probing a certain address, you
can
 specify that address to remain unprobed. If you have a PIIX4, that
often
 includes addresses 0x69 and/or 0x6a.
 
Next adapter: SMBus OSB4 adapter at 0440 (Non-I2C SMBus adapter)
Do you want to scan it? (YES/no/selectively): y
Client found at address 0x00
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Client found at address 0x30
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Client found at address 0x31
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Client found at address 0x50
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Probing for `Serial EEPROM (PC-100 DIMM)'... Success!
    (confidence 8, driver `eeprom')
Probing for `DDC monitor'... Failed!
Client found at address 0x53
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Probing for `Serial EEPROM (PC-100 DIMM)'... Success!
    (confidence 8, driver `eeprom')
Client found at address 0x57
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
 Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
Probing for `Serial EEPROM (PC-100 DIMM)'... Success!
    (confidence 1, driver `eeprom')
Client found at address 0x64
Probing for `National Semiconductor LM78'... Failed!
Probing for `National Semiconductor LM78-J'... Failed!
Probing for `National Semiconductor LM79'... Failed!
Probing for `Winbond W83781D'... Failed!
Probing for `Winbond W83782D'... Failed!
Probing for `Winbond W83783S'... Failed!
Probing for `Winbond W83627HF'... Failed!
Probing for `Asus AS99127F'... Failed!
 
Next adapter: PCF8584 ISA adapter (PCF8584 algorithm)
Do you want to scan it? (YES/no/selectively): y
Next adapter: Velleman K8000 (Bit-shift algorithm)
Do you want to scan it? (YES/no/selectively): y
 
Next adapter: PCF8584 ISA adapter (PCF8584 algorithm)
Do you want to scan it? (YES/no/selectively): y
 
Next adapter: Velleman K8000 (Bit-shift algorithm)
Do you want to scan it? (YES/no/selectively): n
 
 Some chips are also accessible through the ISA bus. ISA probes are
 typically a bit more dangerous, as we have to write to I/O ports to do
 this.  Do you want to scan the ISA bus? (YES/no): y
Probing for `National Semiconductor LM78'
  Trying address 0x0290... Failed!
Probing for `National Semiconductor LM78-J'
  Trying address 0x0290... Failed!
Probing for `National Semiconductor LM79'
  Trying address 0x0290... Failed!
Probing for `Winbond W83781D'
  Trying address 0x0290... Failed!
Probing for `Winbond W83782D'
  Trying address 0x0290... Failed!
Probing for `Winbond W83627HF'
  Trying address 0x0290... Failed!
Probing for `Silicon Integrated Systems SIS5595'
  Trying general detect... Failed!
 
 Driver `eeprom' (should be inserted):
  Detects correctly:
  * Bus `SMBus OSB4 adapter at 0440' (Non-I2C SMBus adapter)
    Busdriver `?????', I2C address 0x50
    Chip `Serial EEPROM (PC-100 DIMM)' (confidence: 8)
  * Bus `SMBus OSB4 adapter at 0440' (Non-I2C SMBus adapter)
    Busdriver `?????', I2C address 0x53
    Chip `Serial EEPROM (PC-100 DIMM)' (confidence: 8)
  * Bus `SMBus OSB4 adapter at 0440' (Non-I2C SMBus adapter)
    Busdriver `?????', I2C address 0x57
    Chip `Serial EEPROM (PC-100 DIMM)' (confidence: 1)
 



out put from i2c_detect. i2c dump:

 Error: No i2c-bus specified!
Syntax: i2cdetect I2CBUS
  I2CBUS is an integer
  Installed I2C busses:
    i2c-0       smbus           SMBus OSB4 adapter at 0440
Non-I2C SMBus
 adapter
    i2c-1       i2c             PCF8584 ISA adapter
PCF8584 algor
ithm
    i2c-2       i2c             Velleman K8000
Bit-shift alg
orithm
 
[root@definity1 detect]# ./i2cdetect 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 00 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
30: 30 31 XX XX XX XX XX XX XX XX XX XX XX XX XX XX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
50: 50 XX XX 53 XX XX XX 57 XX XX XX XX XX XX XX XX
60: XX XX XX XX 64 XX XX XX XX XX XX XX XX XX XX XX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
 
[root@definity1 dump]# ./i2cdump 0 0x30
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x30, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: XX ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
20: ff ff ff ff ff XX XX XX XX XX XX XX XX XX XX XX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
50: XX XX XX ff XX ff ff XX XX XX XX XX XX XX XX XX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
90: XX XX XX XX XX XX XX XX XX XX XX XX ff XX XX XX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
f0: XX XX XX XX XX XX ff XX XX XX XX XX XX XX XX XX
 

[root@definity1 dump]# ./i2cdump 0 0x31
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x31, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 00 00 00 00 02 00 01 07 03 00 00 02 00 01 00 01
10: 03 00 02 00 01 00 03 03 00 02 00 01 07 03 03 00
20: 00 00 05 00 05 04 00 05 04 05 00 06 04 00 00 00
30: 01 07 03 00 00 08 08 00 0a 06 00 00 09 09 00 0a
40: 06 00 00 00 00 00 00 06 00 00 06 06 06 06 06 06
50: 00 07 00 01 01 07 00 05 02 00 06 00 06 02 05 02
60: 00 01 00 07 00 05 07 00 01 01 07 00 05 00 00 03
70: 00 03 00 05 03 04 03 00 00 00 05 00 05 01 01 07
80: 05 05 08 08 00 0a 00 00 05 09 09 00 0b 00 00 05
90: 00 00 00 00 00 00 05 05 05 05 05 05 05 05 32 55
a0: 25 55 6a 45 04 d0 23 5c 3f 44 5a 07 80 e0 13 a0
b0: 04 d8 fb 5c 01 ff 01 51 00 f9 00 b3 00 b5 00 03
c0: 00 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
d0: 55 55 55 55 55 55 55 55 55 55 18 02 03 01 0d 80
e0: 00 00 00 00 00 00 00 55 55 55 55 55 55 55 55 55
f0: 55 55 55 55 01 01 00 00 00 00 01 00 55 55 30 55
[root@definity1 dump]#
 
 
[root@definity1 dump]# ./i2cdump 0 0x50
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x50, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 80 08 04 0c 0a 01 48 00 01 75 54 02 80 08 08 01
10: 8f 04 06 01 01 1f 0e a0 60 00 00 14 0f 14 2c 20
20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 df
40: 2c ff ff ff ff ff ff ff 08 39 4c 53 44 54 31 36
50: 37 32 47 2d 31 33 33 45 31 20 20 01 00 01 2c 5b
60: 18 66 ee 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 8f
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[root@definity1 dump]# ./i2cdump 0 0x53
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x53, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 80 08 04 0c 0a 01 48 00 01 75 54 02 80 08 08 01
10: 8f 04 06 01 01 1f 0e a0 60 00 00 14 0f 14 2c 20
20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 df
40: 2c ff ff ff ff ff ff ff 08 39 4c 53 44 54 31 36
50: 37 32 47 2d 31 33 33 45 31 20 20 01 00 01 2c 5b
60: 18 66 e9 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 8f
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[root@definity1 dump]# ./i2cdump 0 0x57
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x57, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 6e d7 00 00 00 00 00 00 00 00 00 00 00 00 34 fa
10: 31 42 36 31 54 37 20 4b 31 30 47 54 53 4c 52 4d
20: 00 00 00 00 32 35 50 33 33 34 37 20 20 20 20 20
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 7f 7f 7f 7f 7f 7f 7f 7f
50: 00 00 42 4f 58 20 53 45 52 49 41 4c 4e 55 4d 42
60: 45 52 00 00 32 35 50 32 31 32 37 20 20 20 20 20
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

 
[root@definity1 dump]# ./i2cdump 0 0x64
Warning: no size specified (using byte-data access)
  WARNING! This program can confuse your I2C bus, cause data loss and
worse!
  I will probe file /dev/i2c-0, address 0x64, mode byte
  You have five seconds to reconsider and press CTRL-C!
 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
10: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
20: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
30: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
40: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
50: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
60: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
70: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
80: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
90: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
a0: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
b0: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
c0: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
d0: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
e0: e0 00 00 00 00 0f 00 00 02 fe 02 01 00 00 00 00
f0: 00 00 40 20 00 02 00 00 00 00 ff ff ff ff 00 00
 
 






 











-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20020219/5d6f8b47/attachment.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
  2005-05-19  6:23 ` SACAH
  2005-05-19  6:23 ` Chen, Zhen Y (Zhen)
@ 2005-05-19  6:23 ` Gyimesi Attila
  2005-05-19  6:23 ` Minesh Khatri
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Gyimesi Attila @ 2005-05-19  6:23 UTC (permalink / raw)
  To: lm-sensors


Hi!

I got this message in every 10 minutes but I don`t know why.
Can you help me?

Jul  9 05:56:15 jam kernel: i2c-ali1535.o: Resetting entire SMB Bus to clear busy condition (08)                                       
Jul  9 05:56:15 jam kernel: i2c-ali1535.o: SMBus reset failed! (0x08) - controller or device on bus is probably hung                   



                                      JiM 
			      My E-MAIL address :
			        jim@ond.vein.hu

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (2 preceding siblings ...)
  2005-05-19  6:23 ` Gyimesi Attila
@ 2005-05-19  6:23 ` Minesh Khatri
  2005-05-19  6:24 ` Bryan Call
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Minesh Khatri @ 2005-05-19  6:23 UTC (permalink / raw)
  To: lm-sensors

Hi,

I ran your program, sensors-detect, on Red Hat 7.3, and now it has screwed up my
computer (IBM Intellistation). Linux will no longer boot. I was wondering if you
had any solutions or reasons as to why this is happening? 

Thanks,
Minesh


__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better
http://health.yahoo.com

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (3 preceding siblings ...)
  2005-05-19  6:23 ` Minesh Khatri
@ 2005-05-19  6:24 ` Bryan Call
  2005-05-19  6:24 ` Kirby Dotson
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Bryan Call @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

I am interested in helping out this project to add support for the Linux 
2.5/2.6 kernel.

I am a software developer/manager at yahoo and have many years of software 
development experience.  I have written system calls and other kernel mods 
years ago and would like to get back into that type of programming.

-Bryan Call

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (4 preceding siblings ...)
  2005-05-19  6:24 ` Bryan Call
@ 2005-05-19  6:24 ` Kirby Dotson
  2005-05-19  6:24 ` Zaffar Khalid
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Kirby Dotson @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

I', getting compile errors.  I've tried what was in
the  documentation.  Any clues on the following.

Kirby

[root@alpha lm_sensors-2.8.1]#
kernel/busses/i2c-nforce2.c:387: warning: implicit
declaration of function `__devexit_p'
> kernel/busses/i2c-nforce2.c:387: initializer element
is not constant
> kernel/busses/i2c-nforce2.c:387: (near
initialization for `nforce2_driver.remove')
> kernel/busses/i2c-nforce2.c:388: initializer element
is not constant
> kernel/busses/i2c-nforce2.c:388: (near
initialization for `nforce2_driver')
bash: syntax error near unexpected token
``nforce2_driver')'
[root@alpha lm_sensors-2.8.1]# make: ***
[kernel/busses/i2c-nforce2.o] Error 1
bash: make:: command not found
[root@alpha lm_sensors-2.8.1]#
[root@alpha lm_sensors-2.8.1]#


__________________________________
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (5 preceding siblings ...)
  2005-05-19  6:24 ` Kirby Dotson
@ 2005-05-19  6:24 ` Zaffar Khalid
  2005-05-19  6:24 ` cst01074
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: Zaffar Khalid @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

Hello there,

I've got a question for you. I have a system running the Redhat 7.3
operating system and i've tried to run lmsensors on it but i get bogus
values when i run sensors. The chip on the motherboard is the Winbond
w83627hf and i'm using the embedded lmsensors rpm package that comes with
the redhat distribution.

Can you tell me if there is a fix for this problem? Are there any updated
rpms available?

Thanks for your help.
Regards
Zaffar
Systems Engineer


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.lm-sensors.org/pipermail/lm-sensors/attachments/20031121/3635266b/attachment.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (6 preceding siblings ...)
  2005-05-19  6:24 ` Zaffar Khalid
@ 2005-05-19  6:24 ` cst01074
  2005-05-19  6:24 ` spreckel
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: cst01074 @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

To whom it may concern,

I am a student at Camosun College in Victoria, B.C.. As a project for a RedHat Linux System Admin
course that I am currently taking, my partner and I were given the task of installing (or trying
to install) "lmsensors". Our instructor had made a previous attempt without success, and was not
really expecting us to succeed, but to gain experience in the process. Our instructor has
"lmsensors" running  on a few of his own (non-IBM) machines successfully. He was aware of the
obstacles that we would encounter as well. Although we would have liked to have proven him wrong,
we too were unsuccessful.We are running an IBM Xseries 305 server, with multiple IBM NetVista Type
6794-11U subservers all running on Redhat 9 platforms. We encountered the following message during
our installation attempt, and were forced to resign our attempt. Unfortunately, we will also have
to make the focus of our oral report on hardware compatibility issues and the effect that they
have on future purchasing decisions. Are you aware of a patch for IBM machines that can be used
with "lmsensors" so that future students may be more successful than we were? If so, we would be
happy to pass this on to our instructor. The Open Source Community has suggested that they would
be willing to write the patches if the necessary API's were made available.Is that a possibility
for the future?

Thanks in advance for any assistance that you may be able to provide.

This is a printout of the fail message that we encountered.

BIOS vendor (ACPI): PTLTD
 System vendor (DMI): IBM
 BIOS version (DMI): 20KT34AUS
 Sorry, we won't let you go on. IBM systems are known to have
 serious problems with lm_sensors, resulting in hardware failures.
 For more information, see README.thinkpad or
 http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/README.thinkpad.
 We used two methods to determine your system's vendor, and they led
 to different results. We'd appreciate to have feedback about such
 systems. Please, take some time and contact the lm_sensors mailing
 list at <sensors@stimpy.netroedge.com>.
 We need the following information:
  * The brand and model of your system
  * The BIOS vendor (ACPI) displayed above
  * The System vendor (DMI) displayed above
 Thanks!



Thanks again,
Brad and Tim


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (7 preceding siblings ...)
  2005-05-19  6:24 ` cst01074
@ 2005-05-19  6:24 ` spreckel
  2005-05-19  6:24 ` jmp
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: spreckel @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

[-- Attachment #1: Type: multipart/signed, Size: 0 bytes --]

[-- Attachment #2: Type: text/plain, Size: 766 bytes --]

 BIOS vendor (ACPI): PTLTD
 System vendor (DMI): IBM
 BIOS version (DMI): IYET59WW (1.20 )
 Sorry, we won't let you go on. IBM systems are known to have
 serious problems with lm_sensors, resulting in hardware failures.
 For more information, see README.thinkpad or
 http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/README.thinkpad.
 We used two methods to determine your system's vendor, and they led
 to different results. We'd appreciate to have feedback about such
 systems. Please, take some time and contact the lm_sensors mailing
 list at <sensors@stimpy.netroedge.com>.
 We need the following information:
  * The brand and model of your system
  * The BIOS vendor (ACPI) displayed above
  * The System vendor (DMI) displayed above
 Thanks!


[-- Attachment #3: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (8 preceding siblings ...)
  2005-05-19  6:24 ` spreckel
@ 2005-05-19  6:24 ` jmp
  2005-05-19  6:25 ` no subject firase kaled
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: jmp @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors





-The dmesg or syslog output if applicable:
______________________________________________

i2c-dev.o: i2c /dev entries driver module
i2c-core.o: driver i2c-dev dummy driver registered.
i2c-dev.o: Registered 'SMBus Via Pro adapter at 0400' as minor 0
i2c-algo-pcf.o: i2c pcf8584 algorithm module
i2c-elektor.o: i2c pcf8584-isa adapter module
i2c-elektor.o: requested I/O region (0x330:2) is in use.
i2c-algo-bit.o: i2c bit algorithm module
i2c-elv.o: i2c ELV parallel port adapter module
i2c-dev.o: Registered 'ELV Parallel port adaptor' as minor 1
i2c-core.o: adapter ELV Parallel port adaptor registered as adapter 1.
i2c-elv.o: found device at 0x378.
i2c-algo-pcf.o: i2c pcf8584 algorithm module
i2c-elektor.o: i2c pcf8584-isa adapter module
i2c-elektor.o: requested I/O region (0x330:2) is in use.
i2c-algo-pcf.o: i2c pcf8584 algorithm module
i2c-elektor.o: i2c pcf8584-isa adapter module
i2c-elektor.o: requested I/O region (0x330:2) is in use.
i2c-philips-par.o: i2c Philips parallel port adapter module
i2c-velleman.o: i2c Velleman K8000 adapter module
i2c-velleman.o: Port 0x378 already in use.
____________________________


  * The output of (as root) prog/detect/sensors-detect
______________________________________

[root@flaptop root]# sensors-detect

This program will help you determine which I2C/SMBus modules you need to
load to use lm_sensors most effectively. You need to have i2c and
lm_sensors installed before running this program.
Also, you need to be `root', or at least have access to the /dev/i2c-*
files, for most things.
If you have patched your kernel and have some drivers built-in, you can
safely answer NO if asked to load some modules. In this case, things may
seem a bit confusing, but they will still work.

 BIOS vendor (ACPI): AMI
 System vendor (DMI): FUJITSU SIEMENS
 BIOS version (DMI): 0.28
 We can start with probing for (PCI) I2C or SMBus adapters.
 You do not need any special privileges for this.
 Do you want to probe now? (YES/no): y
Probing for PCI bus adapters...
Use driver `i2c-viapro' for device 00:11.0: VIA Technologies
VT8233A/8235 South Bridge
Probe succesfully concluded.

 We will now try to load each adapter module in turn.
Module `i2c-viapro' already loaded.
 Do you now want to be prompted for non-detectable adapters? (yes/NO): y
Load `i2c-elektor' (say NO if built into your kernel)? (YES/no): y
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-elektor.o:
init_module: No such device
Hint: insmod errors can be caused by incorrect module parameters,
including invalid IO or IRQ parameters.
      You may find more information in syslog or the output from dmesg
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-elektor.o:
insmod
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-elektor.o
failed
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-elektor.o:
insmod i2c-elektor failed
Loading failed... skipping.
Load `i2c-elv' (say NO if built into your kernel)? (YES/no): y
Module loaded succesfully.
Load `i2c-philips-par' (say NO if built into your kernel)? (YES/no): y
Module loaded succesfully.
Load `i2c-velleman' (say NO if built into your kernel)? (YES/no): y
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-velleman.o:
init_module: No such device
Hint: insmod errors can be caused by incorrect module parameters,
including invalid IO or IRQ parameters.
      You may find more information in syslog or the output from dmesg
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-velleman.o:
insmod
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-velleman.o
failed
/lib/modules/2.4.22-1.2149.nptl/unsupported/drivers/i2c/i2c-velleman.o:
insmod i2c-velleman failed
Loading failed... skipping.
 To continue, we need module `i2c-dev' to be loaded.
 If it is built-in into your kernel, you can safely skip this.
i2c-dev is already loaded.

 We are now going to do the adapter probings. Some adapters may hang
halfway
 through; we can't really help that. Also, some chips will be double
detected;
 we choose the one with the highest confidence value in that case.
 If you found that the adapter hung after probing a certain address, you
can
 specify that address to remain unprobed. That often
 includes address 0x69 (clock chip).

Next adapter: SMBus Via Pro adapter at 0400 (Non-I2C SMBus adapter)
Do you want to scan it? (YES/no/selectively): y
Client at address 0x51 can not be probed - unload all client drivers
first!
Client found at address 0x69

Next adapter: ELV Parallel port adaptor (Bit-shift algorithm)
Do you want to scan it? (YES/no/selectively): y
^X^X^X^X

[root@flaptop root]#

_______________________________

  * The output of lsmodIf a PCI chip problem: 
      * The output of lspci -n
  * If an I2C sensor chip problem: 
      * The output of (as root) prog/detect/i2cdetect X where X = the
        bus number (run i2cdetect with no arguments to list the busses)
        (please send this only if it's not all XX)
      * The output of (as root) prog/dump/i2cdump X 0xXX where XX = the
        address of each chip you see in the output of i2cdetect. (run
        once for each chip) (please send this only if it's not all ff)
  * If an ISA sensor chip problem: 
      * The output of (as root) prog/dump/isadump 0x295 0x296 (only if
        it's not all XX)
  * Part numbers of chips on your motherboard you think are the sensor
    chips (look at your motherboard)
  * Motherboard type
  * Sensors version
  * Kernel version

^ permalink raw reply	[flat|nested] 409+ messages in thread

* no subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (9 preceding siblings ...)
  2005-05-19  6:24 ` jmp
@ 2005-05-19  6:25 ` firase kaled
  2005-05-19  6:25 ` No subject andreas
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 409+ messages in thread
From: firase kaled @ 2005-05-19  6:25 UTC (permalink / raw)
  To: lm-sensors

hi i have asus motherboard (p4s133-vm)  and intel (  D845GVSR)  I want to know if
chip driver and bus driver supported or not
thanks

_________________________________________________
See cool party pictures from clubs and restaurants in Jordan, Lebanon, and Dubai. GO to Shuftek Parties now
http://www.shuftak.com

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (10 preceding siblings ...)
  2005-05-19  6:25 ` no subject firase kaled
@ 2005-05-19  6:25 ` andreas
  2005-05-19  6:25 ` Rudolf Marek
  2005-05-19  6:25 ` Tomáš Thiemel
  13 siblings, 0 replies; 409+ messages in thread
From: andreas @ 2005-05-19  6:25 UTC (permalink / raw)
  To: lm-sensors

Hello!

I'm trying to use lm-sensors to drive external equip. for a
meas/control-server for estates. My idea is to use the parallel-port to
hook up some i2c-chips for input/output. If I have understood the docs.
right, my simplest way of doing that will be through the pport driver (no
hardware required, or?). I currently use SuSE 9.2 and the included
lm-sensor package. Maybe I am lost, but how do I get the pport driver? I
have searched everywhere for the driver and info. on how to do it... but
alas. Please give me a hint on how to do, or where to find info. on this
subject.

Thank you in advance.

/Andreas

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (11 preceding siblings ...)
  2005-05-19  6:25 ` No subject andreas
@ 2005-05-19  6:25 ` Rudolf Marek
  2005-05-19  6:25 ` Tomáš Thiemel
  13 siblings, 0 replies; 409+ messages in thread
From: Rudolf Marek @ 2005-05-19  6:25 UTC (permalink / raw)
  To: lm-sensors

Hello,

> I can understand your feelings and complaint absolutely, I'm sorry for
> the trouble and obstacles brought you. I will discuss with my managers
> about it and express your meaning, I think we may improve it in our
> future cooperation.
> Thank you!

Thank you too for good coorporation.

I created some paper for your "responsible manager" staff.
Please forward it to them.

Needs of opensource software development model
on fields of system monitoring
-----------------------------------------------

Most of motherboard manufacturers do not support the hardware monitoring
capabilities of their products in free operating systems (or simply
other than Windows). Thus, open projects were created to build
support of the hardware monitoring chips "on their own".

On the Linux platform project lm-sensors created unified infrastructure and
framework to support different hardware monitoring chips and busses. In mean
time new chips or busses support is handled by members of lm-sensors project.
They are working for free, or sometimes someone supports their work by
donating the hardware, in many cases not the chip makers but frustrated
third parties that are willing to support this project. Cooperation with
manufactures was limited to evaluation board donations or datasheet
support.

We are glad that Winbond decided to work on support of new chips with us,
directly supporting our project with new driver. However to enhance our
future cooperation it is essential to understand specific needs of
open source development.

* Free access to documentation
Our source code is not proprietary, under license conditions anyone can fix
or modify the source code. Chip driver maintenance implies access to chip
documentation. Without that future maintenance of driver is not possible.

* Free access to SMBus host documentation
Our drivers are build upon transport layer provided by other drivers for
SMBus (System Management Bus). It is essential that documentation to this SMBus
host chip is also accessible. We do not need whole southbridge documentation
we just need to know the way how to speak with SMBUS host. Please try to
convince some chipset makers about this, specially NVIDIA, SiS and ALI. Most
of registers is done same way in all chipset following ACPI standart, but
it is essential to know what is done differently.

* Support from motherboard manufacturers
This is very crucial and anticipatory point. There is no cooperation these
days. When motherboard manufacturers follows recommended values of resistors
nets, conversion formulas can be gained from datasheet. End users are happy
that our project is supporting their workstations or company servers instead
of "no support" from motherboard manufacturer. But from time to time
motherboard maker decides to use other components resulting in unknown
conversion formulas. Motherboard manufacturers do not want to disclose
information about the formulas or simply do not respond. This is very
strange behavior, we created our project to support different kind of
hardware and indirectly we are supporting motherboard manufacturers products
by our work. We can't understand that this simple thing is not understood.

* Additional obstacles set by motherboard manufactures
Some created proprietary monitoring interfaces or their own ASIC and they
do not want to disclose documentation to this chips. Some are playing hide
and seek.

Infamous examples:

Abit created their uGuru (in fact programmed Winbond IC), they do not want to
disclose information even to "closed source" companies. Bad luck, we can
only tell to growing Linux userbase - avoid them

ASUS created their own proprietary ASIC chips, however their programming
interface is very very close to Winbond so our driver was developed on
"guesswork". We do not support new chips with no documentation today.
Unfortunately we can't drop support for already supported ones even if
it's a pain.

ASUS is even more creative, they started to hide SMBUS host, later they
start to hide "well known" monitoring chips, result is that we cannot
help much with this to end users. Complaints to ASUS do not work.

Summary
-------
Please try to explain the motherboard companies that they have unique
opportunity to have support of their monitoring chips in Linux with no
additional cost to them, when they will communicate with us and provide
documentation that is essential to support their motherboard.

Please try to explain to chipset makers that we really need parts of
documentation of their southbridge to be able to implement SMBUS host
driver. We do not need full datasheet only small part of it.

When it is not possible to disclose the chip documentation to public we
would like to have a possibility to members of our project to have
shared access to the documentation.

Thank you,

Lm-sensors team.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
                   ` (12 preceding siblings ...)
  2005-05-19  6:25 ` Rudolf Marek
@ 2005-05-19  6:25 ` Tomáš Thiemel
  13 siblings, 0 replies; 409+ messages in thread
From: Tomáš Thiemel @ 2005-05-19  6:25 UTC (permalink / raw)
  To: lm-sensors

Hi. 
I have this problem:
==
i2c-piix4.o: IBM Laptop detected; this module may corrupt your serial
eeprom! Refusing to load module!
==

And I have read this message:
####
http://archives.andrew.net.au/lm-sensors/msg01833.html
####

Is my PC on your "whitelist", please?


Thanks a lot

Tomas Thiemel
ICQ #170438916
http://www.wifizabreh.net

PS: What means "serial eeprom" - is it "BIOS chip"?

------------------------------
See information listed below:


***lspci -v ***
..
00:02.3 Bridge: Intel Corp. 82371AB/EB/MB PIIX4 ACPI (rev 02)
        Flags: medium devsel, IRQ 9
..

***lspci -n***
00:00.0 Class 0600: 8086:7190 (rev 03)
00:01.0 Class 0604: 8086:7191 (rev 03)
00:02.0 Class 0601: 8086:7110 (rev 02)
00:02.1 Class 0101: 8086:7111 (rev 01)
00:02.2 Class 0c03: 8086:7112 (rev 01)
00:02.3 Class 0680: 8086:7113 (rev 02)
00:03.0 Class 0200: 8086:1229 (rev 05)
00:12.0 Class 0280: 1260:3873 (rev 01)
00:14.0 Class 0280: 1260:3873 (rev 01)
01:01.0 Class 0300: 5333:8904 (rev 01)

***cat /var/log/dmesg***
Linux version 2.4.29 (root@wifizabreh2) (gcc version 3.2.2 20030222 (Red
Hat Linux 3.2.2-5)) #12 22:57:14 CEST 07-04-2005
127MB LOWMEM available.
..
IBM machine detected. Enabling interrupts during APM calls.
Kernel command line: ro root=/dev/hda1
No local APIC present or hardware disabled
Initializing CPU#0
Detected 398.272 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 794.62 BogoMIPS
Memory: 126864k/131060k available (1508k kernel code, 3808k reserved,
541k data, 100k init, 0k highmem)
..
CPU: L1 I cache: 16K, L1 D cache: 16K
CPU: L2 cache: 512K
Intel machine check architecture supported.
Intel machine check reporting enabled on CPU#0.
CPU:     After generic, caps: 0183f9ff 00000000 00000000 00000000
CPU:             Common caps: 0183f9ff 00000000 00000000 00000000
CPU: Intel Pentium II (Deschutes) stepping 02
Enabling fast FPU save and restore... done.
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
mtrr: v1.40 (20010327) Richard Gooch (rgooch@atnf.csiro.au)
mtrr: detected mtrr type: Intel
PCI: PCI BIOS revision 2.10 entry at 0xfd85c, last bus=1
PCI: Using configuration type 1
PCI: Probing PCI hardware
PCI: Probing PCI hardware (bus 00)
PCI: Using IRQ router PIIX/ICH [8086/7110] at 00:02.0
Limiting direct PCI/PCI transfers.
isapnp: Scanning for PnP cards...
isapnp: Card 'Crystal Audio'
isapnp: 1 Plug & Play card detected total
Linux NET4.0 for Linux 2.4
..
Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4
ide: Assuming 33MHz system bus speed for PIO modes; override with
idebus=xx
PIIX4: IDE controller at PCI slot 00:02.1
PIIX4: chipset revision 1
PIIX4: not 100% native mode: will probe irqs later
    ide0: BM-DMA at 0xfff0-0xfff7, BIOS settings: hda:DMA, hdb:pio
hda: Maxtor 90644D3, ATA DISK drive
blk: queue c0346500, I/O limit 4095Mb (mask 0xffffffff)
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
..


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

gcc-4.x.x
Latest stable GNU config usable for armeb is: binutils-2.16.1 +
gcc-3.4.6
I am wondering if anybody worked on the build of armeb gnu toolchain
with gcc-4.x.x?

gcc-4.x.x provides new interesting cpu types: arm966, arm1176, ...etc

Many thanks for your answers.

Regards - Luc

-----Original Message-----
From: buildroot-bounces@uclibc.org [mailto:buildroot-bounces at uclibc.org]
On Behalf Of Tor Krill
Sent: vendredi 27 octobre 2006 08:07
To: Philippe Ney
Cc: buildroot at uclibc.org
Subject: Re: [Buildroot] Error building arm toolchain: undefined
referenceto `raise'

Quoting Philippe Ney <philippe.ney@pardes.ws>:

> > Hi,
> >
> > I'm trying to build an up to date toolchain for our arm920t board,
> at91rm9200.
> > However compilation fails with a:
> [...]
> >
>
/home/tor/tmp/buildroot/toolchain_build_arm/gcc-4.1.1/gcc/config/arm/lib
1funcs.asm:1000:
> > undefined reference to `raise'
> [...]
> > Am i missing something here?
>
> Have a look at the gumstix buildroot (www.gumstix.org) for a patch=20
> called uClibc-gcc-41-raise-error.patch, I think this will do the
trick.

Thanks Philippe, this solved the compilation error.

/Tor
_______________________________________________
buildroot mailing list
buildroot at uclibc.org
http://busybox.net/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

target types), but the usual reponse is 'get the latest version' which seems a
bit of
a cop-out, plus I am currently required to use 3.4.3 so this does not apply.

a) any ideas to defeat this problem (not involving 3.4.x, x>3 !)
b) if it's frequent, how come it's not been resolved once & for all

Thanks,
MikeW

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

ccache is a fast compiler cache. It is used as a front end to your compiler to safely cache compilation output. When the same code is compiled again the cached output is used giving a significant speedup (typically 5x).


Is this 5x speedup overstated, or why do you have no need for it?

-------- Original-Nachricht --------
Datum: Fri, 24 Nov 2006 15:10:47 +0100
Von: Bernhard Fischer <rep.nop@aon.at>
An: "Matthias G?lck" <Real.Magic@gmx.de>
Betreff: Re: [Buildroot] problem with absolute paths to tools in ccache

> On Fri, Nov 24, 2006 at 03:06:43PM +0100, "Matthias G?lck" wrote:
> >Thanks for your quick response.
> 
> Well, it was not really helpful, i think.
> 
> >Could you please tell me, why you do not use ccache?
> 
> I simply have no need for it.

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal f?r Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

ccache is a fast compiler cache. It is used as a front end to your compiler to safely cache compilation output. When the same code is compiled again the cached output is used giving a significant speedup (typically 5x).


Is this 5x speedup overstated, or why do you have no need for it?

-------- Original-Nachricht --------
Datum: Fri, 24 Nov 2006 15:10:47 +0100
Von: Bernhard Fischer <rep.nop@aon.at>
An: "Matthias G?lck" <Real.Magic@gmx.de>
Betreff: Re: [Buildroot] problem with absolute paths to tools in ccache

> On Fri, Nov 24, 2006 at 03:06:43PM +0100, "Matthias G?lck" wrote:
> >Thanks for your quick response.
> 
> Well, it was not really helpful, i think.
> 
> >Could you please tell me, why you do not use ccache?
> 
> I simply have no need for it.

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal f?r Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal f?r Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

ccache is a fast compiler cache. It is used as a front end to your compiler to safely cache compilation output. When the same code is compiled again the cached output is used giving a significant speedup (typically 5x).


Is this 5x speedup overstated, or why do you have no need for it?
-- 
"Ein Herz f?r Kinder" - Ihre Spende hilft! Aktion: www.deutschlandsegelt.de
Unser Dankesch?n: Ihr Name auf dem Segel der 1. deutschen America's Cup-Yacht!

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

ccache is a fast compiler cache. It is used as a front end to your compiler to safely cache compilation output. 
When the same code is compiled again the cached output is used giving a significant speedup (typically 5x).


Is this 5x speedup overstated, or why do you have no need for it?

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal f?r Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2006-08-17  1:58 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2006-08-17  1:58 UTC (permalink / raw)
  To: buildroot

>>
This seems to be due to an incompatibility between:
1) toolchain.../gcc-x.x.x/config/arm/linux-elf.h
2) toolchain.../binutils-x.x.x/ld/earmelf_linux_eabi.c

In 1) there is a setting TARGET_LINKER_EMULATION "armelf_linux"
In 2) there is a string (part of a struct initialiser) "armelf_linux_eabi"

so unless I can find matching strings in a version of gcc and ld,
buildroot will never be able to build a toolchain.

But 2) says the file is generated by a shell script, so maybe it's
that script which is to blame !
Or maybe I could just hack 1) to have the correct string.
<<

Don't know enough about how this works to fix the discrepancy ...
is there a missing setting (or patch) which should tell
gcc/config/arm/linux-elf.h to append 'eabi' onto the end
of its 'armelf-linux' string ?

Regards,
MikeW

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2006-10-09 23:13 (no subject) albox
@ 2006-10-09 23:31 ` Tobin Davis
  0 siblings, 0 replies; 409+ messages in thread
From: Tobin Davis @ 2006-10-09 23:31 UTC (permalink / raw)
  To: albox; +Cc: alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 11989 bytes --]

Ok, here is a slightly different approach.  If this one works, then
there is an undocumented register in the 883 that is being used (well,
at least it's listed as vendor defined).

I also corrected the subdevice ID.

Tobin

On Tue, 2006-10-10 at 01:13 +0200, albox@free.fr wrote:

> 
> It doesn't work for me either (at least, I can load the driver after using the
> patch from Takashi).
> 
> Here are some details :
> 
> lspci -nv says:
> 0000:00:1b.0 0403: 8086:27d8 (rev 02)
>         Subsystem: 161f:2054
>         Flags: bus master, fast devsel, latency 0, IRQ 82
>         Memory at d5300000 (64-bit, non-prefetchable) [size=16K]
>         Capabilities: [50] Power Management version 2
>         Capabilities: [60] Message Signalled Interrupts: 64bit+ Queue=0/0
> Enable+
>         Capabilities: [70] #10 [0091]
> 
> $ dmesg | grep ALSA
> [17179588.696000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:680:
> codec_mask = 0x3
> [17179588.876000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/hda_codec.c:1741:
> hda_codec: model 'medion' is selected
> [17179589.604000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/../../alsa-kernel/pci/hda/patch_si3054.c:245:
> si3054: cannot initialize. EXT MID = 0000
> [17179589.612000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/../../alsa-kernel/pci/hda/patch_si3054.c:257:
> Link Frame Detect(FDT) is not ready (line status: 0000)
> [17179635.900000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1142:
> azx_pcm_prepare: bufsize=0x10000, fragsize=0x1000, format=0x11
> [17179635.900000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/hda_codec.c:630:
> hda_codec_setup_stream: NID=0x2, stream=0x5, channel=0, format=0x11
> [17179635.908000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/hda_codec.c:630:
> hda_codec_setup_stream: NID=0x4, stream=0x5, channel=0, format=0x11
> [17179635.916000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/hda_codec.c:630:
> hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x11
> [17179635.924000] ALSA
> /home/albuntu/install/realtek-linux-audiopack-4.05b/alsa-driver-1.0.13/pci/hda/hda_codec.c:630:
> hda_codec_setup_stream: NID=0x5, stream=0x5, channel=0, format=0x11
> 
> $ cat /proc/asound/card0/codec#0
> Codec: Realtek ALC883
> Address: 0
> Vendor Id: 0x10ec0883
> Subsystem Id: 0x161fd82b
> Revision Id: 0x100002
> Default PCM: rates 0x560, bits 0x0e, types 0x1
> Default Amp-In caps: N/A
> Default Amp-Out caps: N/A
> Node 0x02 [Audio Output] wcaps 0x11: Stereo
>   PCM: rates 0x560, bits 0x0e, types 0x1
> Node 0x03 [Audio Output] wcaps 0x11: Stereo
>   PCM: rates 0x560, bits 0x0e, types 0x1
> Node 0x04 [Audio Output] wcaps 0x11: Stereo
>   PCM: rates 0x560, bits 0x0e, types 0x1
> Node 0x05 [Audio Output] wcaps 0x11: Stereo
>   PCM: rates 0x560, bits 0x0e, types 0x1
> Node 0x06 [Audio Output] wcaps 0x211: Stereo Digital
>   PCM: rates 0x560, bits 0x1e, types 0x1
> Node 0x07 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In
>   Amp-In caps: ofs=0x08, nsteps=0x1f, stepsize=0x05, mute=1
>   Amp-In vals:  [0x80 0x80]
>   PCM: rates 0x160, bits 0x06, types 0x1
>   Connection: 1
>      0x23
> Node 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In
>   Amp-In caps: ofs=0x08, nsteps=0x1f, stepsize=0x05, mute=1
>   Amp-In vals:  [0x80 0x80]
>   PCM: rates 0x160, bits 0x06, types 0x1
>   Connection: 1
>      0x22
> Node 0x0a [Audio Input] wcaps 0x100391: Stereo Digital
>   PCM: rates 0x560, bits 0x1e, types 0x1
>   Connection: 1
>      0x1f
> Node 0x0b [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
>   Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
>   Amp-In vals:  [0x00 0x00] [0x1f 0x1f] [0x00 0x00] [0x00 0x00] [0x00 0x00]
> [0x00 0x00] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
>   Connection: 10
>      0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x14 0x15 0x16 0x17
> Node 0x0c [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x1f, nsteps=0x1f, stepsize=0x05, mute=0
>   Amp-Out vals:  [0x1f 0x1f]
>   Connection: 2
>      0x02 0x0b
> Node 0x0d [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x1f, nsteps=0x1f, stepsize=0x05, mute=0
>   Amp-Out vals:  [0x06 0x06]
>   Connection: 2
>      0x03 0x0b
> Node 0x0e [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x1f, nsteps=0x1f, stepsize=0x05, mute=0
>   Amp-Out vals:  [0x0b 0x07]
>   Connection: 2
>      0x04 0x0b
> Node 0x0f [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x1f, nsteps=0x1f, stepsize=0x05, mute=0
>   Amp-Out vals:  [0x06 0x06]
>   Connection: 2
>      0x05 0x0b
> Node 0x10 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x11 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x12 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x13 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x14 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Pincap 0x083e: IN OUT HP Detect
>   Pin Default 0x01011110: [Jack] Line Out at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x40: OUT
>   Connection: 5
>      0x0c* 0x0d 0x0e 0x0f 0x26
> Node 0x15 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Pincap 0x083e: IN OUT HP Detect
>   Pin Default 0x01011112: [Jack] Line Out at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x40: OUT
>   Connection: 5
>      0x0c 0x0d* 0x0e 0x0f 0x26
> Node 0x16 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Pincap 0x083e: IN OUT HP Detect
>   Pin Default 0x01011111: [Jack] Line Out at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x40: OUT
>   Connection: 5
>      0x0c 0x0d 0x0e* 0x0f 0x26
> Node 0x17 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Pincap 0x083e: IN OUT HP Detect
>   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x40: OUT
>   Connection: 5
>      0x0c 0x0d 0x0e 0x0f* 0x26
> Node 0x18 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x80 0x80]
>   Pincap 0x08173e: IN OUT HP Detect
>   Pin Default 0x02a11c3f: [Jack] Mic at Ext Front
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x24: IN
>   Connection: 5
>      0x0c* 0x0d 0x0e 0x0f 0x26
> Node 0x19 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x80 0x80]
>   Pincap 0x08173e: IN OUT HP Detect
>   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x24: IN
>   Connection: 5
>      0x0c* 0x0d 0x0e 0x0f 0x26
> Node 0x1a [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x80 0x80]
>   Pincap 0x08173e: IN OUT HP Detect
>   Pin Default 0x99830130: [Fixed] Line In at Int ATAPI
>     Conn = ATAPI, Color = Unknown
>   Pin-ctls: 0x20: IN
>   Connection: 5
>      0x0c* 0x0d 0x0e 0x0f 0x26
> Node 0x1b [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Pincap 0x08173e: IN OUT HP Detect
>   Pin Default 0x0221111f: [Jack] HP Out at Ext Front
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0xc0: OUT HP
>   Connection: 5
>      0x0c* 0x0d 0x0e 0x0f 0x26
> Node 0x1c [Pin Complex] wcaps 0x400001: Stereo
>   Pincap 0x0820: IN
>   Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
>     Conn = 1/8, Color = Black
>   Pin-ctls: 0x00:
> Node 0x1d [Pin Complex] wcaps 0x400000: Mono
>   Pincap 0x0820: IN
>   Pin Default 0x99830131: [Fixed] Line In at Int ATAPI
>     Conn = ATAPI, Color = Unknown
>   Pin-ctls: 0x00:
> Node 0x1e [Pin Complex] wcaps 0x400300: Mono Digital
>   Pincap 0x0810: OUT
>   Pin Default 0x01451120: [Jack] SPDIF Out at Ext Rear
>     Conn = Optical, Color = Black
>   Pin-ctls: 0x00:
>   Connection: 1
>      0x06
> Node 0x1f [Pin Complex] wcaps 0x400200: Mono Digital
>   Pincap 0x0820: IN
>   Pin Default 0x01c46160: [Jack] SPDIF In at Ext Rear
>     Conn = RCA, Color = Orange
>   Pin-ctls: 0x00:
> Node 0x20 [Vendor Defined Widget] wcaps 0xf00040: Mono
> Node 0x21 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x22 [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x80 0x80] [0x00 0x00]
> [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
>   Amp-Out caps: N/A
>   Amp-Out vals:  [0x00 0x00]
>   Connection: 11
>      0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x14 0x15 0x16 0x17 0x0b
> Node 0x23 [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
> [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
>   Amp-Out caps: N/A
>   Amp-Out vals:  [0x00 0x00]
>   Connection: 11
>      0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x14 0x15 0x16 0x17 0x0b
> Node 0x24 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x25 [Audio Output] wcaps 0x11: Stereo
>   PCM: rates 0x560, bits 0x0e, types 0x1
> Node 0x26 [Audio Mixer] wcaps 0x20010f: Stereo Amp-In Amp-Out
>   Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
>   Amp-In vals:  [0x00 0x00] [0x80 0x80]
>   Amp-Out caps: ofs=0x1f, nsteps=0x1f, stepsize=0x05, mute=0
>   Amp-Out vals:  [0x00 0x00]
>   Connection: 2
>      0x25 0x0b
> 
> 
> I also tried speaker-test but nothing happened. I'll now try the tarball that
> Remy posted last weekend and I'll let you know if it works...
> 
> Cheers,
> AL

-- 
Tobin Davis <tdavis@dsl-only.net>

[-- Attachment #1.2: Type: text/html, Size: 19325 bytes --]

[-- Attachment #2: medion-test.patch --]
[-- Type: text/x-patch, Size: 1182 bytes --]

--- alsa-driver/alsa-kernel/pci/hda/patch_realtek.c.orig	2006-10-08 10:58:28.000000000 -0700
+++ alsa-driver/alsa-kernel/pci/hda/patch_realtek.c	2006-10-09 10:50:03.000000000 -0700
@@ -112,6 +112,7 @@
 	ALC883_6ST_DIG,
 	ALC888_DEMO_BOARD,
 	ALC883_ACER,
+	ALC883_MEDION,
 	ALC883_AUTO,
 	ALC883_MODEL_LAST,
 };
@@ -5080,6 +5081,8 @@
 	  .config = ALC883_ACER },
 	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
 	  .config = ALC883_ACER },
+	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x2054,
+	  .modelname = "medion", .config = ALC883_MEDION }
 	{ .modelname = "auto", .config = ALC883_AUTO },
 	{}
 };
@@ -5167,6 +5170,20 @@
 		.channel_mode = alc883_3ST_2ch_modes,
 		.input_mux = &alc883_capture_source,
 	},
+	[ALC883_MEDION] = {
+		.mixers = { alc883_base_mixer,
+			    alc883_chmode_mixer },
+		.init_verbs = { alc882_init_verbs,
+				alc882_eapd_verbs },
+		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
+		.dac_nids = alc883_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+		.adc_nids = alc883_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
+		.channel_mode = alc883_sixstack_modes,
+		.input_mux = &alc883_capture_source,
+	}
+
 };
 
 

[-- Attachment #3: Type: text/plain, Size: 348 bytes --]

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: No Subject
  2007-02-01  7:54 kou.ishizaki
@ 2007-02-04  4:37 ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 409+ messages in thread
From: Benjamin Herrenschmidt @ 2007-02-04  4:37 UTC (permalink / raw)
  To: kou.ishizaki; +Cc: netdev, linuxppc-dev


> We need to use different auto-neg initial settings between
> for 10/100Mbps ethernet switches and for Gbps ethernet switches.

That is strange ! What PHY chip are you using ? Are you sure it's not
just you not properly configuring the PHY ? Is the datasheet for the PHY
available somewhere ?

> Driver don't know which type of network switch is connected to
> network card, so we try both settings alternately in auto negtiation
> sequences by using a variable "is1000".

sungem has an autoneg sequence that falls back to forced speeds but it's
not useful on any modern setup. Your PHY should be perfectly capable to
autoneg on both 1000bT and 10/100bT...

> Furthermore, we have a problem that poll_link() may succeed even when
> the auto-neg initial setting is for different network switch type,
> and the network card does not work on this case. We retry auto-neg
> with the another initial setting on this case.

Ugh ? What is that initial setting bit exactly ? If the link is up, it
should work.

> >- spider_net_write_reg(card, SPIDER_NET_GMACST,
> >-        spider_net_read_reg(card, SPIDER_NET_GMACST));
> >- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
> 
> These codes are enabling LINK status interrupt which is disabled
> at the beginning of auto-neg.
> Without this operation, auto negotiation works only when a connection
> detected for the first time, and auto negotiation will not work 
> when an ethernet cable is unpluged or pluged.

Most drivers poll the link rather than use an interrupt as those are
often unreliable.

> (3)
> >- mii_phy_probe(phy, phy->mii_id);
> It seems that PHY reset is necessary before auto negotiation,
> after a link once went down.

It shouldn't be... again, what PHY are you using ?

> We can't call directly reset routine from driver, so we call
> mii_phy_probe().

If you really need to reset it, then change sungem_phy.c to export the
reset function. But I'm surprised you need that. Another option is to
reset the PHY in your PHY's setup_aneg() function.

> We are still developping the patch as we noted, and we are considering
> to call mii_phy_probe() from spider_net_setup_aneg(), or to call
> reset_one_mii_phy() from bcm54xx_setup_aneg().
> 
> We think these (1)-(3) are necessary, but we are afraid that you removed
> them
> by a reason that they causes some trouble in Cell Blade. If so please
> tell us.

You might want to borrow the link state machine from sungem.c instead...
it tends to just work :-)

Ben.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-06  7:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-06  7:08 UTC (permalink / raw)
  To: buildroot

-e 's/^.*(.CC) \([0-9\.]\)/\1/g' -e "s/[-\ ].*//g"

What do you think? 

---------------------------------------------------------------------- 
 bernhardf - 11-28-06 02:08  
---------------------------------------------------------------------- 
fixed in r16703 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
11-20-06 17:47  alchemar       New Issue                                    
11-20-06 17:47  alchemar       Status                   new => assigned     
11-20-06 17:47  alchemar       Assigned To               => uClibc          
11-20-06 17:47  alchemar       File Added: dependencies.sh                    
11-22-06 13:16  bernhardf      Note Added: 0001770                          
11-22-06 15:41  alchemar       Note Added: 0001788                          
11-22-06 16:14  bernhardf      Note Added: 0001789                          
11-28-06 01:48  bernhardf      Note Added: 0001820                          
11-28-06 02:07  bernhardf      Relationship added       duplicate of 0000961
11-28-06 02:08  bernhardf      Status                   assigned => closed  
11-28-06 02:08  bernhardf      Note Added: 0001824                          
11-28-06 02:08  bernhardf      Resolution               open => fixed       
02-12-07 05:43  vapier         Status                   closed => assigned  
02-12-07 05:43  vapier         Assigned To              uClibc => buildroot 
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-06  7:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-06  7:08 UTC (permalink / raw)
  To: buildroot

the build_i386/staging_dir. It seems to be creating a full usr/include,
usr/lib, etc directory hierarchy under inside build_i386/staging_dir,
rather than integrating with the include/lib/etc dirs that exist at the
staging_dir level (ie. the installation of gettext files occurs at one
level too deep)

This means that libintl.h and the shared libraries aren't where other apps
expect it and compilation errors can occur.

The attached patch fixes this - hope it's ok.

Cheers,

Marcus
====================================================================== 

---------------------------------------------------------------------- 
 prpplague - 05-24-06 07:49  
---------------------------------------------------------------------- 
fixed as of revision 15160 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
11-29-05 07:56  crafterm       New Issue                                    
11-29-05 07:56  crafterm       Status                   new => assigned     
11-29-05 07:56  crafterm       Assigned To               => uClibc          
11-29-05 07:56  crafterm       File Added: gettext-stagingfix.patch             
      
05-24-06 07:49  prpplague      Note Added: 0001377                          
05-24-06 07:49  prpplague      Status                   assigned => closed  
02-12-07 05:45  vapier         Status                   closed => assigned  
02-12-07 05:45  vapier         Assigned To              uClibc => buildroot 
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-06  7:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-06  7:08 UTC (permalink / raw)
  To: buildroot

targets clean and distclean are to have different effects, depending on
whether or not a .config file is present in the top-level directory.

This is because 'clean' and 'distclean' are part of the noconfig_targets
list.

The attached patch removes clean and distclean from the noconfig_targets
list, allowing the behavior of clean and distclean to vary depending on
whether or not a .config file is present.

====================================================================== 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
04-22-05 19:31  samrobb        New Issue                                    
04-22-05 19:31  samrobb        File Added: noconfig_targets.patch               
    
01-25-06 05:37  prpplague      Status                   assigned => resolved
01-25-06 05:37  prpplague      Resolution               open => fixed       
01-25-06 05:37  prpplague      Additional Information Updated                   

03-08-06 16:53  vapier         Status                   resolved => closed  
02-12-07 05:47  vapier         Status                   closed => assigned  
02-12-07 05:47  vapier         Assigned To              uClibc => buildroot 
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-06  7:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-06  7:08 UTC (permalink / raw)
  To: buildroot

make[1]: Leaving directory `/tmp/buildroot/package/config'
package/Config.in:33: can't open file "package/config/Config.in"
make: *** [menuconfig] Error 1

Adding Config.h fomr a cvs ckeckout fixed it.
====================================================================== 

---------------------------------------------------------------------- 
 vapier - 03-20-05 18:38  
---------------------------------------------------------------------- 
works fine for me ...

i turned on these options under packages:
[*] DHCP support
[*]  dhcp server
[*]  dhcp relay
[*]  dhcp client 

---------------------------------------------------------------------- 
 thomasez - 03-31-05 11:22  
---------------------------------------------------------------------- 
It has obviously been fixed. This bug should be closed (Yes, I tested this
now aswell). 

---------------------------------------------------------------------- 
 vapier - 03-31-05 12:02  
---------------------------------------------------------------------- 
sounds good 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
02-10-05 13:53  thomasez       New Issue                                    
03-16-05 12:13  andersen       Status                   new => assigned     
03-16-05 12:13  andersen       Assigned To               => uClibc          
03-20-05 18:38  vapier         Note Added: 0000109                          
03-31-05 11:22  thomasez       Note Added: 0000121                          
03-31-05 12:02  vapier         Status                   assigned => closed  
03-31-05 12:02  vapier         Note Added: 0000122                          
02-12-07 05:51  vapier         Status                   closed => assigned  
02-12-07 05:51  vapier         Assigned To              uClibc => buildroot 
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-14  8:32 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-14  8:32 UTC (permalink / raw)
  To: buildroot

make[1]: Leaving directory `/tmp/buildroot/package/config'
package/Config.in:33: can't open file "package/config/Config.in"
make: *** [menuconfig] Error 1

Adding Config.h fomr a cvs ckeckout fixed it.
====================================================================== 

---------------------------------------------------------------------- 
 vapier - 03-20-05 18:38  
---------------------------------------------------------------------- 
works fine for me ...

i turned on these options under packages:
[*] DHCP support
[*]  dhcp server
[*]  dhcp relay
[*]  dhcp client 

---------------------------------------------------------------------- 
 thomasez - 03-31-05 11:22  
---------------------------------------------------------------------- 
It has obviously been fixed. This bug should be closed (Yes, I tested this
now aswell). 

---------------------------------------------------------------------- 
 vapier - 03-31-05 12:02  
---------------------------------------------------------------------- 
sounds good 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
02-10-05 13:53  thomasez       New Issue                                    
03-16-05 12:13  andersen       Status                   new => assigned     
03-16-05 12:13  andersen       Assigned To               => uClibc          
03-20-05 18:38  vapier         Note Added: 0000109                          
03-31-05 11:22  thomasez       Note Added: 0000121                          
03-31-05 12:02  vapier         Status                   assigned => closed  
03-31-05 12:02  vapier         Note Added: 0000122                          
02-12-07 05:51  vapier         Status                   closed => assigned  
02-12-07 05:51  vapier         Assigned To              uClibc => buildroot 
03-08-07 00:13  bernhardf      Status                   assigned => closed  
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-14  8:32 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-14  8:32 UTC (permalink / raw)
  To: buildroot

the build_i386/staging_dir. It seems to be creating a full usr/include,
usr/lib, etc directory hierarchy under inside build_i386/staging_dir,
rather than integrating with the include/lib/etc dirs that exist at the
staging_dir level (ie. the installation of gettext files occurs at one
level too deep)

This means that libintl.h and the shared libraries aren't where other apps
expect it and compilation errors can occur.

The attached patch fixes this - hope it's ok.

Cheers,

Marcus
====================================================================== 

---------------------------------------------------------------------- 
 prpplague - 05-24-06 07:49  
---------------------------------------------------------------------- 
fixed as of revision 15160 

---------------------------------------------------------------------- 
 bernhardf - 03-20-07 11:02  
---------------------------------------------------------------------- 
This was apparently fixed back in r15160. Closing (again). 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
11-29-05 07:56  crafterm       New Issue                                    
11-29-05 07:56  crafterm       Status                   new => assigned     
11-29-05 07:56  crafterm       Assigned To               => uClibc          
11-29-05 07:56  crafterm       File Added: gettext-stagingfix.patch             
      
05-24-06 07:49  prpplague      Note Added: 0001377                          
05-24-06 07:49  prpplague      Status                   assigned => closed  
02-12-07 05:45  vapier         Status                   closed => assigned  
02-12-07 05:45  vapier         Assigned To              uClibc => buildroot 
03-20-07 11:02  bernhardf      Status                   assigned => closed  
03-20-07 11:02  bernhardf      Note Added: 0002256                          
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-14  8:32 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-14  8:32 UTC (permalink / raw)
  To: buildroot

Does this handle multiple patch-files ?

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-02-14  8:32 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-02-14  8:32 UTC (permalink / raw)
  To: buildroot

people think about this, though.

HTH,

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-06-23 20:07 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-06-23 20:07 UTC (permalink / raw)
  To: buildroot

* under $(STAGING_DIR)/{bin,lib,include} and $(STAGING_DIR)/{bin,lib}
for the toolchain (e.g. uclibc)
* under $(STAGING_DIR)/usr/{bin,lib,include} and
$(STAGING_DIR)/usr/{bin,lib} for other packages (e.g. gtk)

Is this correct?

If so, we have a problem.
Half the of the package/*/*.mk use one option, half use the other.
As I "svn uped" today, the fontconfig package I had a hard time
patching broke, because expat decided AGAIN to install directly under
/lib.

Please, please establish a clear policy on this, so we can start
submiting patches
-- 
Julien Letessier
<julien.letessier@technosens.fr>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-07-23 18:04 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-07-23 18:04 UTC (permalink / raw)
  To: buildroot

the extra path arguments to configure at all.

Care to remove those and send a tested, updated patch?

TIA && cheers,
Bernhard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-07-23 18:04 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-07-23 18:04 UTC (permalink / raw)
  To: buildroot

> 
> I Think we should modify this so that the Makefile
> checks for the existance of the source file in $(DL_DIR)
> like most other packages.
> Tried, (see patch below), but the rule:
> 
> +$(DL_DIR)/$$($(PKG)_SOURCE):
>         $(call MESSAGE,"Downloading")
>         test -e $(DL_DIR)/$($(PKG)_SOURCE) || $(WGET) -P $(DL_DIR)
> $($(PKG)_SITE)/$($(PKG)_SOURCE)
>         mkdir -p $(@D)
Mainly because of the way, make handles variables. They get
expanded,when the makefile is parsed. Even the doubled dollarsign can't
help you here.

> 
> fails (is not found) so I had to add 
> 
> +$$($(2)_TARGET_SOURCE):
> +       $(WGET) -P $(DL_DIR) $$($(2)_SITE)/$$($(2)_SOURCE)
> +
> 
In the macro it gets evaluated every time any package wants it to use.
Does that really pays the one unneeded stamp-file?

> to make it work.
> Anyone got a clue why the first rule fails?
> 
> 
> Maybe we should also consider building x11r7 in $(BUILD_DIR)/x11r7
> due to crowding.
You even get afraid of crowding, aren't you?
> 
> 
> Index: package/Makefile.autotools.in
> ===================================================================
> --- package/Makefile.autotools.in       (revision 19425)
> +++ package/Makefile.autotools.in       (arbetskopia)
> @@ -127,7 +127,7 @@
> 
> ################################################################################
>  
>  # Retrieve and unpack the archive
> -$(BUILD_DIR)/%/.stamp_downloaded:
> +$(DL_DIR)/$$($(PKG)_SOURCE):
>         $(call MESSAGE,"Downloading")
>         test -e $(DL_DIR)/$($(PKG)_SOURCE) || $(WGET) -P $(DL_DIR)
> $($(PKG)_SITE)/$($(PKG)_SOURCE)
>         mkdir -p $(@D)
> @@ -279,7 +279,7 @@
>  $(2)_TARGET_AUTORECONF =       $$($(2)_DIR)/.stamp_autoconfigured
>  $(2)_TARGET_PATCH =            $$($(2)_DIR)/.stamp_patched
>  $(2)_TARGET_EXTRACT =          $$($(2)_DIR)/.stamp_extracted
> -$(2)_TARGET_SOURCE =           $$($(2)_DIR)/.stamp_downloaded
> +$(2)_TARGET_SOURCE =           $$(DL_DIR)/$$($(2)_SOURCE)
>  $(2)_TARGET_UNINSTALL =                $$($(2)_DIR)/.stamp_uninstalled
>  $(2)_TARGET_CLEAN =            $$($(2)_DIR)/.stamp_cleaned
>  $(2)_TARGET_DIRCLEAN =         $$($(2)_DIR)/.stamp_dircleaned
> @@ -322,6 +322,9 @@
>  
>  $(1)-depends:          $(1)-source $$($(2)_DEPENDANCIES)
>  
> +$$($(2)_TARGET_SOURCE):
> +       $(WGET) -P $(DL_DIR) $$($(2)_SITE)/$$($(2)_SOURCE)
> +
>  $(1)-source:           $$($(2)_TARGET_SOURCE)
>  
>  # non-build targets
> 
> 
> Best Regards
> Ulf Samuelsson
> 
> 
> 
> 
> 
> 
> 
> _______________________________________________
> buildroot mailing list
> buildroot at uclibc.org
> http://busybox.net/mailman/listinfo/buildroot
> 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-10-06 20:13 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-10-06 20:13 UTC (permalink / raw)
  To: buildroot

I assume make allconfig will give tons of errors.
Today I just tried to make all packages except "Graphic libraries and applications"
and it gave me about 40 errors related with wrong URLs and versions! I'm not talking
about even correctness of installing into staging dir and rootfs packaging.



Best regards,
Ivan
--------------------------------
Embedded Linux engineer,
Promwad Company: http://www.promwad.com/
Homepage : http://www.ivankuten.com/
--------------------------------

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-10-06 20:13 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-10-06 20:13 UTC (permalink / raw)
  To: buildroot

May be strace does not provide correct output?

Regards,
Ivan

ing. Federico Fuga wrote:
> Hi Ivan,
> 
> which kernel version and kernel headers are you using? Mine are 2.6.23.1
> and 2.6.23, but now I am trying to move the kernel headers to 2.6.21
> (Angstrom  linux works without problems, but are based on different
> kernel headers).
> uclibc I am using are 0.9.29, alsa 1.0.14.
> The failing ioctl is identical both in the working (Angstrom) and not
> working versions, and since the kernel is the same (really the same!) I
> am thinking that is only a problem between the "glue" of uclibc and
> kernel...
> I'll keep you informed.
> 
> Regards,
> 
> ing. Federico Fuga
> 
> Ivan Kuten ha scritto:
>> Hi Federico!
>>
>> I'm observing the same problem with ALSA as you.
>>
>>   
>>> ioctl(4, USBDEVFS_CONTROL, 0xbef809cc)  = 0
>>> ioctl(4, UI_DEV_CREATE, 0xbef80ab0)     = 0
>>> ioctl(4, USBDEVFS_CONNECTINFO, 0xbef80634) = 0
>>> ioctl(4, USBDEVFS_HUB_PORTINFO, 0xbef80748) = -1 ENOTTY (Inappropriate
>>> ioctl for device)
>>>     
>> Think these lines are key to understanding what the problem is.
>>
>> Regards,
>> Ivan
>>
>>
>>   
> 


--------------------------------
Embedded Linux engineer,
Promwad Company: http://www.promwad.com/
Homepage : http://www.ivankuten.com/
--------------------------------

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-10-06 20:13 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-10-06 20:13 UTC (permalink / raw)
  To: buildroot

Regards,
Ivan
-- 

--------------------------------
Embedded Linux engineer,
Promwad Company: http://www.promwad.com/
Homepage : http://www.ivankuten.com/
--------------------------------

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-12-01  7:52 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-12-01  7:52 UTC (permalink / raw)
  To: buildroot

native gcc (not the cross-compiler), which is using headers from
/usr. That looks like a bug, either in the configure script or in the
relevant .mk files for programs that use OpenSSL.

I've got OpenSSL enabled with python linking against it and no such
issues.


Hamish
-- 
Hamish Moffatt VK3SB <hamish@debian.org> <hamish@cloud.net.au>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2007-12-01  7:52 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2007-12-01  7:52 UTC (permalink / raw)
  To: buildroot

default "package/busybox/busybox-1.6.0.config" if BR2_BUSYBOX_VERSION_1_9_X

 Will> I have fixed it by just going back to the 1.6.0 file - is that correct?

Yes.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-03-17 22:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-03-17 22:01 UTC (permalink / raw)
  To: buildroot

There is a dependency on buildroot's gcc 3.4.6 that probably should be
added.

As for mapping buildroot's target architectures to uMon ports, that
may be unnecessary.  However, the following ports are available in
uMon:

adse_imx21
as3dev
csb250
csb335
csb360
csb472
csb625
csb655
fads860
ads_imx21
bf537
csb272
csb337
csb431
csb535fs
csb637
csb726
mpc852t
v4
altep2c35
csb226
csb281
csb350
csb437tl
csb536fs
csb650
evalsh2
m68en302
walnut

I'm not the best candidate to limit uMon selection to buildroot
architectures that cover those ports.

Josh

On Mon, Mar 31, 2008 at 10:55 PM, Ulf Samuelsson <ulf@atmel.com> wrote:
>
>
>  > The following patch adds support for the Microcross Micromonitor
>  > (uMon) bootloader.
>  > Josh
>  >
>  >
>
>  Does this work for all targets, or do we want to only
>  enable the configuration for those targets which
>  actually can build uMon?
>
>  Best Regards
>  Ulf Samuelsson
>
>
>
>
>  > diff -purN buildroot/target/Config.in buildroot-umon/target/Config.in
>  > --- buildroot/target/Config.in 2008-03-31 00:15:26.000000000 -0700
>  > +++ buildroot-umon/target/Config.in 2008-03-31 22:22:09.000000000 -0700
>  > @@ -19,6 +19,7 @@ source "target/x86/grub/Config.in"
>  > source "target/x86/syslinux/Config.in"
>  > source "target/powerpc/yaboot/Config.in"
>  > source "target/u-boot/Config.in"
>  > +source "target/umon/Config.in"
>  > endmenu
>  >
>  > menu "Kernel"
>  > diff -purN buildroot/target/Makefile.in buildroot-umon/target/Makefile.in
>  > --- buildroot/target/Makefile.in 2008-03-31 00:15:26.000000000 -0700
>  > +++ buildroot-umon/target/Makefile.in 2008-03-31 22:22:30.000000000 -0700
>  > @@ -15,6 +15,10 @@ ifeq ($(strip $(BR2_TARGET_UBOOT)),y)
>  > include target/u-boot/Makefile.in
>  > endif
>  >
>  > +ifeq ($(strip $(BR2_TARGET_UMON)),y)
>  > +include target/umon/Makefile.in
>  > +endif
>  > +
>  > # and finally build the filesystems/tarballs
>  > include target/*/*.mk
>  >
>  > diff -purN buildroot/target/umon/Config.in buildroot-umon/target/umon/Config.in
>  > --- buildroot/target/umon/Config.in 1969-12-31 16:00:00.000000000 -0800
>  > +++ buildroot-umon/target/umon/Config.in 2008-03-31 22:18:49.000000000 -0700
>  > @@ -0,0 +1,20 @@
>  > +config BR2_TARGET_UMON
>  > + bool "Micromonitor Boot Loader"
>  > + default n
>  > + help
>  > +   Build uMon bootloader.
>  > +
>  > +config BR2_TARGET_UMON_PORT
>  > + string "port name"
>  > + depends on BR2_TARGET_UMON
>  > + default "$(BOARD_NAME)"
>  > + help
>  > +   uMon port name. This is the name of the directory under umon_ports.
>  > +
>  > +config BR2_TARGET_UMON_CUSTOM_PATCH
>  > + string "custom patch"
>  > + depends on BR2_TARGET_UMON
>  > + help
>  > +   If your board requires a custom patch, add the path to the file here.
>  > +   Most users may leave this empty.
>  > +
>  > diff -purN buildroot/target/umon/Makefile.in
>  > buildroot-umon/target/umon/Makefile.in
>  > --- buildroot/target/umon/Makefile.in 1969-12-31 16:00:00.000000000 -0800
>  > +++ buildroot-umon/target/umon/Makefile.in 2008-03-31 22:18:49.000000000 -0700
>  > @@ -0,0 +1,66 @@
>  > +#############################################################
>  > +#
>  > +# umon
>  > +#
>  > +#############################################################
>  > +UMON_VERSION:=sep8_2007
>  > +UMON_SOURCE:=umon_$(UMON_VERSION).tgz
>  > +UMON_SITE:=http://microcross.com
>  > +UMON_PORT:=$(strip $(subst ",,$(BR2_TARGET_UMON_PORT)))
>  > +UMON_DIR:=$(PROJECT_BUILD_DIR)/umon/umon_ports/$(UMON_PORT)
>  > +UMON_HOST_DIR:=$(PROJECT_BUILD_DIR)/umon/umon_main/host
>  > +UMON_PATCH_DIR:=$(PROJECT_BUILD_DIR)/umon-patches
>  > +UMON_CAT:=$(ZCAT)
>  > +UMON_BIN:=boot.bin
>  > +UMON_TOP:=$(PROJECT_BUILD_DIR)/umon/umon_main
>  > +# this is a nasty hack to get the PLATFORM variable from the makefile
>  > +UMON_PLATFORM:=$$(grep '^PLATFORM.*=' $(UMON_DIR)/makefile | sed
>  > 's@^PLATFORM.*=@@')
>  > +
>  > +$(DL_DIR)/$(UMON_SOURCE):
>  > + $(WGET) -P $(DL_DIR) $(UMON_SITE)/$(UMON_SOURCE)
>  > +
>  > +$(UMON_DIR)/.unpacked: $(DL_DIR)/$(UMON_SOURCE)
>  > + $(UMON_CAT) $(DL_DIR)/$(UMON_SOURCE) \
>  > + | tar -C $(PROJECT_BUILD_DIR) $(TAR_OPTIONS) -
>  > + touch $@
>  > +
>  > +$(UMON_DIR)/.patched: $(UMON_DIR)/.unpacked
>  > +ifneq ($(strip $(BR2_TARGET_UMON_CUSTOM_PATCH)),"")
>  > + @mkdir -p $(UMON_PATCH_DIR)
>  > + cp -dpr $(BR2_TARGET_UMON_CUSTOM_PATCH) $(UMON_PATCH_DIR)
>  > + toolchain/patch-kernel.sh $(PROJECT_BUILD_DIR)/umon $(UMON_PATCH_DIR) *.patch
>  > +endif
>  > + touch $@
>  > +
>  > +$(UMON_DIR)/build_$(UMON_PLATFORM)/$(UMON_BIN): $(UMON_DIR)/.patched
>  > + $(MAKE) -C $(UMON_HOST_DIR) UMON_TOP=$(UMON_TOP) OSTYPE=linux install
>  > + $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(UMON_DIR) UMONTOP=$(UMON_TOP)
>  > +
>  > +$(BINARIES_DIR)/$(UMON_BIN): $(UMON_DIR)/build_$(UMON_PLATFORM)/$(UMON_BIN)
>  > + cp $(UMON_DIR)/build_$(UMON_PLATFORM)/$(UMON_BIN) $(BINARIES_DIR)/$(UMON_BIN)
>  > +
>  > +umon: $(BINARIES_DIR)/$(UMON_BIN)
>  > +
>  > +umon-clean:
>  > + $(MAKE) -C $(UMON_DIR) clean
>  > +
>  > +umon-dirclean:
>  > + rm -rf $(UMON_DIR)
>  > +
>  > +umon-source: $(DL_DIR)/$(UMON_SOURCE)
>  > +
>  > +#############################################################
>  > +#
>  > +# Toplevel Makefile options
>  > +#
>  > +#############################################################
>  > +ifeq ($(strip $(BR2_TARGET_UMON)),y)
>  > +TARGETS+=umon
>  > +endif
>  > +
>  > +umon-status:
>  > + @echo
>  > + @echo BR2_TARGET_UMON_PORT = $(BR2_TARGET_UMON_PORT)
>  > + @echo BR2_TARGET_UMON_CUSTOM_PATCH = $(BR2_TARGET_UMON_CUSTOM_PATCH)
>  > + @echo
>  > + @exit 0
>  > _______________________________________________
>  > buildroot mailing list
>  > buildroot at uclibc.org
>  > http://busybox.net/mailman/listinfo/buildroot
>  >
>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot

0x40000930  0x40003f50  Yes
/home/osingla/buildroot-9260/buildroot/build_arm/staging_dir/lib/ld-uClibc.so.0
0x40011dd0  0x40018380  Yes
/home/osingla/buildroot-9260/buildroot/build_arm/staging_dir/lib/libpthread.so.0
0x40033800  0x40071e60  Yes
/home/osingla/buildroot-9260/buildroot/build_arm/staging_dir/lib/libc.so.0
(gdb) q
~$

When the thread has been created, it is not visible from the debugger.
It runs, but I can't put a breakpoint.
A few notes:

- I do not like the message "warning: Remote failure reply: E01", it
might mean that gdb host and gdbserver are not in sync for whatever
reason.

- If I put a breakpoint on the thread function, before 'cont', the
program terminates as soon the thread is created.

- the shared library 'thread_db' is not loaded (I think it should):
# cat /proc/2298/maps
00008000-00009000 r-xp 00000000 00:0c 4339       /tmp/test
00010000-00011000 rw-p 00000000 00:0c 4339       /tmp/test
00011000-00012000 rwxp 00011000 00:00 0          [heap]
40000000-40005000 r-xp 00000000 00:01 398        /lib/ld-uClibc-0.9.29.so
40005000-40006000 rw-p 40005000 00:00 0
4000c000-4000d000 r--p 00004000 00:01 398        /lib/ld-uClibc-0.9.29.so
4000d000-4000e000 rw-p 00005000 00:01 398        /lib/ld-uClibc-0.9.29.so
4000e000-40019000 r-xp 00000000 00:01 406        /lib/libpthread-0.9.29.so
40019000-40020000 ---p 40019000 00:00 0
40020000-40021000 r--p 0000a000 00:01 406        /lib/libpthread-0.9.29.so
40021000-40026000 rw-p 0000b000 00:01 406        /lib/libpthread-0.9.29.so
40026000-40028000 rw-p 40026000 00:00 0
40028000-400b5000 r-xp 00000000 00:01 414        /lib/libuClibc-0.9.29.so
400b5000-400bc000 ---p 400b5000 00:00 0
400bc000-400bd000 r--p 0008c000 00:01 414        /lib/libuClibc-0.9.29.so
400bd000-400be000 rw-p 0008d000 00:01 414        /lib/libuClibc-0.9.29.so
400be000-400c3000 rw-p 400be000 00:00 0
bebde000-bebf3000 rwxp befeb000 00:00 0          [stack]

I used linuxthreads (stable/old), and I checked 'pthreads debugging
support ' within uclibc menuconfig.

Any idea what I am missing?

TIA,
~Olivier

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot

./arch-arm/kernel-patches-2.6.24/linux-2.6.24-at91.patch
./arch-arm/kernel-patches-2.6.20.4/linux-2.6.20.4-atmel.patch
./arch-arm/kernel-patches-2.6.21.1/linux-2.6.21.1-at91.patch
./arch-arm/kernel-patches-2.6.21.1/linux-2.6.21.1-at91-1-update.patch
./arch-arm/kernel-patches-2.6.21.5/linux-2.6.21.5-at91-1-update.patch
./arch-arm/kernel-patches-2.6.21.5/linux-2.6.21.5-at91.patch

Not to mention having a separate u-boot, just because the Atmel ARM
didn't get to get their patches upstream, while AVR32 did.

>  > On top of that, external toolchain tries to download prepatched
>  > toochain from a site that you control, but that has no such files to
>  > download from.
>
>  BR2_ATMEL_MIRROR should be ftp://www.at91.com/pub/buildroot/
>  I see the files in this location.

There is no gcc 4.2.2 in there. There is no gdb-4.7.1 in there.

>  > Please revert your changes asap.
>  >
>
>  No, if there are problems, it should be fixed within the external toolchain
>  to avoid adding those megabytes, which are of no interest to AVR32 users.
>  There are hooks to patch the external toolchain if neccessary.

Then I guess we will all be getting FTP user accounts to your server
now? So that we can fix things within the external toolchain?
I'm interested in those few kb (namely 915826 bytes). Last time I
checked, I was in the universe of AVR32 users.

You didn't even care to test your changes, and despite protests
removed the toolchain support anyway. You are taking away our freedom
to update, fix, do whatever with the toolchain from within buildroot.
Not to mention breaking things up and making me and a hell lot of
other people lose their day's or week's work.
Please revert your changes asap.

Regards,
   Thiago A. Correa

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot

make[1]: Entering directory
`/media/EkstraDisk/buildroot/build_i686/dnsmasq-2.41'
cd src && /usr/bin/make \
 DBUS_MINOR=" `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --modversion
dbus-1 | nawk -F . -- '{ if ($(NF-1)) print \"-DDBUS_MINOR=\"$(NF-1) }'`" 
\
 DBUS_CFLAGS="`echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --cflags
dbus-1`"  \
 DBUS_LIBS="  `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --libs
dbus-1`"  \
 SUNOS_LIBS=" `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket
-lnsl -lposix4; fi `" \
 SUNOS_VER="  `if uname | grep SunOS 2>&1 >/dev/null; then uname -r | nawk
-F . -- '{ print \"-DSUNOS_VER=\"$2 }'; fi`" \
 -f ../bld/Makefile dnsmasq 
/bin/sh: line 1: nawk: command not found

Don't you have nawk installed? On my system, nawk is a link to gawk.

Seems like we don't currently check for awk in dependencies.sh, will fix 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
06-14-08 17:01  KHAksnes       New Issue                                    
06-14-08 17:01  KHAksnes       Status                   new => assigned     
06-14-08 17:01  KHAksnes       Assigned To               => buildroot       
06-15-08 13:40  jacmet         Note Added: 0008264                          
06-15-08 14:07  KHAksnes       Note Added: 0008274                          
06-15-08 14:08  KHAksnes       File Added: compilelog                       
06-18-08 06:06  jacmet         Note Added: 0008384                          
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot

make[1]: Entering directory
`/media/EkstraDisk/buildroot/build_i686/dnsmasq-2.41'
cd src && /usr/bin/make \
 DBUS_MINOR=" `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --modversion
dbus-1 | nawk -F . -- '{ if ($(NF-1)) print \"-DDBUS_MINOR=\"$(NF-1) }'`" 
\
 DBUS_CFLAGS="`echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --cflags
dbus-1`"  \
 DBUS_LIBS="  `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --libs
dbus-1`"  \
 SUNOS_LIBS=" `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket
-lnsl -lposix4; fi `" \
 SUNOS_VER="  `if uname | grep SunOS 2>&1 >/dev/null; then uname -r | nawk
-F . -- '{ print \"-DSUNOS_VER=\"$2 }'; fi`" \
 -f ../bld/Makefile dnsmasq 
/bin/sh: line 1: nawk: command not found

Don't you have nawk installed? On my system, nawk is a link to gawk.

Seems like we don't currently check for awk in dependencies.sh, will fix 

---------------------------------------------------------------------- 
 jacmet - 06-18-08 06:17  
---------------------------------------------------------------------- 
I have now added an awk check to dependencies.sh and forced dnsmasq to use
awk rather than nawk, so closing issue. 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
06-14-08 17:01  KHAksnes       New Issue                                    
06-14-08 17:01  KHAksnes       Status                   new => assigned     
06-14-08 17:01  KHAksnes       Assigned To               => buildroot       
06-15-08 13:40  jacmet         Note Added: 0008264                          
06-15-08 14:07  KHAksnes       Note Added: 0008274                          
06-15-08 14:08  KHAksnes       File Added: compilelog                       
06-18-08 06:06  jacmet         Note Added: 0008384                          
06-18-08 06:17  jacmet         Status                   assigned => resolved
06-18-08 06:17  jacmet         Resolution               open => fixed       
06-18-08 06:17  jacmet         Note Added: 0008394                          
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot


Modified:
   trunk/buildroot/Makefile
   trunk/buildroot/package/config/Makefile


Changeset:
Modified: trunk/buildroot/Makefile
===================================================================
--- trunk/buildroot/Makefile	2008-06-19 07:24:59 UTC (rev 22448)
+++ trunk/buildroot/Makefile	2008-06-19 08:11:35 UTC (rev 22449)
@@ -170,6 +170,8 @@
 HOST_EXEEXT:=.exe
 HOST_LIBEXT:=.lib
 HOST_SHREXT:=.dll
+HOST_LOADLIBES="-lcurses -lintl"
+export HOST_LOADLIBES
 endif
 ifneq ($(findstring mingw,$(BR2_GNU_BUILD_SUFFIX)),)
 HOST_EXEEXT:=.exe

Modified: trunk/buildroot/package/config/Makefile
===================================================================
--- trunk/buildroot/package/config/Makefile	2008-06-19 07:24:59 UTC (rev 22448)
+++ trunk/buildroot/package/config/Makefile	2008-06-19 08:11:35 UTC (rev 22449)
@@ -17,10 +17,10 @@
 host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
 
 $(host-csingle): %: %.c
-	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $< -o $@
+	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $< $(HOST_LOADLIBES) -o $@
 
 $(host-cmulti): %: $(host-cobjs) $(host-cshlib)
-	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $(HOST_LOADLIBES) $($@-objs) -o $@
+	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) $($@-objs) $(HOST_LOADLIBES) -o $@
 
 $(host-cobjs): %.o: %.c
 	$(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS) $(HOSTCFLAGS_$@) -c $< -o $@

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot


Modified:
   trunk/buildroot/package/config/Makefile.kconfig
   trunk/buildroot/package/config/README.buildroot2
   trunk/buildroot/package/config/conf.c
   trunk/buildroot/package/config/confdata.c
   trunk/buildroot/package/config/expr.h
   trunk/buildroot/package/config/gconf.c
   trunk/buildroot/package/config/kconfig-language.txt
   trunk/buildroot/package/config/kconfig-to-buildroot2.patch
   trunk/buildroot/package/config/kxgettext.c
   trunk/buildroot/package/config/lkc_proto.h
   trunk/buildroot/package/config/lxdialog/check-lxdialog.sh
   trunk/buildroot/package/config/mconf.c
   trunk/buildroot/package/config/menu.c
   trunk/buildroot/package/config/qconf.cc
   trunk/buildroot/package/config/zconf.tab.c_shipped
   trunk/buildroot/package/config/zconf.y


Changeset:
Modified: trunk/buildroot/package/config/Makefile.kconfig
===================================================================
--- trunk/buildroot/package/config/Makefile.kconfig	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/Makefile.kconfig	2008-06-19 08:11:43 UTC (rev 22450)
@@ -22,24 +22,25 @@
 silentoldconfig: $(obj)/conf
 	$< -s arch/$(ARCH)/Kconfig
 
+# Create new linux.po file
+# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
+# The symlink is used to repair a deficiency in arch/um
 update-po-config: $(obj)/kxgettext
-	xgettext --default-domain=linux \
-          --add-comments --keyword=_ --keyword=N_ \
-          --files-from=scripts/kconfig/POTFILES.in \
-          --output scripts/kconfig/config.pot
-	$(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch
-	$(Q)for i in `ls arch/`; \
-	do \
-	  scripts/kconfig/kxgettext arch/$$i/Kconfig \
-	    | msguniq -o scripts/kconfig/linux_$${i}.pot; \
-	done
-	$(Q)msgcat scripts/kconfig/config.pot \
-	  `find scripts/kconfig/ -type f -name linux_*.pot` \
-	  --output scripts/kconfig/linux_raw.pot
-	$(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \
-	    --output scripts/kconfig/linux.pot
-	$(Q)rm -f arch/um/Kconfig_arch
-	$(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot
+	xgettext --default-domain=linux                  \
+	    --add-comments --keyword=_ --keyword=N_      \
+	    --from-code=UTF-8                            \
+	    --files-from=scripts/kconfig/POTFILES.in     \
+	    --output $(obj)/config.pot
+	$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
+	$(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
+	(for i in `ls arch/`;                            \
+	do                                               \
+	    $(obj)/kxgettext arch/$$i/Kconfig;           \
+	done ) >> $(obj)/config.pot
+	msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
+	    --output $(obj)/linux.pot
+	$(Q)rm -f arch/um/Kconfig.arch
+	$(Q)rm -f $(obj)/config.pot
 
 PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
 

Modified: trunk/buildroot/package/config/README.buildroot2
===================================================================
--- trunk/buildroot/package/config/README.buildroot2	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/README.buildroot2	2008-06-19 08:11:43 UTC (rev 22450)
@@ -1,15 +1,16 @@
-This is a copy of the kconfig code in the kernel (currently 2.6.22.7) tweaked to
-suit Buildroot.
+This is a copy of the kconfig code in the kernel (currently 2.6.23.14) tweaked
+to suit Buildroot.
 
 To update:
 	cp -r /usr/src/linux/scripts/kconfig package/config.new
 	cd package/config.new
 	cp /usr/src/linux/Documentation/kbuild/kconfig-language.txt .
+	patch -p1 < ../config/kconfig-to-buildroot2.patch
 	mv Makefile Makefile.kconfig
-	patch -p1 < ../config/kconfig-to-buildroot2.patch
 	cp ../config/README.buildroot2 .
 	cp ../config/foo.h .
 	cp ../config/Makefile .
+	cp ../config/kconfig-to-buildroot2.patch .
 	cd ..
 	rm -rf config
 	mv config.new config

Modified: trunk/buildroot/package/config/conf.c
===================================================================
--- trunk/buildroot/package/config/conf.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/conf.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -37,6 +37,14 @@
 
 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 
+static const char *get_help(struct menu *menu)
+{
+	if (menu_has_help(menu))
+		return menu_get_help(menu);
+	else
+		return nohelp_text;
+}
+
 static void strip(char *str)
 {
 	char *p = str;
@@ -172,7 +180,7 @@
 int conf_string(struct menu *menu)
 {
 	struct symbol *sym = menu->sym;
-	const char *def, *help;
+	const char *def;
 
 	while (1) {
 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
@@ -188,10 +196,7 @@
 		case '?':
 			/* print help */
 			if (line[1] == '\n') {
-				help = nohelp_text;
-				if (menu->sym->help)
-					help = menu->sym->help;
-				printf("\n%s\n", menu->sym->help);
+				printf("\n%s\n", get_help(menu));
 				def = NULL;
 				break;
 			}
@@ -209,7 +214,6 @@
 	struct symbol *sym = menu->sym;
 	int type;
 	tristate oldval, newval;
-	const char *help;
 
 	while (1) {
 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
@@ -235,7 +239,7 @@
 			printf("/m");
 		if (oldval != yes && sym_tristate_within_range(sym, yes))
 			printf("/y");
-		if (sym->help)
+		if (menu_has_help(menu))
 			printf("/?");
 		printf("] ");
 		if (!conf_askvalue(sym, sym_get_string_value(sym)))
@@ -272,10 +276,7 @@
 		if (sym_set_tristate_value(sym, newval))
 			return 0;
 help:
-		help = nohelp_text;
-		if (sym->help)
-			help = sym->help;
-		printf("\n%s\n", help);
+		printf("\n%s\n", get_help(menu));
 	}
 }
 
@@ -345,7 +346,7 @@
 			goto conf_childs;
 		}
 		printf("[1-%d", cnt);
-		if (sym->help)
+		if (menu_has_help(menu))
 			printf("?");
 		printf("]: ");
 		switch (input_mode) {
@@ -362,8 +363,7 @@
 			fgets(line, 128, stdin);
 			strip(line);
 			if (line[0] == '?') {
-				printf("\n%s\n", menu->sym->help ?
-					menu->sym->help : nohelp_text);
+				printf("\n%s\n", get_help(menu));
 				continue;
 			}
 			if (!line[0])
@@ -394,8 +394,7 @@
 		if (!child)
 			continue;
 		if (line[strlen(line) - 1] == '?') {
-			printf("\n%s\n", child->sym->help ?
-				child->sym->help : nohelp_text);
+			printf("\n%s\n", get_help(child));
 			continue;
 		}
 		sym_set_choice_value(sym, child->sym);

Modified: trunk/buildroot/package/config/confdata.c
===================================================================
--- trunk/buildroot/package/config/confdata.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/confdata.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -338,27 +338,42 @@
 		conf_unsaved++;
 		/* maybe print value in verbose mode... */
 	sym_ok:
+		if (!sym_is_choice(sym))
+			continue;
+		/* The choice symbol only has a set value (and thus is not new)
+		 * if all its visible childs have values.
+		 */
+		prop = sym_get_choice_prop(sym);
+		flags = sym->flags;
+		for (e = prop->expr; e; e = e->left.expr)
+			if (e->right.sym->visible != no)
+				flags &= e->right.sym->flags;
+		sym->flags &= flags | ~SYMBOL_DEF_USER;
+	}
+
+	for_all_symbols(i, sym) {
 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
-			if (sym->visible == no)
+			/* Reset values of generates values, so they'll appear
+			 * as new, if they should become visible, but that
+			 * doesn't quite work if the Kconfig and the saved
+			 * configuration disagree.
+			 */
+			if (sym->visible == no && !conf_unsaved)
 				sym->flags &= ~SYMBOL_DEF_USER;
 			switch (sym->type) {
 			case S_STRING:
 			case S_INT:
 			case S_HEX:
-				if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
-					sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				/* Reset a string value if it's out of range */
+				if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+					break;
+				sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				conf_unsaved++;
+				break;
 			default:
 				break;
 			}
 		}
-		if (!sym_is_choice(sym))
-			continue;
-		prop = sym_get_choice_prop(sym);
-		flags = sym->flags;
-		for (e = prop->expr; e; e = e->left.expr)
-			if (e->right.sym->visible != no)
-				flags &= e->right.sym->flags;
-		sym->flags &= flags | ~SYMBOL_DEF_USER;
 	}
 
 	sym_add_change_count(conf_warnings || conf_unsaved);

Modified: trunk/buildroot/package/config/expr.h
===================================================================
--- trunk/buildroot/package/config/expr.h	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/expr.h	2008-06-19 08:11:43 UTC (rev 22450)
@@ -71,14 +71,12 @@
 struct symbol {
 	struct symbol *next;
 	char *name;
-	char *help;
 	enum symbol_type type;
 	struct symbol_value curr;
 	struct symbol_value def[4];
 	tristate visible;
 	int flags;
 	struct property *prop;
-	struct expr *dep, *dep2;
 	struct expr_value rev_dep;
 };
 
@@ -139,7 +137,7 @@
 	struct property *prompt;
 	struct expr *dep;
 	unsigned int flags;
-	/*char *help; */
+	char *help;
 	struct file *file;
 	int lineno;
 	void *data;

Modified: trunk/buildroot/package/config/gconf.c
===================================================================
--- trunk/buildroot/package/config/gconf.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/gconf.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -38,9 +38,6 @@
 static gboolean show_debug = FALSE;
 static gboolean resizeable = FALSE;
 
-static char nohelp_text[] =
-    N_("Sorry, no help available for this option yet.\n");
-
 GtkWidget *main_wnd = NULL;
 GtkWidget *tree1_w = NULL;	// left  frame
 GtkWidget *tree2_w = NULL;	// right frame
@@ -462,12 +459,9 @@
 	GtkTextIter start, end;
 	const char *prompt = menu_get_prompt(menu);
 	gchar *name;
-	const char *help = _(nohelp_text);
+	const char *help;
 
-	if (!menu->sym)
-		help = "";
-	else if (menu->sym->help)
-		help = _(menu->sym->help);
+	help = _(menu_get_help(menu));
 
 	if (menu->sym && menu->sym->name)
 		name = g_strdup_printf(_(menu->sym->name));

Modified: trunk/buildroot/package/config/kconfig-language.txt
===================================================================
--- trunk/buildroot/package/config/kconfig-language.txt	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/kconfig-language.txt	2008-06-19 08:11:43 UTC (rev 22450)
@@ -98,6 +98,15 @@
   times, the limit is set to the largest selection.
   Reverse dependencies can only be used with boolean or tristate
   symbols.
+  Note:
+	select is evil.... select will by brute force set a symbol
+	equal to 'y' without visiting the dependencies. So abusing
+	select you are able to select a symbol FOO even if FOO depends
+	on BAR that is not set. In general use select only for
+	non-visible symbols (no promts anywhere) and for symbols with
+	no dependencies. That will limit the usefulness but on the
+	other hand avoid the illegal configurations all over. kconfig
+	should one day warn about such things.
 
 - numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
   This allows to limit the range of possible input values for int

Modified: trunk/buildroot/package/config/kconfig-to-buildroot2.patch
===================================================================
--- trunk/buildroot/package/config/kconfig-to-buildroot2.patch	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/kconfig-to-buildroot2.patch	2008-06-19 08:11:43 UTC (rev 22450)
@@ -501,15 +501,6 @@
  };
  
  struct symbol {
-@@ -139,7 +139,7 @@ struct menu {
- 	struct property *prompt;
- 	struct expr *dep;
- 	unsigned int flags;
--	//char *help;
-+	/*char *help; */
- 	struct file *file;
- 	int lineno;
- 	void *data;
 diff -rdup kernel-config/gconf.c config/gconf.c
 --- kernel-config/gconf.c	2007-09-22 00:38:23.000000000 +0200
 +++ config/gconf.c	2007-09-23 15:33:26.000000000 +0200

Modified: trunk/buildroot/package/config/kxgettext.c
===================================================================
--- trunk/buildroot/package/config/kxgettext.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/kxgettext.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -170,8 +170,8 @@
 		     menu->file == NULL ? "Root Menu" : menu->file->name,
 		     menu->lineno);
 
-	if (menu->sym != NULL && menu->sym->help != NULL)
-		message__add(menu->sym->help, menu->sym->name,
+	if (menu->sym != NULL && menu_has_help(menu))
+		message__add(menu_get_help(menu), menu->sym->name,
 			     menu->file == NULL ? "Root Menu" : menu->file->name,
 			     menu->lineno);
 
@@ -212,7 +212,9 @@
 	struct message *m = message__list;
 
 	while (m != NULL) {
-		message__print_gettext_msgid_msgstr(m);
+		/* skip empty lines ("") */
+		if (strlen(m->msg) > sizeof("\"\""))
+			message__print_gettext_msgid_msgstr(m);
 		m = m->next;
 	}
 }

Modified: trunk/buildroot/package/config/lkc_proto.h
===================================================================
--- trunk/buildroot/package/config/lkc_proto.h	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/lkc_proto.h	2008-06-19 08:11:43 UTC (rev 22450)
@@ -15,6 +15,8 @@
 P(menu_get_prompt,const char *,(struct menu *menu));
 P(menu_get_root_menu,struct menu *,(struct menu *menu));
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+P(menu_has_help,bool,(struct menu *menu));
+P(menu_get_help,const char *,(struct menu *menu));
 
 /* symbol.c */
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);

Modified: trunk/buildroot/package/config/lxdialog/check-lxdialog.sh
===================================================================
--- trunk/buildroot/package/config/lxdialog/check-lxdialog.sh	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/lxdialog/check-lxdialog.sh	2008-06-19 08:11:43 UTC (rev 22450)
@@ -51,7 +51,7 @@
 	printf "Usage: $0 [-check compiler options|-header|-library]\n"
 }
 
-if [ $# == 0 ]; then
+if [ $# -eq 0 ]; then
 	usage
 	exit 1
 fi

Modified: trunk/buildroot/package/config/mconf.c
===================================================================
--- trunk/buildroot/package/config/mconf.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/mconf.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -417,11 +417,13 @@
 {
 	struct symbol **sym_arr;
 	struct gstr res;
+	char *dialog_input;
 	int dres;
 again:
 	dialog_clear();
 	dres = dialog_inputbox(_("Search Configuration Parameter"),
-			      _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"),
+			      _("Enter CONFIG_ (sub)string to search for "
+				"(with or without \"CONFIG\")"),
 			      10, 75, "");
 	switch (dres) {
 	case 0:
@@ -433,7 +435,12 @@
 		return;
 	}
 
-	sym_arr = sym_re_search(dialog_input_result);
+	/* strip CONFIG_ if necessary */
+	dialog_input = dialog_input_result;
+	if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
+		dialog_input += 7;
+
+	sym_arr = sym_re_search(dialog_input);
 	res = get_relations_str(sym_arr);
 	free(sym_arr);
 	show_textbox(_("Search Results"), str_get(&res), 0, 0);
@@ -716,11 +723,11 @@
 	struct gstr help = str_new();
 	struct symbol *sym = menu->sym;
 
-	if (sym->help)
+	if (menu_has_help(menu))
 	{
 		if (sym->name) {
 			str_printf(&help, "CONFIG_%s:\n\n", sym->name);
-			str_append(&help, _(sym->help));
+			str_append(&help, _(menu_get_help(menu)));
 			str_append(&help, "\n");
 		}
 	} else {

Modified: trunk/buildroot/package/config/menu.c
===================================================================
--- trunk/buildroot/package/config/menu.c	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/menu.c	2008-06-19 08:11:43 UTC (rev 22450)
@@ -417,3 +417,15 @@
 	return menu;
 }
 
+bool menu_has_help(struct menu *menu)
+{
+	return menu->help != NULL;
+}
+
+const char *menu_get_help(struct menu *menu)
+{
+	if (menu->help)
+		return menu->help;
+	else
+		return "";
+}

Modified: trunk/buildroot/package/config/qconf.cc
===================================================================
--- trunk/buildroot/package/config/qconf.cc	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/qconf.cc	2008-06-19 08:11:43 UTC (rev 22450)
@@ -1041,7 +1041,7 @@
 		if (showDebug())
 			debug = debug_info(sym);
 
-		help = print_filter(_(sym->help));
+		help = print_filter(_(menu_get_help(menu)));
 	} else if (menu->prompt) {
 		head += "<big><b>";
 		head += print_filter(_(menu->prompt->text));

Modified: trunk/buildroot/package/config/zconf.tab.c_shipped
===================================================================
--- trunk/buildroot/package/config/zconf.tab.c_shipped	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/zconf.tab.c_shipped	2008-06-19 08:11:43 UTC (rev 22450)
@@ -1722,7 +1722,7 @@
   case 83:
 
     {
-	current_entry->sym->help = (yyvsp[0].string);
+	current_entry->help = (yyvsp[0].string);
 ;}
     break;
 
@@ -2280,11 +2280,11 @@
 			break;
 		}
 	}
-	if (sym->help) {
-		int len = strlen(sym->help);
-		while (sym->help[--len] == '\n')
-			sym->help[len] = 0;
-		fprintf(out, "  help\n%s\n", sym->help);
+	if (menu->help) {
+		int len = strlen(menu->help);
+		while (menu->help[--len] == '\n')
+			menu->help[len] = 0;
+		fprintf(out, "  help\n%s\n", menu->help);
 	}
 	fputc('\n', out);
 }

Modified: trunk/buildroot/package/config/zconf.y
===================================================================
--- trunk/buildroot/package/config/zconf.y	2008-06-19 08:11:35 UTC (rev 22449)
+++ trunk/buildroot/package/config/zconf.y	2008-06-19 08:11:43 UTC (rev 22450)
@@ -402,7 +402,7 @@
 
 help: help_start T_HELPTEXT
 {
-	current_entry->sym->help = $2;
+	current_entry->help = $2;
 };
 
 /* depends option */
@@ -649,11 +649,11 @@
 			break;
 		}
 	}
-	if (sym->help) {
-		int len = strlen(sym->help);
-		while (sym->help[--len] == '\n')
-			sym->help[len] = 0;
-		fprintf(out, "  help\n%s\n", sym->help);
+	if (menu->help) {
+		int len = strlen(menu->help);
+		while (menu->help[--len] == '\n')
+			menu->help[len] = 0;
+		fprintf(out, "  help\n%s\n", menu->help);
 	}
 	fputc('\n', out);
 }

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot


Modified:
   trunk/buildroot/package/config/Makefile.kconfig
   trunk/buildroot/package/config/README.buildroot2
   trunk/buildroot/package/config/conf.c
   trunk/buildroot/package/config/confdata.c
   trunk/buildroot/package/config/kconfig-language.txt
   trunk/buildroot/package/config/kconfig-to-buildroot2.patch
   trunk/buildroot/package/config/lex.zconf.c_shipped
   trunk/buildroot/package/config/mconf.c
   trunk/buildroot/package/config/qconf.cc
   trunk/buildroot/package/config/util.c
   trunk/buildroot/package/config/zconf.gperf
   trunk/buildroot/package/config/zconf.hash.c_shipped
   trunk/buildroot/package/config/zconf.tab.c_shipped
   trunk/buildroot/package/config/zconf.y


Changeset:

Sorry, the patch is too large to include (4155 lines).
Please use ViewCVS to see it!

http://uclibc.org/cgi-bin/viewcvs.cgi?view=rev&root=svn&rev=22451

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot


Modified:
   trunk/buildroot/package/config/Makefile.kconfig
   trunk/buildroot/package/config/README.buildroot2
   trunk/buildroot/package/config/conf.c
   trunk/buildroot/package/config/confdata.c
   trunk/buildroot/package/config/kconfig-language.txt
   trunk/buildroot/package/config/kconfig-to-buildroot2.patch
   trunk/buildroot/package/config/lex.zconf.c_shipped
   trunk/buildroot/package/config/mconf.c
   trunk/buildroot/package/config/qconf.cc
   trunk/buildroot/package/config/util.c
   trunk/buildroot/package/config/zconf.gperf
   trunk/buildroot/package/config/zconf.hash.c_shipped
   trunk/buildroot/package/config/zconf.tab.c_shipped
   trunk/buildroot/package/config/zconf.y


Changeset:

Sorry, the patch is too large to include (4155 lines).
Please use ViewCVS to see it!

http://uclibc.org/cgi-bin/viewcvs.cgi?view=3Drev&root=3Dsvn&rev=3D22451
_______________________________________________
buildroot mailing list
buildroot at uclibc.org
http://busybox.net/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-04-23 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-04-23 14:39 UTC (permalink / raw)
  To: buildroot


Added:
   trunk/buildroot/package/config/check.sh


Changeset:
Added: trunk/buildroot/package/config/check.sh
===================================================================
--- trunk/buildroot/package/config/check.sh	                        (rev 0)
+++ trunk/buildroot/package/config/check.sh	2008-06-19 19:06:08 UTC (rev 22454)
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Needed for systems without gettext
+$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+#include <libintl.h>
+int main()
+{
+	gettext("");
+	return 0;
+}
+EOF
+if [ ! "$?" -eq "0"  ]; then
+	echo -DKBUILD_NO_NLS;
+fi
+


Property changes on: trunk/buildroot/package/config/check.sh
___________________________________________________________________
Name: svn:executable
   + *

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-07-14 13:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-07-14 13:16 UTC (permalink / raw)
  To: buildroot

make[1]: Entering directory
`/media/EkstraDisk/buildroot/build_i686/dnsmasq-2.41'
cd src && /usr/bin/make \
 DBUS_MINOR=" `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --modversion
dbus-1 | nawk -F . -- '{ if ($(NF-1)) print \"-DDBUS_MINOR=\"$(NF-1) }'`" 
\
 DBUS_CFLAGS="`echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --cflags
dbus-1`"  \
 DBUS_LIBS="  `echo -DNO_IPV6 | ../bld/pkg-wrapper pkg-config --libs
dbus-1`"  \
 SUNOS_LIBS=" `if uname | grep SunOS 2>&1 >/dev/null; then echo -lsocket
-lnsl -lposix4; fi `" \
 SUNOS_VER="  `if uname | grep SunOS 2>&1 >/dev/null; then uname -r | nawk
-F . -- '{ print \"-DSUNOS_VER=\"$2 }'; fi`" \
 -f ../bld/Makefile dnsmasq 
/bin/sh: line 1: nawk: command not found

Don't you have nawk installed? On my system, nawk is a link to gawk.

Seems like we don't currently check for awk in dependencies.sh, will fix 

---------------------------------------------------------------------- 
 jacmet - 06-18-08 06:17  
---------------------------------------------------------------------- 
I have now added an awk check to dependencies.sh and forced dnsmasq to use
awk rather than nawk, so closing issue. 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
06-14-08 17:01  KHAksnes       New Issue                                    
06-14-08 17:01  KHAksnes       Status                   new => assigned     
06-14-08 17:01  KHAksnes       Assigned To               => buildroot       
06-15-08 13:40  jacmet         Note Added: 0008264                          
06-15-08 14:07  KHAksnes       Note Added: 0008274                          
06-15-08 14:08  KHAksnes       File Added: compilelog                       
06-18-08 06:06  jacmet         Note Added: 0008384                          
06-18-08 06:17  jacmet         Status                   assigned => resolved
06-18-08 06:17  jacmet         Resolution               open => fixed       
06-18-08 06:17  jacmet         Note Added: 0008394                          
07-16-08 08:02  bernhardf      Status                   resolved => new     
07-17-08 03:39  bernhardf      Status                   new => closed       
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-07-14 13:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-07-14 13:16 UTC (permalink / raw)
  To: buildroot

PrBoom is a version of Doom using the Simple Direct Media
layer (SDL) library, which enables it to use XFree86, OpenGL,
Linux framebuffer console, GGI, SVGALib or even color or
monochrome text consoles as display. There is an additional
OpenGL renderer as well.
-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-07-14 13:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-07-14 13:16 UTC (permalink / raw)
  To: buildroot

ttymxc0 device. If so, then the reason why you cannot login is that
you don't have ttymxc0 listed in /etc/securetty.

The file comes from target/generic/target_skeleton/etc, but you can
simply edit it under project_build_arm/uclibc/root/etc and rerun make
to regenerate your filesystem image.

I don't see any mention of /dev/ttymxcN in Documentation/devices.txt
in the kernel sources? I take it that the serial driver isn't in the
mainline kernel?

 > THe other thing I tried to do was pass init=/dev/sh and
 > init=/dev/bash to try to get a direct shell prompt. I don't think
 > it was connecting to the MX31's serial port because I never saw any
 > outputs after the filesystem was mounted. Is there a recommended
 > way to force /dev/sh to appear on a ttyS0 (or actually ttymxc0 for
 > the MX31)

I take it you mean /bin/sh not /dev/sh?

Strange. And you do get output from init and login with the same
filesystem if you boot without init=/bin/sh?

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-07-14 13:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-07-14 13:16 UTC (permalink / raw)
  To: buildroot

Modified:
   trunk/buildroot/package/config/lex.zconf.c_shipped
   trunk/buildroot/package/config/zconf.l


Changeset:
Modified: trunk/buildroot/package/config/lex.zconf.c_shipped
===================================================================
--- trunk/buildroot/package/config/lex.zconf.c_shipped	2008-08-27 15:06:41 UTC (rev 23246)
+++ trunk/buildroot/package/config/lex.zconf.c_shipped	2008-08-27 20:18:33 UTC (rev 23247)
@@ -815,6 +815,11 @@
 void append_string(const char *str, int size)
 {
 	int new_size = text_size + size + 1;
+	if (size > 70) {
+		fprintf (stderr, "%s:%d warning: Overlong line\n",
+		current_file->name, current_file->lineno);
+	}
+
 	if (new_size > text_asize) {
 		new_size += START_STRSIZE - 1;
 		new_size &= -START_STRSIZE;

Modified: trunk/buildroot/package/config/zconf.l
===================================================================
--- trunk/buildroot/package/config/zconf.l	2008-08-27 15:06:41 UTC (rev 23246)
+++ trunk/buildroot/package/config/zconf.l	2008-08-27 20:18:33 UTC (rev 23247)
@@ -49,6 +49,10 @@
 void append_string(const char *str, int size)
 {
 	int new_size = text_size + size + 1;
+	if (size > 70) {
+	        fprintf (stderr, "%s:%d warning: Overlong line\n",
+			 current_file->name, current_file->lineno);
+	}
 	if (new_size > text_asize) {
 		new_size += START_STRSIZE - 1;
 		new_size &= -START_STRSIZE;

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-07-28  4:41 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-07-28  4:41 UTC (permalink / raw)
  To: ath9k-devel

Connectivtiy is lost after Group rekeying is done. The keytype
maintained by ath9k is reset when group key is updated. Though
sc_keytype can be reset only for broadcast key the proper fix
would be to use mac80211 provided key type from txinfo during
xmit and get rid of sc_keytype from ath9k ath_softc.

Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
---
 drivers/net/wireless/ath9k/core.h |    1 -
 drivers/net/wireless/ath9k/main.c |    3 ---
 drivers/net/wireless/ath9k/xmit.c |    6 +++---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k=
/core.h
index b66de29..e8ccbe4 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -976,7 +976,6 @@ struct ath_softc {
        u32 sc_keymax;          /* size of key cache */
        DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);  /* key use bit map */
        u8 sc_splitmic;         /* split TKIP MIC keys */
-       int sc_keytype;

        /* RX */
        struct list_head sc_rxbuf;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k=
/main.c
index 1ba1800..aca893a 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -204,8 +204,6 @@ static int ath_key_config(struct ath_softc *sc,
        if (!ret)
                return -EIO;

-       if (mac)
-               sc->sc_keytype =3D hk.kv_type;
        return 0;
 }

@@ -1507,7 +1505,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
        case DISABLE_KEY:
                ath_key_delete(sc, key);
                clear_bit(key->keyidx, sc->sc_keymap);
-               sc->sc_keytype =3D ATH9K_CIPHER_CLR;
                break;
        default:
                ret =3D -EINVAL;
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k=
/xmit.c
index 3fc6641..2592905 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -239,11 +239,11 @@ static int ath_tx_prepare(struct ath_softc *sc,
                txctl->keyix =3D tx_info->control.hw_key->hw_key_idx;
                txctl->frmlen +=3D tx_info->control.icv_len;

-               if (sc->sc_keytype =3D=3D ATH9K_CIPHER_WEP)
+               if (tx_info->control.hw_key->alg =3D=3D ALG_WEP)
                        txctl->keytype =3D ATH9K_KEY_TYPE_WEP;
-               else if (sc->sc_keytype =3D=3D ATH9K_CIPHER_TKIP)
+               else if (tx_info->control.hw_key->alg =3D=3D ALG_TKIP)
                        txctl->keytype =3D ATH9K_KEY_TYPE_TKIP;
-               else if (sc->sc_keytype =3D=3D ATH9K_CIPHER_AES_CCM)
+               else if (tx_info->control.hw_key->alg =3D=3D ALG_CCMP)
                        txctl->keytype =3D ATH9K_KEY_TYPE_AES;
        }

--
1.5.5



--opJtzjQTFsWo+cga
Content-Type: text/x-diff; charset="us-ascii"
Content-Disposition: attachment; filename="connectivity.patch"

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2008-09-15 17:22 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-09-15 17:22 UTC (permalink / raw)
  To: buildroot

>>>>>>>
And add uClibc-0.9.29-cygwin_host_loadlibes.patch
for solved identical problem during build uClibc 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
10-24-07 08:28  AndyI          New Issue                                    
10-24-07 08:28  AndyI          Status                   new => assigned     
10-24-07 08:28  AndyI          Assigned To               => buildroot       
10-24-07 08:28  AndyI          File Added: fix_cygwin_HOST_LOADLIBES.patch      
             
10-24-07 08:28  AndyI          File Added:
uClibc-0.9.29-cygwin_host_loadlibes.patch                    
10-24-07 08:29  AndyI          Issue Monitored: AndyI                       
09-17-08 05:42  AndyI          Note Added: 0011544                          
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-09-15 17:22 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-09-15 17:22 UTC (permalink / raw)
  To: buildroot

>>>>>>>
And add uClibc-0.9.29-cygwin_host_loadlibes.patch
for solved identical problem during build uClibc 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
10-24-07 08:28  AndyI          New Issue                                    
10-24-07 08:28  AndyI          Status                   new => assigned     
10-24-07 08:28  AndyI          Assigned To               => buildroot       
10-24-07 08:28  AndyI          File Added: fix_cygwin_HOST_LOADLIBES.patch      
             
10-24-07 08:28  AndyI          File Added:
uClibc-0.9.29-cygwin_host_loadlibes.patch                    
10-24-07 08:29  AndyI          Issue Monitored: AndyI                       
09-17-08 05:42  AndyI          Note Added: 0011544                          
09-17-08 06:30  bernhardf      Status                   assigned => closed  
======================================================================

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel

how can i else monitor the problem?

On Mon, 13 Oct 2008 15:14:37 -0700
"Luis R. Rodriguez" <mcgrof@gmail.com> wrote:

> On Sat, Oct 11, 2008 at 6:46 AM, Alexander Petukhov <al_petukhov@mail.ru> wrote:
> > Hello,
> >
> > first of all - many thanks to you guys for developing this driver!
> > i'm owning D-Link DWA-547 card (Atheros Communications Inc. AR5416 802.11abgn Wireless PCI Adapter (rev 01)), and i'm on Debian Lenny\Sid.
> > My current kernel is 2.6.27 released not long ago, and i have one problem - connection periodicly losts, i.e. i can't even ping router i'm associated with. After some time (5-40 seconds) all becomes fine again. This happents one time for an hour or so on. Interface is not down when this problem occures, gnome applet shows it is up and have a normal(~90%) signal strength. Now i'm using wpa on router and wpasupplicant package on debian box(without any network-managers), but this still happents even without any encryption used.
> > Would be glad to help in testing.
> 
> Can you do this:
> 
> sudo dmesg -c > /dev/null
> 
> Then connect to the AP, every now and then do this:
> 
> sudo dmesg -c | tee log
> 
> Keep doing this routinely, it'll keep overwriting the data from the
> kernel ring buffer to the log but you will also be able to see it on
> the screen. Once you see the strange disconnect issue appear please
> play more careful attention to what comes up and send us the log. To
> be safe you can just use 'tee -a' to append to the log all the
> information.
> 
> Anyway please send us the log.
> 
>   Luis
> 


-- 
Best regards,
Alexander Petukhov <al_petukhov@mail.ru>

--Multipart=_Wed__15_Oct_2008_01_31_40_+0400_4IyuS81Mmz9KfB9=
Content-Type: application/octet-stream;
 name="log"
Content-Disposition: attachment;
 filename="log"
Content-Transfer-Encoding: base64

WzEzNzIxLjMxNjg1Ml0gd2xhbjA6IGF1dGhlbnRpY2F0ZSB3aXRoIEFQIDAwOjIxOjkxOjA5OmY5
OjNiClsxMzcyMS4zMTgyODJdIHdsYW4wOiBhdXRoZW50aWNhdGVkClsxMzcyMS4zMTgzMjJdIHds
YW4wOiBhc3NvY2lhdGUgd2l0aCBBUCAwMDoyMTo5MTowOTpmOTozYgpbMTM3MjEuMzIxODU5XSB3
bGFuMDogUlggQXNzb2NSZXNwIGZyb20gMDA6MjE6OTE6MDk6Zjk6M2IgKGNhcGFiPTB4NDMxIHN0
YXR1cz0wIGFpZD0xKQpbMTM3MjEuMzIxODk3XSB3bGFuMDogYXNzb2NpYXRlZApbMTM3MjEuMzIy
MDgzXSB3bGFuMCAoV0UpIDogV2lyZWxlc3MgRXZlbnQgdG9vIGJpZyAoMzIwKQpbMTk0MjQuNDc3
OTU5XSBzZCA0OjA6MDowOiBbc2RhXSAxMDAzNTIwIDUxMi1ieXRlIGhhcmR3YXJlIHNlY3RvcnMg
KDUxNCBNQikKWzE5NDI0LjQ3ODgzMV0gc2QgNDowOjA6MDogW3NkYV0gV3JpdGUgUHJvdGVjdCBp
cyBvZmYKWzE5NDI0LjQ3ODgzNF0gc2QgNDowOjA6MDogW3NkYV0gTW9kZSBTZW5zZTogMDMgMDAg
MDAgMDAKWzE5NDI0LjQ3ODgzNV0gc2QgNDowOjA6MDogW3NkYV0gQXNzdW1pbmcgZHJpdmUgY2Fj
aGU6IHdyaXRlIHRocm91Z2gKWzE5NDI0LjQ3OTcwMF0gc2QgNDowOjA6MDogW3NkYV0gMTAwMzUy
MCA1MTItYnl0ZSBoYXJkd2FyZSBzZWN0b3JzICg1MTQgTUIpClsxOTQyNC40ODA3MDBdIHNkIDQ6
MDowOjA6IFtzZGFdIFdyaXRlIFByb3RlY3QgaXMgb2ZmClsxOTQyNC40ODA3MDJdIHNkIDQ6MDow
OjA6IFtzZGFdIE1vZGUgU2Vuc2U6IDAzIDAwIDAwIDAwClsxOTQyNC40ODA3MDRdIHNkIDQ6MDow
OjA6IFtzZGFdIEFzc3VtaW5nIGRyaXZlIGNhY2hlOiB3cml0ZSB0aHJvdWdoClsxOTQyNC40ODA3
MDVdICBzZGE6IHNkYTEKWzE5NDI0Ljg1Njc4Nl0gRkFUOiB1dGY4IGlzIG5vdCBhIHJlY29tbWVu
ZGVkIElPIGNoYXJzZXQgZm9yIEZBVCBmaWxlc3lzdGVtcywgZmlsZXN5c3RlbSB3aWxsIGJlIGNh
c2Ugc2Vuc2l0aXZlIQpbMTk1MjguMDE4MDczXSBCdWZmZXIgSS9PIGVycm9yIG9uIGRldmljZSBz
ZGExLCBsb2dpY2FsIGJsb2NrIDUyMwpbMTk1MjguMDE4MDc3XSBsb3N0IHBhZ2Ugd3JpdGUgZHVl
IHRvIEkvTyBlcnJvciBvbiBzZGExClsxOTUyOC4wMTgwNzldIEJ1ZmZlciBJL08gZXJyb3Igb24g
ZGV2aWNlIHNkYTEsIGxvZ2ljYWwgYmxvY2sgNTI0ClsxOTUyOC4wMTgwODBdIGxvc3QgcGFnZSB3
cml0ZSBkdWUgdG8gSS9PIGVycm9yIG9uIHNkYTEKWzE5NTI4LjAxODA4Ml0gQnVmZmVyIEkvTyBl
cnJvciBvbiBkZXZpY2Ugc2RhMSwgbG9naWNhbCBibG9jayA1MjUKWzE5NTI4LjAxODA4M10gbG9z
dCBwYWdlIHdyaXRlIGR1ZSB0byBJL08gZXJyb3Igb24gc2RhMQpbMTk1MjguMDE4MDg0XSBCdWZm
ZXIgSS9PIGVycm9yIG9uIGRldmljZSBzZGExLCBsb2dpY2FsIGJsb2NrIDUyNgpbMTk1MjguMDE4
MDg2XSBsb3N0IHBhZ2Ugd3JpdGUgZHVlIHRvIEkvTyBlcnJvciBvbiBzZGExClsxOTUyOC4wMTgw
ODddIEJ1ZmZlciBJL08gZXJyb3Igb24gZGV2aWNlIHNkYTEsIGxvZ2ljYWwgYmxvY2sgNTI3Clsx
OTUyOC4wMTgwODhdIGxvc3QgcGFnZSB3cml0ZSBkdWUgdG8gSS9PIGVycm9yIG9uIHNkYTEKWzE5
NTI4LjAxODA5MV0gQnVmZmVyIEkvTyBlcnJvciBvbiBkZXZpY2Ugc2RhMSwgbG9naWNhbCBibG9j
ayA1MjgKWzE5NTI4LjAxODA5Ml0gbG9zdCBwYWdlIHdyaXRlIGR1ZSB0byBJL08gZXJyb3Igb24g
c2RhMQpbMTk1MjguMDE4MDk0XSBCdWZmZXIgSS9PIGVycm9yIG9uIGRldmljZSBzZGExLCBsb2dp
Y2FsIGJsb2NrIDUyOQpbMTk1MjguMDE4MDk1XSBsb3N0IHBhZ2Ugd3JpdGUgZHVlIHRvIEkvTyBl
cnJvciBvbiBzZGExClsxOTUyOC4wMTgwOTZdIEJ1ZmZlciBJL08gZXJyb3Igb24gZGV2aWNlIHNk
YTEsIGxvZ2ljYWwgYmxvY2sgNTMwClsxOTUyOC4wMTgwOTddIGxvc3QgcGFnZSB3cml0ZSBkdWUg
dG8gSS9PIGVycm9yIG9uIHNkYTEK

--Multipart=_Wed__15_Oct_2008_01_31_40_+0400_4IyuS81Mmz9KfB9=--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-14 11:50 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-14 11:50 UTC (permalink / raw)
  To: ath9k-devel

computer) I get a stable stream at >4MBps.

Eirik

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-23 17:17 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-23 17:17 UTC (permalink / raw)
  To: buildroot

config BR2_TARGET_ROOTFS_EXT2_BLOCKS
        int "size in blocks (leave at 0 for auto calculation)"
        depends on BR2_TARGET_ROOTFS_EXT2
        default 0

config BR2_TARGET_ROOTFS_EXT2_INODES
        int "inodes (leave at 0 for auto calculation)"
        depends on BR2_TARGET_ROOTFS_EXT2
        default 0

 Adam> Strangely, when I mount/chroot into one of the pre-built root
 Adam> filesystems available from the uclibc website, I can create files
 Adam> without any problems.

The really old ones? They were afaik padded to 128MB.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-23 17:17 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-23 17:17 UTC (permalink / raw)
  To: buildroot

at91sam9260ek		MACH_AT91SAM9260EK	AT91SAM9260EK
1099

It appears you have the 9G20 suppost in u-boot but still have a kernel
for the 9260.

Hartley

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-10-23 17:17 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-10-23 17:17 UTC (permalink / raw)
  To: buildroot

build 3.7x, so I have so far just fixed the 3.61 URL.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-11-21  1:22 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-11-21  1:22 UTC (permalink / raw)
  To: buildroot

	DEPMOD=$(STAGING_DIR)/bin/$(GNU_TARGET_NAME)-depmod26

And 4 lines further down this is even used directly.
This tool is pulled through this dependency:

linux26-modules: cross-depmod26 $(LINUX26_DIR)/.modules_installed

And this cross-depmod26 is provided by module-init-tools.


Nicolas

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2008-12-07 21:22 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2008-12-07 21:22 UTC (permalink / raw)
  To: buildroot

Author: ulf <ulf@69ca8d6d-28ef-0310-b511-8ec308f3f277>
Date:   Thu Aug 16 21:54:48 2007 +0000

    Add further documentation for BSP patch

I'm also not completely happy about that section.

 Thomas> Is the author of this section on the list ? If so, could he
 Thomas> mention what the intention was ?

He posted on the list a few days ago.

--=20
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-01-04 17:33 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-01-04 17:33 UTC (permalink / raw)
  To: ath9k-devel

---------------------------------------------------------------------------=
------------------------
Reason Meaning
0	Reserved
1	Unspecified reason
2	Previous authentication no longer valid
3	Deauthenticated because sending STA is leaving (or has left) IBSS or ESS
4	Disassociated due to inactivity
5	Disassociated because AP is unable to handle all currently associated STA=
s
6	Class 2 frame received from nonauthenticated STA
7	Class 3 frame received from nonassociated STA
8	Disassociated because sending STA is leaving (or has left) BSS
9	STA requesting (re)association is not authenticated with responding STA
10	Disassociated because the information in the Power Capability element is=
 unacceptable
11	Disassociated because the information in the Supported Channels element =
is unacceptable
12	Reserved
13	Invalid information element, i.e., an information element defined in thi=
s standard for
	which the content does not meet the specifications in Clause 7
14	Message integrity code (MIC) failure
15	4-Way Handshake timeout
16	Group Key Handshake timeout
17	Information element in 4-Way Handshake different from (Re)Association Re=
quest/Probe
	Response/Beacon frame
18	Invalid group cipher
19	Invalid pairwise cipher
20	Invalid AKMP
21	Unsupported RSN information element version
22	Invalid RSN information element capabilities
23	IEEE 802.1X authentication failed
24	Cipher suite rejected because of the security policy
25=E2=80=9331	Reserved
32	Disassociated for unspecified, QoS-related reason
33	Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA
34	Disassociated because excessive number of frames need to be acknowledged=
, but are not
	acknowledged due to AP transmissions and/or poor channel conditions
35	Disassociated because STA is transmitting outside the limits of its TXOP=
s
36	Requested from peer STA as the STA is leaving the BSS (or resetting)
37	Requested from peer STA as it does not want to use the mechanism
38	Requested from peer STA as the STA received frames using the mechanism f=
or which a
	setup is required
39	Requested from peer STA due to timeout
45	Peer STA does not support the requested cipher suite
46=E2=80=9365	Reserved
535	Reserved
---------------------------------------------------------------------------=
------------------------

> Jan 30 23:31:37 ws1 dhcpcd[23630]: wlan0: carrier lost
> Jan 30 23:31:37 ws1 wpa_cli: interface wlan0 DISCONNECTED
> Jan 30 23:31:38 ws1 [ 9444.502016] wlan0: associate with AP f51a5ea8
> Jan 30 23:31:38 ws1 dhcpcd[23630]: wlan0: received SIGTERM, stopping
> Jan 30 23:31:38 ws1 [ 9444.703019] wlan0: associate with AP f51a5ea8
> Jan 30 23:31:38 ws1 [ 9444.902015] wlan0: associate with AP f51a5ea8
> Jan 30 23:31:39 ws1 [ 9445.102013] wlan0: association with AP f51a5ea8 ti=
med out
> Jan 30 23:31:40 ws1 [ 9445.990865] wlan0: authenticate with AP f51a5ea8
> Jan 30 23:31:40 ws1 [ 9445.998616] wlan0: authenticate with AP f51a5ea8
> Jan 30 23:31:40 ws1 [ 9446.000416] wlan0: authenticated
> Jan 30 23:31:40 ws1 [ 9446.000421] wlan0: associate with AP f51a5ea8
> Jan 30 23:31:40 ws1 [ 9446.003209] wlan0: RX AssocResp from f029002a (cap=
ab=3D0x411 status=3D0 aid=3D2)
> Jan 30 23:31:40 ws1 [ 9446.003214] wlan0: associated
> Jan 30 23:31:40 ws1 wpa_cli: interface wlan0 CONNECTED
> Jan 30 23:31:41 ws1 dhcpcd[24556]: wlan0: dhcpcd 4.0.7 starting
> Jan 30 23:31:41 ws1 dhcpcd[24556]: wlan0: broadcasting for a lease
> Jan 30 23:31:42 ws1 dhcpcd[24556]: wlan0: offered 192.168.1.100 from 192.=
168.1.1
> Jan 30 23:31:42 ws1 dhcpcd[24556]: wlan0: checking 192.168.1.100 is avail=
able on attached networks
> Jan 30 23:31:47 ws1 dhcpcd[24556]: wlan0: acknowledged 192.168.1.100 from=
 192.168.1.1

Yeap everything looks good except your AP doesn't seem to like you to be id=
le
for more than 8 minutes, that is if no traffic was going on in between your
dhcp negotiation and your disassoc.

> Used Hardware :
> My Router: Linksys WRT 160v2 Standard: 80211N. maybe a broadcom Chip
> My Wlan Card: Linksys WMP 300N v2 Standard: 80211N. AR5416 Chip
>=20
> But at all it works. Today i have set the router that he only uses the 80=
211N Standard and it works with my Wireless Card.

I don't see any issues above. Please see:

http://wireless.kernel.org/en/users/Documentation/Reporting_bugs

> !!!!!!!!!!!!!!Big Thanks for your great drivers and packages!!!!!!!!!!!!!=
!
>=20
> Well night
>=20
> kind regards
>=20
> Alexander Bartha

  Luis

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-01-04 17:33 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-01-04 17:33 UTC (permalink / raw)
  To: ath9k-devel

802.11n chips. Is any one has ath9k or similar driver for linux 2.6.21? I
saw the ath9k driver in 2.6.28. It is higly dependent on linux 2.6.28
kernel. Anyone has PCI/PCIe driver supporting any 802.11n chips for 2.6.21?

any sugestions welcome!!

thanks,
MB.

--000e0cd15718164b2c0462176409
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>Hi All,</div>
<div>&nbsp;</div>
<div>From Linux 2.6.28 onwards ath9k driver is part of the linux and suppor=
ts 802.11n chips. Is any one has ath9k or similar driver for linux 2.6.21? =
I saw the ath9k driver in 2.6.28. It is higly dependent on linux 2.6.28 ker=
nel. Anyone has PCI/PCIe driver supporting any 802.11n chips for 2.6.21?</d=
iv>

<div>&nbsp;</div>
<div>any sugestions welcome!!</div>
<div>&nbsp;</div>
<div>thanks,</div>
<div>MB.</div>

--000e0cd15718164b2c0462176409--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-15  8:49 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-15  8:49 UTC (permalink / raw)
  To: ath9k-devel

am not sure if this is related to AP mode in ath9k.

Sujith

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

wlan0: STA 00:23:4d:b7:98:e8 IEEE 802.11: authenticated
MGMT
mgmt::assoc_req
association request: STA=00:23:4d:b7:98:e8 capab_info=0x431 listen_interval=10
handle_assoc STA 00:23:4d:b7:98:e8 - no HT, num of non-HT stations 1
hostapd_ht_operation_update current operation mode=0x0
hostapd_ht_operation_update new operation mode=0x13 changes=2
  new AID 1
wlan0: STA 00:23:4d:b7:98:e8 IEEE 802.11: association OK (aid 1)

This is weird, since it chooses non-HT mode for the STA.
Am not sure why this is happening. Are you running the latest git
code for all 3 cases ?

* hostapd
* ath9k - AP side
* ath9k - STA side

Also, can you paste your hostapd.conf and wpa_supplicant's configuration file here ?

Sujith

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

required. You can think of my previous phrase as possible feature
request, or a question of "how to?" type. I know that borh SLI nvidia
cards are sharing IRQ 16 as well as atheros based dlink wireless card.
(if it's not difficult, please look into my previous emails, they will
have dmesg and lspci -vv details, otherwise just ask me for more
details, i shall provide them)
>>  Obviously, there is not much point of asking Nvidia to do it, since
>> those behemoth's won't do anything for sure, since their current driver
>> (i dont use it for that matter)release is pretty banged up...
>>     
>
> If you do most of the work finding how to work around the problem, and
> it turns out that something could be improved in free software, then
> maybe your patch will be applied.
>
> If you expect others to question you about the symptoms, then suggest
> patches and push them to the kernel, that's not going to happen.
>   
Symptoms are simple with nvidia module and ath9k loaded at the same time
connection degrades over short period of time and after several minutes
disappears all together. I suspect it could be IRQ sharing or other I/O
or similar hardware conflict, since both of them work pretty well while
other devices driver is not loaded. no unusual messages in dmesg.
Machine may hang and even if in terminal(not in X), machine hangs
completely without providing a bit of information, not even oops message.
>   
>> Another question, my Access Point and PCI wifi card are from same
>> manufacturer. AP is set to B,G,N auto mode, but my card only connects to
>> it using G mode, which is not why i bought it in the first place. Why is
>> this happening? i am pretty much only user to network myself 99% of
>> time. i tried to force it to use N mode, it could detect it, but it
>> couldn't connect.
>>     
>
> I suggest that you actually show what commands you run and what they
> return, not just your interpretation.
>
> In case you are hitting the stuck scan bug, try setting the channel with
> iwconfig instead of loading and unloading modules.
>
>   
Commands are simple as well.
ip link set wlan0 up
iwconfig wlan0 essid dlink
they don't give any errors and don't show any unusual messages in dmesg

thats pretty much it. (no wireless security used at all)

N.B.
What i really don't want is any kind of aggression towards to me.
Coding something for a community, even advanced one requires certain
amount of tolerance, as ANY normal communication.
I am not perfect tester(i just attempt to become better one), i
understand that, but i am not coming after difficult day, working with
difficult people to submit difficult issues(which other people may
prefer to ignore all together or for those reasons abandon Linux and go
to MS products, i have seeing enough of those). I am not going to become
more enthusiastic by being referred to "RTFM noob" like documents, who
nearly imply my stupidity.
So far I was very happy in this list, and even my lack of technical
knowledge did not spoil my attitude towards this list. I want it to stay
that way. Ignoring problems of people who lack technical knowledge on
matter is path to nowhere. I seriously, don't want to start flame wars,
i am not naive and I don't ask for apologies. I just ask one thing,
please be tolerant, everyone can have a shi*** day, that includes you
and me!

Dmitri

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

rev. 2.1 now), a single function device may _only_ provide an interrupt
request on pin A and no others.  Pins B-D only have meaning for multi-
function devices.

> > There seems to be some kind of race.  If I have both the AR5416 and 
> > HPT371N, loaded, and after the board has booted(everything is 
> > configured), the "IRQ X  Nobody cared" never occurs.   If i remove 
> > AR5416 mini-pci,  I also never get the "IRQ X  Nobody cared".
> 
> You would have to investigate a) which chip generates the bogus IRQ,
> and b) how to clear it. Then you can clear the IRQ in the platform code,
> or using a PCI quirk code if it's not related to the platform.

It sounds to me like the driver is prodding the chip, and it's generating
an interrupt but the driver hasn't yet registered its handler.  If so,
that's really a driver bug needing to be fixed.

Normally you get a backtrace when a "nobody cared" message is issued -
this should tell you which driver is probably the cause.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

(usually link quality warries between 60-70)


Machine started to suffer with disconnects.

Below is fuller log.
1249488753.366831: wlan0 (phy #0): deauth 00:22:b0:bc:1e:1e ->
00:1e:58:b4:f6:83 reason 4: Disassociated due to inactivity
1249488753.366985: wlan0 (phy #0): disconnected (local request)
1249488848.660029: wlan0 (phy #0): auth 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249488848.668387: wlan0 (phy #0): assoc 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249488848.668489: wlan0 (phy #0): connected to 00:1e:58:b4:f6:83
1249488918.365949: wlan0 (phy #0): deauth 00:22:b0:bc:1e:1e ->
00:1e:58:b4:f6:83 reason 4: Disassociated due to inactivity
1249488918.365996: wlan0 (phy #0): disconnected (local request)
1249489968.542997: wlan0 (phy #0): auth 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249489968.551472: wlan0 (phy #0): assoc 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249489968.551576: wlan0 (phy #0): connected to 00:1e:58:b4:f6:83
1249489985.366774: wlan0 (phy #0): deauth 00:22:b0:bc:1e:1e ->
00:1e:58:b4:f6:83 reason 4: Disassociated due to inactivity
1249489985.366850: wlan0 (phy #0): disconnected (local request)
1249490017.023313: wlan0 (phy #0): auth 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249490017.031578: wlan0 (phy #0): assoc 00:1e:58:b4:f6:83 ->
00:22:b0:bc:1e:1e status: 0: Successful
1249490017.031616: wlan0 (phy #0): connected to 00:1e:58:b4:f6:83
1249490039.365052: wlan0 (phy #0): deauth 00:22:b0:bc:1e:1e ->
00:1e:58:b4:f6:83 reason 4: Disassociated due to inactivity
1249490039.365096: wlan0 (phy #0): disconnected (local request)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

  // ?? nice pointer arithmetic... should use PTR_ALIGN here?
  off = ((unsigned long) skb->data) % sc->cachelsz;
  if (off != 0)
      skb_reserve(skb, sc->cachelsz);

in other words, when we allocate, round up to the next cache line
greater than IEEE80211_MAX_LEN, then add an extra cache_line-1
bytes so we can map starting from it.

dev_alloc_skb already does some padding and alignment, and it's
configurable on a per-arch basis (though looks like only powerpc
sets it to L1 cache size, everywhere else it's 32 bytes.)

I guess if someone is bored some benchmarking would be useful.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

is=20
yet, but I wonder if anyone else has solved this with a vendor extension?

--=20
Tim Smith <Tim.Smith@csr.com>


Member of the CSR plc group of companies. CSR plc registered in England and=
 Wales, registered number 4187346, registered office Churchill House, Cambr=
idge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-02-27 19:01 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2009-02-27 19:01 UTC (permalink / raw)
  To: ath9k-devel

should be automagically functional on the kernel I'm on, assuming the
hardware is compatible?

So that's where I stand now. I'm probably not asking the right
questions or providing enough information - please let me know any
tests you'd like me to run or further information I can give.

Thanks!

Andrew

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-08-25 10:34 Syed Rafiuddin
  0 siblings, 0 replies; 409+ messages in thread
From: Syed Rafiuddin @ 2009-08-25 10:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Syed Rafiuddin <rafiuddin.syed@ti.com>

This patch Adds Keypad support on OMAP4.And adds
OMAP4 register addresses and configures them for OMAP4.


This patch has been updated as per the comments received from
Trilok Soni to remove GPIO based omap2 keypad logic from omap_keypad.c
(http://www.mail-archive.com/linux-omap at vger.kernel.org/msg14570.html)
Matrix_keypad.c (gpio based keypad driver) can be used in OMAP2,
which is not tested on OMAP2 since unavailability of omap2 target's.


Signed-off-by: Syed Rafiuddin <rafiuddin.syed@ti.com>
---
 drivers/input/keyboard/omap-keypad.c |  247 ++++++++++++++++-------------------
 1 files changed, 115 insertions(+), 132 deletions(-)

Index: kernel-omap4-base/drivers/input/keyboard/omap-keypad.c
===================================================================
--- kernel-omap4-base.orig/drivers/input/keyboard/omap-keypad.c	2009-08-19 12:23:14.000000000 +0530
+++ kernel-omap4-base/drivers/input/keyboard/omap-keypad.c	2009-08-19 18:25:17.000000000 +0530
@@ -44,6 +44,36 @@

 #undef NEW_BOARD_LEARNING_MODE

+#define OMAP4_KBDOCP_BASE              0x4A31C000
+#define OMAP4_KBD_REVISION             0x00
+#define OMAP4_KBD_SYSCONFIG            0x10
+#define OMAP4_KBD_SYSSTATUS            0x14
+#define OMAP4_KBD_IRQSTATUS            0x18
+#define OMAP4_KBD_IRQENABLE            0x1C
+#define OMAP4_KBD_WAKEUPENABLE         0x20
+#define OMAP4_KBD_PENDING              0x24
+#define OMAP4_KBD_CTRL                 0x28
+#define OMAP4_KBD_DEBOUNCINGTIME       0x2C
+#define OMAP4_KBD_LONGKEYTIME          0x30
+#define OMAP4_KBD_TIMEOUT              0x34
+#define OMAP4_KBD_STATEMACHINE         0x38
+#define OMAP4_KBD_ROWINPUTS            0x3C
+#define OMAP4_KBD_COLUMNOUTPUTS                0x40
+#define OMAP4_KBD_FULLCODE31_0         0x44
+#define OMAP4_KBD_FULLCODE63_32                0x48
+
+#define OMAP4_KBD_SYSCONFIG_SOFTRST    (1 << 1)
+#define OMAP4_KBD_SYSCONFIG_ENAWKUP    (1 << 2)
+#define OMAP4_KBD_IRQENABLE_EVENTEN    (1 << 0)
+#define OMAP4_KBD_IRQENABLE_LONGKEY    (1 << 1)
+#define OMAP4_KBD_IRQENABLE_TIMEOUTEN  (1 << 2)
+#define OMAP4_KBD_CTRL_NOSOFTMODE      (1 << 1)
+#define OMAP4_KBD_CTRLPTVVALUE         (1 << 2)
+#define OMAP4_KBD_CTRLPTV              (1 << 1)
+#define OMAP4_KBD_IRQDISABLE           0x00
+
+#define OMAP4_KBD_IRQSTATUSDISABLE     0xffff
+
 static void omap_kp_tasklet(unsigned long);
 static void omap_kp_timer(unsigned long);

@@ -65,55 +95,16 @@ struct omap_kp {
 static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);

 static int *keymap;
-static unsigned int *row_gpios;
-static unsigned int *col_gpios;
-
-#ifdef CONFIG_ARCH_OMAP2
-static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
-{
-	int col;
-
-	for (col = 0; col < omap_kp->cols; col++)
-		gpio_set_value(col_gpios[col], value & (1 << col));
-}
-
-static u8 get_row_gpio_val(struct omap_kp *omap_kp)
-{
-	int row;
-	u8 value = 0;
-
-	for (row = 0; row < omap_kp->rows; row++) {
-		if (gpio_get_value(row_gpios[row]))
-			value |= (1 << row);
-	}
-	return value;
-}
-#else
-#define		set_col_gpio_val(x, y)	do {} while (0)
-#define		get_row_gpio_val(x)	0
-#endif

 static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
 {
-	struct omap_kp *omap_kp = dev_id;
+	if (cpu_is_omap44xx()) {
+		/* disable keyboard interrupt and schedule for handling */
+		omap_writel(OMAP4_KBD_IRQDISABLE, OMAP4_KBDOCP_BASE +
+			OMAP4_KBD_IRQENABLE);

-	/* disable keyboard interrupt and schedule for handling */
-	if (cpu_is_omap24xx()) {
-		int i;
-
-		for (i = 0; i < omap_kp->rows; i++) {
-			int gpio_irq = gpio_to_irq(row_gpios[i]);
-			/*
-			 * The interrupt which we're currently handling should
-			 * be disabled _nosync() to avoid deadlocks waiting
-			 * for this handler to complete.  All others should
-			 * be disabled the regular way for SMP safety.
-			 */
-			if (gpio_irq == irq)
-				disable_irq_nosync(gpio_irq);
-			else
-				disable_irq(gpio_irq);
-		}
+		omap_writel(omap_readl(OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS),
+			OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS);
 	} else
 		/* disable keyboard interrupt and schedule for handling */
 		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
@@ -132,14 +123,13 @@ static void omap_kp_scan_keypad(struct o
 {
 	int col = 0;

+	u32 *p = (u32 *) state;
 	/* read the keypad status */
-	if (cpu_is_omap24xx()) {
-		/* read the keypad status */
-		for (col = 0; col < omap_kp->cols; col++) {
-			set_col_gpio_val(omap_kp, ~(1 << col));
-			state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff;
-		}
-		set_col_gpio_val(omap_kp, 0);
+	if (cpu_is_omap44xx()) {
+
+		*p = omap_readl(OMAP4_KBDOCP_BASE + OMAP4_KBD_FULLCODE31_0);
+		*(p + 1) = omap_readl(OMAP4_KBDOCP_BASE +
+					OMAP4_KBD_FULLCODE63_32);

 	} else {
 		/* disable keyboard interrupt and schedule for handling */
@@ -198,7 +188,13 @@ static void omap_kp_tasklet(unsigned lon
 			       row, (new_state[col] & (1 << row)) ?
 			       "pressed" : "released");
 #else
-			key = omap_kp_find_key(col, row);
+
+			/* Keymappings have changed in omap4.*/
+			if (cpu_is_omap44xx())
+				key = omap_kp_find_key(row, col);
+			else
+				key = omap_kp_find_key(col, row);
+
 			if (key < 0) {
 				printk(KERN_WARNING
 				      "omap-keypad: Spurious key event %d-%d\n",
@@ -213,8 +209,16 @@ static void omap_kp_tasklet(unsigned lon
 				continue;

 			kp_cur_group = key & GROUP_MASK;
-			input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
-					 new_state[col] & (1 << row));
+
+			if (cpu_is_omap44xx())
+				input_report_key(omap_kp_data->input,
+					key & ~GROUP_MASK, new_state[row]
+						& (1 << col));
+			else
+				input_report_key(omap_kp_data->input,
+					key & ~GROUP_MASK, new_state[col]
+						& (1 << row));
+
 #endif
 		}
 	}
@@ -229,14 +233,18 @@ static void omap_kp_tasklet(unsigned lon
 		mod_timer(&omap_kp_data->timer, jiffies + delay);
 	} else {
 		/* enable interrupts */
-		if (cpu_is_omap24xx()) {
-			int i;
-			for (i = 0; i < omap_kp_data->rows; i++)
-				enable_irq(gpio_to_irq(row_gpios[i]));
-		} else {
-			omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		if (cpu_is_omap44xx()) {
+			omap_writew(OMAP4_KBD_IRQENABLE_EVENTEN |
+				OMAP4_KBD_IRQENABLE_LONGKEY,
+					OMAP4_KBDOCP_BASE +
+					OMAP4_KBD_IRQENABLE);
 			kp_cur_group = -1;
-		}
+		} else {
+			omap_writew(0, OMAP_MPUIO_BASE +
+				OMAP_MPUIO_KBD_MASKIT);
+				kp_cur_group = -1;
+			}
+
 	}
 }

@@ -296,7 +304,7 @@ static int __devinit omap_kp_probe(struc
 	struct omap_kp *omap_kp;
 	struct input_dev *input_dev;
 	struct omap_kp_platform_data *pdata =  pdev->dev.platform_data;
-	int i, col_idx, row_idx, irq_idx, ret;
+	int i, col_idx, row_idx, ret;

 	if (!pdata->rows || !pdata->cols || !pdata->keymap) {
 		printk(KERN_ERR "No rows, cols or keymap from pdata\n");
@@ -316,7 +324,7 @@ static int __devinit omap_kp_probe(struc
 	omap_kp->input = input_dev;

 	/* Disable the interrupt for the MPUIO keyboard */
-	if (!cpu_is_omap24xx())
+	if (!cpu_is_omap44xx())
 		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);

 	keymap = pdata->keymap;
@@ -327,39 +335,11 @@ static int __devinit omap_kp_probe(struc
 	if (pdata->delay)
 		omap_kp->delay = pdata->delay;

-	if (pdata->row_gpios && pdata->col_gpios) {
-		row_gpios = pdata->row_gpios;
-		col_gpios = pdata->col_gpios;
-	}
-
 	omap_kp->rows = pdata->rows;
 	omap_kp->cols = pdata->cols;

-	if (cpu_is_omap24xx()) {
-		/* Cols: outputs */
-		for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
-			if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
-				printk(KERN_ERR "Failed to request"
-				       "GPIO%d for keypad\n",
-				       col_gpios[col_idx]);
-				goto err1;
-			}
-			gpio_direction_output(col_gpios[col_idx], 0);
-		}
-		/* Rows: inputs */
-		for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
-			if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
-				printk(KERN_ERR "Failed to request"
-				       "GPIO%d for keypad\n",
-				       row_gpios[row_idx]);
-				goto err2;
-			}
-			gpio_direction_input(row_gpios[row_idx]);
-		}
-	} else {
-		col_idx = 0;
-		row_idx = 0;
-	}
+	col_idx = 0;
+	row_idx = 0;

 	setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);

@@ -369,7 +349,7 @@ static int __devinit omap_kp_probe(struc

 	ret = device_create_file(&pdev->dev, &dev_attr_enable);
 	if (ret < 0)
-		goto err2;
+		goto err1;

 	/* setup input device */
 	__set_bit(EV_KEY, input_dev->evbit);
@@ -387,47 +367,54 @@ static int __devinit omap_kp_probe(struc
 	ret = input_register_device(omap_kp->input);
 	if (ret < 0) {
 		printk(KERN_ERR "Unable to register omap-keypad input device\n");
-		goto err3;
+		goto err2;
 	}

-	if (pdata->dbounce)
-		omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
+	if (pdata->dbounce) {
+		if (cpu_is_omap44xx())
+			omap_writew(0xff, OMAP_MPUIO_BASE +
+				OMAP4_KBD_DEBOUNCINGTIME);
+		else
+			omap_writew(0xff, OMAP_MPUIO_BASE +
+				OMAP_MPUIO_GPIO_DEBOUNCING);
+	}

 	/* scan current status and enable interrupt */
 	omap_kp_scan_keypad(omap_kp, keypad_state);
-	if (!cpu_is_omap24xx()) {
-		omap_kp->irq = platform_get_irq(pdev, 0);
-		if (omap_kp->irq >= 0) {
-			if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
-					"omap-keypad", omap_kp) < 0)
-				goto err4;
-		}
+
+	/* Configuring OMAP4 keypad registers */
+	if (cpu_is_omap44xx()) {
+		omap_writew(OMAP4_KBD_SYSCONFIG_SOFTRST |
+			OMAP4_KBD_SYSCONFIG_ENAWKUP, OMAP4_KBDOCP_BASE
+				+ OMAP4_KBD_SYSCONFIG);
+		omap_writew((OMAP4_KBD_CTRLPTVVALUE << OMAP4_KBD_CTRLPTV) |
+			OMAP4_KBD_CTRL_NOSOFTMODE,
+				OMAP4_KBDOCP_BASE + OMAP4_KBD_CTRL);
+	}
+
+	omap_kp->irq = platform_get_irq(pdev, 0);
+
+	if (omap_kp->irq >= 0) {
+		if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
+				"omap-keypad", omap_kp) < 0)
+			goto err3;
+	}
+
+	if (!cpu_is_omap44xx())
 		omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
-	} else {
-		for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
-			if (request_irq(gpio_to_irq(row_gpios[irq_idx]),
-					omap_kp_interrupt,
-					IRQF_TRIGGER_FALLING,
-					"omap-keypad", omap_kp) < 0)
-				goto err5;
-		}
+
+	if (cpu_is_omap44xx()) {
+		omap_writew(OMAP4_KBD_IRQENABLE_EVENTEN |
+			OMAP4_KBD_IRQENABLE_LONGKEY, OMAP4_KBDOCP_BASE +
+				OMAP4_KBD_IRQENABLE);
 	}
 	return 0;
-err5:
-	for (i = irq_idx - 1; i >=0; i--)
-		free_irq(row_gpios[i], 0);
-err4:
+err3:
 	input_unregister_device(omap_kp->input);
 	input_dev = NULL;
-err3:
-	device_remove_file(&pdev->dev, &dev_attr_enable);
 err2:
-	for (i = row_idx - 1; i >=0; i--)
-		gpio_free(row_gpios[i]);
+	device_remove_file(&pdev->dev, &dev_attr_enable);
 err1:
-	for (i = col_idx - 1; i >=0; i--)
-		gpio_free(col_gpios[i]);
-
 	kfree(omap_kp);
 	input_free_device(input_dev);

@@ -440,14 +427,10 @@ static int __devexit omap_kp_remove(stru

 	/* disable keypad interrupt handling */
 	tasklet_disable(&kp_tasklet);
-	if (cpu_is_omap24xx()) {
-		int i;
-		for (i = 0; i < omap_kp->cols; i++)
-			gpio_free(col_gpios[i]);
-		for (i = 0; i < omap_kp->rows; i++) {
-			gpio_free(row_gpios[i]);
-			free_irq(gpio_to_irq(row_gpios[i]), 0);
-		}
+	if (cpu_is_omap44xx()) {
+		omap_writel(OMAP4_KBD_IRQDISABLE, OMAP4_KBDOCP_BASE +
+			OMAP4_KBD_IRQENABLE);
+		free_irq(omap_kp->irq, 0);
 	} else {
 		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 		free_irq(omap_kp->irq, 0);

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-09-07 14:07 Somshekar ChandrashekarKadam
  0 siblings, 0 replies; 409+ messages in thread
From: Somshekar ChandrashekarKadam @ 2009-09-07 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Catalin Marinas,

I am working on ARM1176 Realview board.
Kernel stable arm 2.6.28

My first query

I think reboot command is not implemented. ?

Work done locally here.

Implemented reboot by setting  8th bit of SYS_RESETCTL (reset control register 0x10000040). It works fine when given command reboot.

Issue Faced

ASLA works fine when done hard poweroff and poweron. ALSA detected properly and works fine.When I do a soft reboot using reboot command.  when kernel boots up it doesn't detect ALSA device itself with the
following messages. It is not able to read AC97 Register failing
because of timeout. I tried increasing the timeout and udelay still the
same case. Messages are shown below a the end.I also tried setting the various depth of a soft reset like 
(1=SYSRST rest logic tile, 2=PLLLOCK reset PLL, 4=PBRESET board reset,
same as pressing reset button). still ALSA does not work.Now I am confused on this. Please throw some light on this or any pointer will be useful.It is not able to read AC97 Register failing
because of timeout. routine (/*
 * Read an AC'97 register.
 */
static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)) 
I hope i have made myself clear. 
Thanks In Advance

Messages when ALSA not detected

====================================================

When sound doesn't work I see following in boot log:

Advanced Linux Sound Architecture Driver Version 1.0.18rc3.
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7c)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7e)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7c)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7e)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 1c)
port 1 high speed
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7c)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 7e)
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back (0 != 1c)
usb 1-1: new high speed USB device using isp1760 and address 2
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: ac97 read back fail.  retry
aaci-pl041 fpga:04: wrong ac97 register read back 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20090907/092b9ae9/attachment-0001.htm>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-09-17  9:37 Marc Kleine-Budde
  0 siblings, 0 replies; 409+ messages in thread
From: Marc Kleine-Budde @ 2009-09-17  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This patch series adds support for the Atmel CAN controller as found
on the AT91SAM9263.

It adds the at91_can to the generic device definition, activates the CAN
controller on the at91sam9263ek and adds the driver itself.

Changes since V1:
- let Kconfig depend on CAN_DEV
- add example how driver is used in baord file

Please review and consider for inclusion.

cheers, Marc

Marc Kleine-Budde (3):
      at91sam9263: add at91_can device to generic device definition
      at91sam9263ek: activate at91 CAN controller
      at91_can: add driver for Atmel's CAN controller on AT91SAM9263

 arch/arm/mach-at91/at91sam9263_devices.c |   36 +
 arch/arm/mach-at91/board-sam9263ek.c     |   19 +
 arch/arm/mach-at91/include/mach/board.h  |    6 +
 drivers/net/can/Kconfig                  |    6 +
 drivers/net/can/Makefile                 |    1 +
 drivers/net/can/at91_can.c               | 1186 ++++++++++++++++++++++++++++++
 6 files changed, 1254 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/at91_can.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2009-11-19 13:58 Vimal Singh
  0 siblings, 0 replies; 409+ messages in thread
From: Vimal Singh @ 2009-11-19 13:58 UTC (permalink / raw)
  To: linux-mtd

This patch series adds flash support for NAND (in sdp, zoom and ldp),
OneNAND and NOR (in sdp)

Tested on Zoom2 and 3430SDP

Vimal Singh (4):
[PATCH-v6 1/4] OMAP2/3: Add support for flash on SDP boards
[PATCH-v6 2/4] OMAP3: Add support for NAND on ZOOM/LDP boards
[PATCH-v6 3/4] OMAP: Zoom2: Enable NAND and JFFS2 support in defconfig
[PATCH-v6 4/4] OMAP: 3430SDP: Enable NAND in defconfig


v6 :
1. Implemented Tony's comments on below threads:

[PATCH-v5 1/4] OMAP2/3: Add support for flash on SDP boards
http://marc.info/?l=linux-omap&m=125805845217778&w=2

[PATCH-v5 2/4] OMAP3: Add support for NAND on ZOOM2/LDP boards
http://marc.info/?l=linux-omap&m=125805867318269&w=2

[PATCH 2/3]NAND: OMAP: Fixing omap nand driver, compiled as module
http://marc.info/?l=linux-omap&m=125787938923028&w=2

2. Creating 'mach-omap2/gpmc-nand.c' to handle GPMC related setups for
the driver.
3. Removed all 'gpmc_cs_read_reg' and 'gpmc_cs_write_reg' calls from
'nand/omap2.c'
4. Corrected macro 'GPMC_CONFIG1_DEVICETYPE_NAND' for NAND
5. Removed 'nand unlock' routine in patch 2/4, will take this
discussion to mtd list.

v4-v5:
[PATCH-v5 1/4] OMAP2/3: Add support for flash on SDP boards:
Implemented Tony's comments.

-- 
Regards,
Vimal Singh

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-02-25  9:36 Thomas Weber
  0 siblings, 0 replies; 409+ messages in thread
From: Thomas Weber @ 2010-02-25  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH/RFC] OMAP2: serial.c: Fix number of uarts in early_init

The omap_serial_early_init prints the following errors:

Could not get uart4_ick
Could not get uart4_fck

because all the uarts available in omap_uart[] will be initialized.
Only omap4430 and omap3630 have 4 uarts at the moment.
This patch reduces the number of uarts when cpu is not omap4430 or
omap3630.

Signed-off-by: Thomas Weber <weber@corscience.de>
---
 arch/arm/mach-omap2/serial.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index b79bc89..da77930 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -644,16 +644,21 @@ static void serial_out_override(struct uart_port *up, int offset, int value)
 }
 void __init omap_serial_early_init(void)
 {
-	int i;
+	int i, nr_ports;
 	char name[16];
 
+	if (!(cpu_is_omap3630() || cpu_is_omap4430()))
+		nr_ports = 3;
+	else
+		nr_ports = ARRAY_SIZE(omap_uart);
+
 	/*
 	 * Make sure the serial ports are muxed on at this point.
 	 * You have to mux them off in device drivers later on
 	 * if not needed.
 	 */
 
-	for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
+	for (i = 0; i < nr_ports; i++) {
 		struct omap_uart_state *uart = &omap_uart[i];
 		struct platform_device *pdev = &uart->pdev;
 		struct device *dev = &pdev->dev;
@@ -669,17 +674,17 @@ void __init omap_serial_early_init(void)
 			continue;
 		}
 
-		sprintf(name, "uart%d_ick", i+1);
+		sprintf(name, "uart%d_ick", i + 1);
 		uart->ick = clk_get(NULL, name);
 		if (IS_ERR(uart->ick)) {
-			printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+			printk(KERN_ERR "Could not get uart%d_ick\n", i + 1);
 			uart->ick = NULL;
 		}
 
 		sprintf(name, "uart%d_fck", i+1);
 		uart->fck = clk_get(NULL, name);
 		if (IS_ERR(uart->fck)) {
-			printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+			printk(KERN_ERR "Could not get uart%d_fck\n", i + 1);
 			uart->fck = NULL;
 		}
 
-- 
1.6.4.4

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2010-03-25 17:02 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-03-25 17:02 UTC (permalink / raw)
  To: ath9k-devel

the production level yet, although my chipset is AR9160.

One issue is after a long time running the traffic maybe stopped
occasionally. Another one is it seems have some compatibility issue
with Intel chipset. They have troubled me a lot.

-Daniel

2010/5/6 Alan <lameventanas@gmail.com>:
> Can anybody give me a status report on the current state of ath9k?
> I know the one shipped with kernel 2.6.33.2 is working without major
> issues with 802.11g because I'm using it.
> But what is the status of 802.11n?
> What is the status of multiple ssids? Can I configure more than one in
> master mode?
>
> I'm asking because I'm about to set up an AP to be considered
> production level, and having 802.11n and two ssids (one open for
> guests, one encrypted for intended users) would be great.
> Should I stick to the version provided with the current kernel or
> should I use compat-wireless?
> Should I wait for the next kernel to be released with a major
> breakthrough in ath9k? (judging by the mailing list activity, it seems
> so).
> Hardware is AR5008 (dual band, 3 antennas).
>
> Thanks a lot!
>
> Alan
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel at lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-03-25 17:02 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-03-25 17:02 UTC (permalink / raw)
  To: ath9k-devel

different behaviour and if the ls and error message were done on the same
machine the file is actually there.
I have not read the code, so I am more speculating, but could some other error
in the firmware loading be falsely evaluated as fw not found?

-Stefan

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-04-17 21:43 nelakurthi koteswararao
  0 siblings, 0 replies; 409+ messages in thread
From: nelakurthi koteswararao @ 2010-04-17 21:43 UTC (permalink / raw)
  To: linux-arm-kernel

http://ColleenKitts2530.co.cc

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-05-18 10:38 Marek Szyprowski
  0 siblings, 0 replies; 409+ messages in thread
From: Marek Szyprowski @ 2010-05-18 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch series perform a general cleanup in Samsung S5PC100 SoC support.
This chip is moved from custom s5pc1xx platform framework to new plat-s5p
framework, so more common code can be easily reused in upcomming extensions
for S5PV210/S5PC110 SoCs.

This patch series is prepared against next-samsung tree, with assumption
that the "[PATCH v3] ARM: S5PC100: Pre-requisite clock patch for
plat-s5pc1xx to plat-s5p" has been applied as well as the '[PATCH v6]
ARM: S5PV210: Add Ext interrupt support' (with additional bug fixes).

I've tried to split my changes as much as possible to clearly show how the
transition from plat-s5pc1xx to plat-s5p is being done.

Changes since v2:
- fixed some whitespace/tabs errors
- removed external interrupt code, a common code from plat-s5p will be used
- moved SMDKC100 fixes to separate patch series

Changes since v1:
- bases on completely new clock code provided by Kukjin Kim
- added some plat-s5p fixes required for transition
- removed custom functions from gpiolib implementation (now uses common
  code from plat-samsung)
- restructured the changes to avoid breaking the functionality beteen the
  patches
- some other minor cleanups (mainly c1xx to c100 renames)

This patch series includes:

[PATCH 01/11] drivers: serial: S5PC100 serial driver cleanup
[PATCH 02/11] ARM: S5PC100: Use common functions for gpiolib implementation
[PATCH 03/11] ARM: S5PC100: Move gpio support from plat-s5pc1xx to mach-s5pc100
[PATCH 04/11] ARM: S5PC100: gpio.h cleanup
[PATCH 05/11] ARM: S5PC100: Move frame buffer helpers from plat-s5pc1xx to mach-s5pc100
[PATCH 06/11] ARM: S5PC100: Move i2c helpers from plat-s5pc1xx to mach-s5pc100
[PATCH 07/11] ARM: S5PC100: Move sdhci helpers from plat-s5pc1xx to mach-s5pc100
[PATCH 08/11] ARM: Samsung: move S5PC100 support from plat-s5pc1xx to plat-s5p framework
[PATCH 09/11] ARM: S5PC100: Add support for gpio interrupt
[PATCH 10/11] ARM: S5PC100: use common plat-s5p external interrupt code
[PATCH 11/11] ARM: remove obsolete plat-s5pc1xx directory

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-06-07 17:58 Dave Hylands
  0 siblings, 0 replies; 409+ messages in thread
From: Dave Hylands @ 2010-06-07 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I'm trying to understand what I need to be concerned about with SMP
processors and sharing global data (in particular a dual Cortex-A9)

I'm familiar with spinlocks, but in this case I'm trying to work with
some lockless data structures.

What I'm not sure is whether the following would work. Suppose I have
a couple of 8-bit get/put indicies which are in adjacent memory
locations (within the same 32-bit word).

If I have an ISR and a thread running on an SMP core, and the ISR is
running on one core and the thread is running on a second core, if the
ISR were to only write to the put pointer and the thread were only to
write to the get pointer, does the cache maintain consistency? Or do
the get and put pointers need to be in separate cache lines?

Another way of asking this: If both cores are writing to the same
32-bit word (but different bytes) do the writes collide?

--
Dave Hylands
Shuswap, BC, Canada
http://www.DaveHylands.com/

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-06-24 13:48 Uwe Kleine-König
  0 siblings, 0 replies; 409+ messages in thread
From: Uwe Kleine-König @ 2010-06-24 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

this is the next step in the project "clean up the imx port" targeting
2.6.36.  The highlights this time are:

 - Unification of mach-mx2 and mach-mx1 into mach-imx
 - start allocating devices dynamically
   This should reduce the memory footprint because (in the end) no
   unused struct platform_device, struct resource or struct
   $platformdatafordriverX are kept in memory.  This also cleans up
   with naming conflicts.

This is intermixed with various fixes and simplifications.

I have to admit that some patches could have squashed but squashing them
now would be more work that it's worth so I kept them as they are now.

The patches are based on 67a3e12b05e055c0415c556a315a3d3eb637e29e

  Linux 2.6.35-rc1 (2010-05-30 13:21:02 -0700)

and are available in the git repository at:
  git://git.pengutronix.de/git/ukl/linux-2.6.git imx/for-2.6.36

plus sent as a reply to this mail.  Shortlog and diffstat are to be
found below.

Have fun
Uwe

Uwe Kleine-K?nig (61):
      ARM: mx3: rename mach-mx35pdk.c to mach-mx35_3ds.c matching its arch number
      ARM: mx25: rename mach-mx25pdk.c to mach-mx25_3ds.c matching its arch number
      ARM: mx1: don't use deprecated symbol names
      ARM: mx1/scb9328: fix type of uart1_mxc_exit to make compiler happy
      ARM: mx2/mx27_3ds: document alternative names and remove empty header
      ARM: imx: remove empty and unused board headers
      ARM: mx3/kzm_arm11_01: fold board header in its only user
      ARM: mx2/mx21ads: fold board header in its only user
      ARM: mx2/mx27ads: fold board header in its only user
      ARM: mx3/qong: get rid of nearly empty header
      ARM: mx3/mx31_3ds: fold board header in its only user
      ARM: mx3/mx31ads: fold board header in its only user
      ARM: mxc: grammar fix
      ARM: imx: rename mach dir for mx21 and mx27 to mach-imx
      ARM: imx/mx1: fold crm_regs.h into its only consumer
      ARM: imx: get rid of mxc_gpio_init
      ARM: imx: fold serial.c into devices.c
      ARM: imx1: rename imx_csi_device to match its .name
      ARM: imx1: rename imx_i2c_device to follow a common naming scheme
      ARM: imx1: rename imx_uart[12]_device to follow a common naming scheme
      ARM: mx3: mx31lilly: fix build error for !CONFIG_USB_ULPI
      ARM: imx: rename mxc_uart_devicex to follow a common naming scheme
      ARM: imx: move mx1 support to mach-imx
      ARM: imx: Kconfig: use an if block instead of a depend for many symbols
      ARM: imx: prepare deprecating ARCH_MX1, MACH_MX2, MACH_MX21 and MACH_MX27
      ARM: imx: prepare deprecating ARCH_MX1, MACH_MX2, MACH_MX21 and MACH_MX27
      ARM: imx: new Kconfig symbol and feature test macro for DMA on mx1 and mx2
      ARM: imx: new helper function imx_add_platform_device
      MTD: mxc_nand: make bit fields unsigned to please sparse
      ARM: imx: remove paragraphs with old address of the FSF
      ARM: mx25: remove paragraphs with old address of the FSF
      ARM: mx3: remove paragraphs with old address of the FSF
      ARM: mxc91231: remove paragraphs with old address of the FSF
      ARM: mxc: remove paragraphs with old address of the FSF
      ARM: imx: Change the way nand devices are registered (generic part)
      ARM: imx: Change the way nand devices are registered (imx21)
      ARM: imx: Change the way nand devices are registered (imx25)
      ARM: imx: Change the way nand devices are registered (imx27)
      ARM: imx: Change the way nand devices are registered (imx31)
      ARM: imx: Change the way nand devices are registered (imx35)
      ARM: imx: dynamically register imx-i2c devices (generic part)
      ARM: imx: dynamically register imx-i2c devices (imx1)
      ARM: imx: dynamically register imx-i2c devices (imx21)
      ARM: imx: dynamically register imx-i2c devices (imx25)
      ARM: imx: dynamically register imx-i2c devices (imx27)
      ARM: imx: dynamically register imx-i2c devices (imx31)
      ARM: imx: dynamically register imx-i2c devices (imx35)
      ARM: imx: dynamically register spi_imx devices (generic part)
      ARM: imx: dynamically register spi_imx devices (imx21)
      ARM: imx: dynamically register spi_imx devices (imx25)
      ARM: imx: dynamically register spi_imx devices (imx27)
      ARM: imx: dynamically register spi_imx devices (imx31)
      ARM: imx: dynamically register spi_imx devices (imx35)
      ARM: imx: dynamically register imx-uart devices (generic part)
      ARM: imx: dynamically register imx-uart devices (imx1)
      ARM: imx: dynamically register imx-uart devices (imx21)
      ARM: imx: dynamically register imx-uart devices (imx25)
      ARM: imx: dynamically register imx-uart devices (imx27)
      ARM: imx: dynamically register imx-uart devices (imx31)
      ARM: imx: dynamically register imx-uart devices (imx35)
      ARM: mx3: complement uart init routine with an exit routine

 arch/arm/Makefile                                  |    4 +-
 arch/arm/mach-imx/Kconfig                          |  186 +++++++++++
 arch/arm/{mach-mx2 => mach-imx}/Makefile           |   18 +-
 arch/arm/{mach-mx2 => mach-imx}/Makefile.boot      |    4 +
 .../{mach-mx1/clock.c => mach-imx/clock-imx1.c}    |   50 +++-
 .../clock_imx21.c => mach-imx/clock-imx21.c}       |    0
 .../clock_imx27.c => mach-imx/clock-imx27.c}       |    0
 .../{mach-mx2/cpu_imx27.c => mach-imx/cpu-imx27.c} |    0
 arch/arm/mach-imx/devices-imx1.h                   |   18 +
 arch/arm/mach-imx/devices-imx21.h                  |   30 ++
 arch/arm/mach-imx/devices-imx27.h                  |   38 +++
 arch/arm/{mach-mx2 => mach-imx}/devices.c          |  250 +++++++++------
 arch/arm/{mach-mx2 => mach-imx}/devices.h          |   30 +--
 .../{plat-mxc/dma-mx1-mx2.c => mach-imx/dma-v1.c}  |    4 +-
 .../eukrea_mbimx27-baseboard.c                     |   19 +-
 arch/arm/mach-imx/include/mach/dma-mx1-mx2.h       |   10 +
 .../include/mach/dma-v1.h}                         |   10 +-
 arch/arm/{mach-mx2 => mach-imx}/mach-cpuimx27.c    |   25 +-
 arch/arm/{mach-mx2 => mach-imx}/mach-imx27lite.c   |   11 +-
 arch/arm/{mach-mx1 => mach-imx}/mach-mx1ads.c      |   34 +-
 arch/arm/{mach-mx2 => mach-imx}/mach-mx21ads.c     |   58 +++-
 arch/arm/{mach-mx2 => mach-imx}/mach-mx27_3ds.c    |   17 +-
 arch/arm/{mach-mx2 => mach-imx}/mach-mx27ads.c     |   76 +++--
 arch/arm/{mach-mx2 => mach-imx}/mach-mxt_td60.c    |   36 +--
 arch/arm/{mach-mx2 => mach-imx}/mach-pca100.c      |   23 +-
 arch/arm/{mach-mx2 => mach-imx}/mach-pcm038.c      |   33 +--
 arch/arm/{mach-mx1 => mach-imx}/mach-scb9328.c     |   21 +-
 .../arm/{mach-mx1/generic.c => mach-imx/mm-imx1.c} |   23 +-
 arch/arm/{mach-mx2 => mach-imx}/mm-imx21.c         |    5 +-
 arch/arm/{mach-mx2 => mach-imx}/mm-imx27.c         |    5 +-
 .../ksym_mx1.c => mach-imx/mx1-camera-fiq-ksym.c}  |    0
 .../mx1_camera_fiq.S => mach-imx/mx1-camera-fiq.S} |    0
 arch/arm/{mach-mx2 => mach-imx}/pcm970-baseboard.c |    0
 arch/arm/mach-mx1/Kconfig                          |   19 -
 arch/arm/mach-mx1/Makefile                         |   15 -
 arch/arm/mach-mx1/Makefile.boot                    |    4 -
 arch/arm/mach-mx1/crm_regs.h                       |   55 ---
 arch/arm/mach-mx1/devices.c                        |  242 --------------
 arch/arm/mach-mx1/devices.h                        |    7 -
 arch/arm/mach-mx2/Kconfig                          |  116 -------
 arch/arm/mach-mx2/serial.c                         |  141 --------
 arch/arm/mach-mx25/Kconfig                         |    2 +
 arch/arm/mach-mx25/Makefile                        |    2 +-
 arch/arm/mach-mx25/devices-imx25.h                 |   38 +++
 arch/arm/mach-mx25/devices.c                       |  231 +-------------
 arch/arm/mach-mx25/devices.h                       |   12 -
 .../mach-mx25/{mach-mx25pdk.c => mach-mx25_3ds.c}  |   21 +-
 arch/arm/mach-mx25/mm.c                            |    7 +-
 arch/arm/mach-mx3/Kconfig                          |   26 ++
 arch/arm/mach-mx3/Makefile                         |    2 +-
 arch/arm/mach-mx3/devices-imx31.h                  |   38 +++
 arch/arm/mach-mx3/devices-imx35.h                  |   32 ++
 arch/arm/mach-mx3/devices.c                        |  247 +--------------
 arch/arm/mach-mx3/devices.h                        |   13 -
 arch/arm/mach-mx3/mach-armadillo5x0.c              |   17 +-
 arch/arm/mach-mx3/mach-kzm_arm11_01.c              |   31 ++-
 arch/arm/mach-mx3/mach-mx31_3ds.c                  |   64 +++--
 arch/arm/mach-mx3/mach-mx31ads.c                   |   55 +++-
 arch/arm/mach-mx3/mach-mx31lilly.c                 |   47 ++--
 arch/arm/mach-mx3/mach-mx31lite.c                  |   17 +-
 arch/arm/mach-mx3/mach-mx31moboard.c               |   50 ++--
 .../mach-mx3/{mach-mx35pdk.c => mach-mx35_3ds.c}   |   16 +-
 arch/arm/mach-mx3/mach-pcm037.c                    |   31 +-
 arch/arm/mach-mx3/mach-pcm037_eet.c                |    7 +-
 arch/arm/mach-mx3/mach-pcm043.c                    |   25 +-
 arch/arm/mach-mx3/mach-qong.c                      |   16 +-
 arch/arm/mach-mx3/mm.c                             |    7 +-
 arch/arm/mach-mx3/mx31lilly-db.c                   |   14 +-
 arch/arm/mach-mx3/mx31lite-db.c                    |   15 +-
 arch/arm/mach-mx3/mx31moboard-devboard.c           |   10 +-
 arch/arm/mach-mx3/mx31moboard-marxbot.c            |    4 -
 arch/arm/mach-mx3/mx31moboard-smartbot.c           |   11 +-
 arch/arm/mach-mx5/devices.c                        |    2 +-
 arch/arm/mach-mx5/mm.c                             |    3 +
 arch/arm/mach-mxc91231/crm_regs.h                  |    5 -
 arch/arm/mach-mxc91231/devices.c                   |    2 +-
 arch/arm/mach-mxc91231/mm.c                        |    8 +-
 arch/arm/plat-mxc/Kconfig                          |   10 +-
 arch/arm/plat-mxc/Makefile                         |    4 +-
 arch/arm/plat-mxc/audmux-v1.c                      |    4 -
 arch/arm/plat-mxc/audmux-v2.c                      |    4 -
 arch/arm/plat-mxc/devices.c                        |   33 ++
 arch/arm/plat-mxc/devices/Kconfig                  |   11 +
 arch/arm/plat-mxc/devices/Makefile                 |    4 +
 arch/arm/plat-mxc/devices/platform-imx-i2c.c       |   29 ++
 arch/arm/plat-mxc/devices/platform-imx-uart.c      |   60 ++++
 arch/arm/plat-mxc/devices/platform-mxc_nand.c      |   44 +++
 arch/arm/plat-mxc/devices/platform-spi_imx.c       |   30 ++
 arch/arm/plat-mxc/ehci.c                           |    4 -
 .../arm/plat-mxc/include/mach/board-armadillo5x0.h |   15 -
 .../plat-mxc/include/mach/board-eukrea_cpuimx27.h  |    2 +-
 arch/arm/plat-mxc/include/mach/board-kzmarm11.h    |   39 ---
 arch/arm/plat-mxc/include/mach/board-mx21ads.h     |   52 ---
 arch/arm/plat-mxc/include/mach/board-mx27ads.h     |  344 --------------------
 arch/arm/plat-mxc/include/mach/board-mx27lite.h    |   14 -
 arch/arm/plat-mxc/include/mach/board-mx27pdk.h     |   14 -
 arch/arm/plat-mxc/include/mach/board-mx31_3ds.h    |   59 ----
 arch/arm/plat-mxc/include/mach/board-mx31ads.h     |  117 -------
 arch/arm/plat-mxc/include/mach/board-mx31lilly.h   |    2 +-
 arch/arm/plat-mxc/include/mach/board-mx31lite.h    |    2 +-
 arch/arm/plat-mxc/include/mach/board-mx31moboard.h |    2 +-
 arch/arm/plat-mxc/include/mach/board-mx35pdk.h     |   22 --
 arch/arm/plat-mxc/include/mach/board-pcm037.h      |   22 --
 arch/arm/plat-mxc/include/mach/board-pcm038.h      |    2 +-
 arch/arm/plat-mxc/include/mach/board-pcm043.h      |   22 --
 arch/arm/plat-mxc/include/mach/board-qong.h        |   17 -
 arch/arm/plat-mxc/include/mach/devices-common.h    |   42 +++
 arch/arm/plat-mxc/include/mach/iomux-mxc91231.h    |    4 -
 arch/arm/plat-mxc/include/mach/mx1.h               |   28 +-
 arch/arm/plat-mxc/include/mach/mx25.h              |   28 ++-
 arch/arm/plat-mxc/include/mach/mx27.h              |    4 +-
 arch/arm/plat-mxc/include/mach/mx31.h              |    4 +-
 arch/arm/plat-mxc/include/mach/mx35.h              |    4 +-
 arch/arm/plat-mxc/include/mach/mx3_camera.h        |    4 -
 arch/arm/plat-mxc/include/mach/mxc91231.h          |    4 -
 arch/arm/plat-mxc/include/mach/mxc_nand.h          |    6 +-
 arch/arm/plat-mxc/include/mach/system.h            |    4 -
 arch/arm/plat-mxc/include/mach/timex.h             |    4 -
 arch/arm/plat-mxc/include/mach/uncompress.h        |    4 -
 arch/arm/plat-mxc/include/mach/vmalloc.h           |    4 -
 arch/arm/plat-mxc/irq.c                            |    3 -
 arch/arm/plat-mxc/system.c                         |    4 -
 arch/arm/plat-mxc/tzic.c                           |    2 -
 123 files changed, 1424 insertions(+), 2478 deletions(-)
 create mode 100644 arch/arm/mach-imx/Kconfig
 rename arch/arm/{mach-mx2 => mach-imx}/Makefile (55%)
 rename arch/arm/{mach-mx2 => mach-imx}/Makefile.boot (67%)
 rename arch/arm/{mach-mx1/clock.c => mach-imx/clock-imx1.c} (90%)
 rename arch/arm/{mach-mx2/clock_imx21.c => mach-imx/clock-imx21.c} (100%)
 rename arch/arm/{mach-mx2/clock_imx27.c => mach-imx/clock-imx27.c} (100%)
 rename arch/arm/{mach-mx2/cpu_imx27.c => mach-imx/cpu-imx27.c} (100%)
 create mode 100644 arch/arm/mach-imx/devices-imx1.h
 create mode 100644 arch/arm/mach-imx/devices-imx21.h
 create mode 100644 arch/arm/mach-imx/devices-imx27.h
 rename arch/arm/{mach-mx2 => mach-imx}/devices.c (73%)
 rename arch/arm/{mach-mx2 => mach-imx}/devices.h (54%)
 rename arch/arm/{plat-mxc/dma-mx1-mx2.c => mach-imx/dma-v1.c} (99%)
 rename arch/arm/{mach-mx2 => mach-imx}/eukrea_mbimx27-baseboard.c (93%)
 create mode 100644 arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
 rename arch/arm/{plat-mxc/include/mach/dma-mx1-mx2.h => mach-imx/include/mach/dma-v1.h} (93%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-cpuimx27.c (90%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-imx27lite.c (86%)
 rename arch/arm/{mach-mx1 => mach-imx}/mach-mx1ads.c (81%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-mx21ads.c (77%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-mx27_3ds.c (85%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-mx27ads.c (82%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-mxt_td60.c (86%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-pca100.c (93%)
 rename arch/arm/{mach-mx2 => mach-imx}/mach-pcm038.c (91%)
 rename arch/arm/{mach-mx1 => mach-imx}/mach-scb9328.c (89%)
 rename arch/arm/{mach-mx1/generic.c => mach-imx/mm-imx1.c} (68%)
 rename arch/arm/{mach-mx2 => mach-imx}/mm-imx21.c (95%)
 rename arch/arm/{mach-mx2 => mach-imx}/mm-imx27.c (95%)
 rename arch/arm/{mach-mx1/ksym_mx1.c => mach-imx/mx1-camera-fiq-ksym.c} (100%)
 rename arch/arm/{mach-mx1/mx1_camera_fiq.S => mach-imx/mx1-camera-fiq.S} (100%)
 rename arch/arm/{mach-mx2 => mach-imx}/pcm970-baseboard.c (100%)
 delete mode 100644 arch/arm/mach-mx1/Kconfig
 delete mode 100644 arch/arm/mach-mx1/Makefile
 delete mode 100644 arch/arm/mach-mx1/Makefile.boot
 delete mode 100644 arch/arm/mach-mx1/crm_regs.h
 delete mode 100644 arch/arm/mach-mx1/devices.c
 delete mode 100644 arch/arm/mach-mx1/devices.h
 delete mode 100644 arch/arm/mach-mx2/Kconfig
 delete mode 100644 arch/arm/mach-mx2/serial.c
 create mode 100644 arch/arm/mach-mx25/devices-imx25.h
 rename arch/arm/mach-mx25/{mach-mx25pdk.c => mach-mx25_3ds.c} (91%)
 create mode 100644 arch/arm/mach-mx3/devices-imx31.h
 create mode 100644 arch/arm/mach-mx3/devices-imx35.h
 rename arch/arm/mach-mx3/{mach-mx35pdk.c => mach-mx35_3ds.c} (89%)
 create mode 100644 arch/arm/plat-mxc/devices/Kconfig
 create mode 100644 arch/arm/plat-mxc/devices/Makefile
 create mode 100644 arch/arm/plat-mxc/devices/platform-imx-i2c.c
 create mode 100644 arch/arm/plat-mxc/devices/platform-imx-uart.c
 create mode 100644 arch/arm/plat-mxc/devices/platform-mxc_nand.c
 create mode 100644 arch/arm/plat-mxc/devices/platform-spi_imx.c
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-kzmarm11.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx21ads.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx27ads.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx27lite.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx27pdk.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx31ads.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx35pdk.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-pcm037.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-pcm043.h
 delete mode 100644 arch/arm/plat-mxc/include/mach/board-qong.h
 create mode 100644 arch/arm/plat-mxc/include/mach/devices-common.h

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-07-23 10:05 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-07-23 10:05 UTC (permalink / raw)
  To: ath9k-devel

mesh point. We have not yet figured out why the mesh interface is removed a=
nd reset to an interface of type NL80211_IFTYPE_STATION.

Regards
Abhijeet

-----Original Message-----
From: Luis R. Rodriguez [mailto:mcgrof at gmail.com]
Sent: Wednesday, July 28, 2010 9:23 PM
To: Abhijeet Chandran
Cc: ath9k-devel at lists.ath9k.org
Subject: Re: [ath9k-devel] ath9k mesh point not emitting beacons

On Wed, Jul 28, 2010 at 7:19 AM, Abhijeet Chandran <Abhijeet.Chandran@arice=
nt.com> wrote:
> Hi
> We have a problem that we have configured a  mesh point for the first
> time and  it  does not seem to start emitting beacons as soon as it comes=
 up.
> The card we are using is ath 9220
> We brought mesh point up , ex:
> # iw phy phy0 interface add mesh type mp mesh_id mymesh # ifconfig
> mesh up
>
> Through tracing in the kernel module mac80211  it appears that a
> callback function ieee80211_open is called with type mesh point as
> soon as the above commands are executed.
> However it  is immediately followed by the callback function
> ieee80211_stop (usually called when the mesh point is brought down) ,
> following which the meshpoint related sdata is flushed .
> Another question that we have is that do we need to enable scanning
> for the mesh point to emit beacons/probes?
>
> We have used the simulator mac80211_hwsim before  in which beacons are
> emitted as soon as the mesh point comes up.In the simulator don't need
> to start scanning on the mesh point.
> We'd really appreciate if somone can help us out here.

Known issue no one has yet looked into:

https://bugzilla.kernel.org/show_bug.cgi?id=3D14187

It should start beaconing if you issue a scan.

  Luis

"DISCLAIMER: This message is proprietary to Aricent and is intended solely =
for the use of the individual to whom it is addressed. It may contain privi=
leged or confidential information and should not be circulated or used for =
any purpose other than for what it is intended. If you have received this m=
essage in error, please notify the originator immediately. If you are not t=
he intended recipient, you are notified that you are strictly prohibited fr=
om using, copying, altering, or disclosing the contents of this message. Ar=
icent accepts no responsibility for loss or damage arising from the use of =
the information transmitted by this email including damage from virus."

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-08-23 14:32 auto595907
  0 siblings, 0 replies; 409+ messages in thread
From: auto595907 @ 2010-08-23 14:32 UTC (permalink / raw)
  To: maciej.rutecki; +Cc: netdev, linux-kernel

>I created a Bugzilla entry at 
>https://bugzilla.kernel.org/show_bug.cgi?id=16423
>for your bug report, please add your address to the CC list in 
>there, thanks!
>
>-- 
>Maciej Rutecki
>http://www.maciek.unixy.pl


this patch fixes the bug above
(http://marc.info/?l=netfilter-devel&m=128116762801769&w=2)


thanks.


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-08-30  5:02 auto595907
  0 siblings, 0 replies; 409+ messages in thread
From: auto595907 @ 2010-08-30  5:02 UTC (permalink / raw)
  To: rjw; +Cc: linux-kernel

Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16423
Subject		: netfilter/iptables stopped logging 2.6.35-rc
Submitter	: auto401300@hushmail.com
Date		: 2010-07-17 10:20 (44 days old)
Message-ID	: <20100717072036.1BBE52804B@smtp.hushmail.com>
References	: 
http://lkml.indiana.edu/hypermail/linux/kernel/1007.2/00440.html


this patch fixes the bug above:
(http://marc.info/?l=netfilter-devel&m=128116762801769&w=2)

fixed in 2.6.36-rc3


thanks


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-09  3:33 tarek attia
  0 siblings, 0 replies; 409+ messages in thread
From: tarek attia @ 2010-09-09  3:33 UTC (permalink / raw)
  To: linux-arm-kernel

register

--
tarek

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel

possible with the driver at this point.

As a side note, no, iwconfig should not be used for anything anymore.


//Peter

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel

when ath_draintxq() is called. From ath_draintxq() point of view that
looks like a bad idea (race between CPU and DMA).

Also, that looking around "cabq_depth =3D cabq->axq_depth;" looks very
peculiar. I believe it's correct (because nobody else puts anything
into this queue and we don't care if it's shorter later on when we
drain it) but I think it would be nice with a comment.

Any thoughts? I can whip up and test a patch if there are no objections.

/Bj=F6rn

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel

Like you said, it is low because both interfaces share the medium but if I don??t change the rate using iwconfig, this values or at least the first one goes down until 1,5 MBits. That??s way I wonder if there is something that keeps the rate low by the time a virtual interface is created. 

Thanks for your response

Best regards

Lorna 


-------- Original-Nachricht --------
> Datum: Thu, 11 Nov 2010 09:00:45 -0800
> Von: Ben Greear <greearb@candelatech.com>
> An: "Lorna Gonz??lez" <lorna.glez@gmx.net>
> CC: Jouni Malinen <jouni.malinen@atheros.com>, ath9k-devel at venema.h4ckr.net
> Betreff: Re: [ath9k-devel] ath9k: Virtual interface as AP

> On 11/11/2010 07:06 AM, "Lorna Gonz??lez" wrote:
> >
> > Hello
> >
> > I finally got a station an a virtual AP working on the same channel
> using the setup below. I made some test sending TCP through iperf between the
> AP and the station and the VAP to a station associated with it.
> > Using an AP operating with Ieee802.11n, an atheros AR928X and without
> virtual interfaces I get a max throughput of 50 MBits/s.
> > As soon as I start using my desired setup, the thoughput of the station
> is about 15 MBits/s... I actually need to make the rate fixed using
> iwconfig to get this max. Otherwise the traffic is sent at 1 MBit/s.
> >
> > Can someone please tell me how is the behaviour of the rate control in
> case of virtual interfaces on mac80211?
> 
> Can you give a more detailed description/diagram of your virtual AP setup
> and
> network throughput test?  It sounds like you are using the same radio as
> AP
> and STA?  If so, then of course you are going to get less bandwidth on the
> VIFS because they have to share the radio.
> 
> I'm not sure it should drop all the way to 15Mbps, though.  We haven't
> done a lot of throughput
> testing yet, but if we use two STA vifs on the ath9k box connected to an
> 80211n AP (trendnet),
> then we can set a max of about 9Mbps tx + rx across each STA (the STAs are
> sending to each other).
> That is around 40Mbps total tx + rx across the radio.
> 
> Thanks,
> Ben
> 
> -- 
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
> 

-- 
Neu: GMX De-Mail - Einfach wie E-Mail, sicher wie ein Brief!  
Jetzt De-Mail-Adresse reservieren: http://portal.gmx.net/de/go/demail

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel

Like you said, it is low because both interfaces share the medium but if I don??t change the rate using iwconfig, this values or at least the first one goes down until 1,5 MBits. That??s way I wonder if there is something that keeps the rate low by the time a virtual interface is created. 

Thanks for your response

Best regards

Lorna 


-------- Original-Nachricht --------
> Datum: Thu, 11 Nov 2010 09:00:45 -0800
> Von: Ben Greear <greearb@candelatech.com>
> An: "Lorna Gonz??lez" <lorna.glez@gmx.net>
> CC: Jouni Malinen <jouni.malinen@atheros.com>, ath9k-devel at venema.h4ckr.net
> Betreff: Re: [ath9k-devel] ath9k: Virtual interface as AP

> On 11/11/2010 07:06 AM, "Lorna Gonz??lez" wrote:
> >
> > Hello
> >
> > I finally got a station an a virtual AP working on the same channel
> using the setup below. I made some test sending TCP through iperf between the
> AP and the station and the VAP to a station associated with it.
> > Using an AP operating with Ieee802.11n, an atheros AR928X and without
> virtual interfaces I get a max throughput of 50 MBits/s.
> > As soon as I start using my desired setup, the thoughput of the station
> is about 15 MBits/s... I actually need to make the rate fixed using
> iwconfig to get this max. Otherwise the traffic is sent at 1 MBit/s.
> >
> > Can someone please tell me how is the behaviour of the rate control in
> case of virtual interfaces on mac80211?
> 
> Can you give a more detailed description/diagram of your virtual AP setup
> and
> network throughput test?  It sounds like you are using the same radio as
> AP
> and STA?  If so, then of course you are going to get less bandwidth on the
> VIFS because they have to share the radio.
> 
> I'm not sure it should drop all the way to 15Mbps, though.  We haven't
> done a lot of throughput
> testing yet, but if we use two STA vifs on the ath9k box connected to an
> 80211n AP (trendnet),
> then we can set a max of about 9Mbps tx + rx across each STA (the STAs are
> sending to each other).
> That is around 40Mbps total tx + rx across the radio.
> 
> Thanks,
> Ben
> 
> -- 
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
> 

-- 
Neu: GMX De-Mail - Einfach wie E-Mail, sicher wie ein Brief!  
Jetzt De-Mail-Adresse reservieren: http://portal.gmx.net/de/go/demail

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-09-24 14:53 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-09-24 14:53 UTC (permalink / raw)
  To: ath9k-devel

ath9k, I read.
The mac filtering has not implemented at ath9k or not?

I would like to know how it is about the status.

Any comments will be very appreciated of..
-
mason

--0016e68e92891791f80497724c8a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>From the openwrt site, mac address filtering has not implemented yet a=
t ath9k, I read.</div>
<div>The mac filtering has not implemented at ath9k or not? </div>
<div>=A0</div>
<div>I would like to know how it is about the status.</div>
<div>=A0</div>
<div>Any comments will be very appreciated of..</div>
<div>-</div>
<div>mason</div>
<div><br clear=3D"all"><br>=A0</div>

--0016e68e92891791f80497724c8a--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-10-08  6:02 Daein Moon
  0 siblings, 0 replies; 409+ messages in thread
From: Daein Moon @ 2010-10-08  6:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ben Dooks and Kukjin,

I found an issue about s3c_gpio_getpull API.

The 'plat-samsung' provides 's3c_gpio_setpull' and 's3c_gpio_getpull'
to set and get pull-{none|up|down} of GPIO. But there is no
's3c_gpio_getpull' definition in 'arch/arm/plat-samsung/gpio-config.c',
and there is only declaration in the corresponding header file.

's3c_gpio_getpull' isn't supported/used. So if providing this api, its
definition should be inserted.

Otherwise, code that is used to provide s3c_gpio_getpull including
following code should be removed.

arch/arm/plat-samsung/include/plat/gpio-cfg.h:
	extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);

arch/arm/mach-{s3c*|s5p*}/gpiolib.c:
        .get_pull       = s3c_gpio_getpull_updown,


What do you think about that?

Best Regards,
Daein Moon

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-03  1:08 tarek attia
  0 siblings, 0 replies; 409+ messages in thread
From: tarek attia @ 2010-12-03  1:08 UTC (permalink / raw)
  To: linux-arm-kernel

register

-- 
tarek

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

chip haven't been woken up.

The AR9280 support works (for values of "work") in FreeBSD, so I'm
thinking the local code is missing a couple of relevant register
settings to enable the thing.

Does anyone know off-hand what I may need to glimpse at to make it
work? What's different between the AR9280 and AR9220 initialisation
sequences? I couldn't see anything AR9220 specific in ath9k.

Thanks,


Adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

* If your RX chainmask has >1 radio enabled, you'll always be doing
receive-side "diversity" (which is really "combining" (MRC) if I
understand the technology correctly on multi-radio atheros 11n cards);
* If your TX chainmask has >1 radio enabled and the TX descriptor has
the relevant chainmask bits set, you should be transmitting on both
antennas regardless of the rate. I honestly haven't verified it (I've
only verified that behaviour for transmitting legacy rates out of the
11n chips);

* For rates < MCS8 (and legacy rates) there's further TX-side trickery
that can be going on which I'm not too up-to-date on. For example,
some (all?) of the 11n chips allow you to optionally transmit MCS0-7
using STBC. But iirc, STBC is only enabled for 1-stream TX.

In short, if you've got all the radios enabled  for RX and ath9k is
enabling both/all radio chains when TX'ing, I think the answer is
"yes" for you. :)



Adrian

On 16 February 2011 22:47, Baldomero Coll <baldo.ath9k@gmail.com> wrote:
> I'm not sure, but I've read somewhere that by default the two antennas are
> used.
> It is true that I'm not interested in selecting the number of antennas, what
> I really want is that the MIMO capability is exploited if I'm using 802.11n
> HT IBSS operation mode.
> Can someone confirm that by default the two antennas (spatial diversity) are
> being used when we create the HT IBSS network?
>
> 2011/2/16 Mohammed Shafi <shafi.ath9k@gmail.com>
>>
>> On Tue, Feb 15, 2011 at 2:35 PM, Baldomero Coll <baldo.ath9k@gmail.com>
>> wrote:
>> > Hello,
>> >
>> > Can you please tell me how do you select one o two antennas?
>>
>> I don't know why you should do that. I guess changing the tx/rx
>> chainmask will do after it was read from eeprom.
>>
>> >
>> > I'm using a similar setting than you:
>> > Linux kernel: 2.6.32-28-generic-pae.
>> > Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the patch
>> > suggested by
>> > Alex.
>> > Radio card: Ubiquiti SR71x
>> >
>> > Thanks in advance,
>> > Baldomero
>> >>
>> >> Hi all,
>> >>
>> >> I would like to confirm my findings. My test platform configurations
>> >> are
>> >> follow.
>> >> Board: pcengine alix3d2
>> >> Linux kernel: 2.6.35 from linux-wireless git
>> >> Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the patch
>> >> suggested by Alex.
>> >> Radio card: Ubiqiti SR71a on channel 36 with HT40+
>> >> Measurement tool and settings: Iperf, UDP, 100Mb offered load
>> >>
>> >> Recored throughput: 50-54Mbps (one antenna); 78-80Mbps (two or three
>> >> antennas).
>> >
>> >
>> > _______________________________________________
>> > ath9k-devel mailing list
>> > ath9k-devel at lists.ath9k.org
>> > https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>> >
>> >
>
>
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel at lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>
>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

<br>
* If your RX chainmask has &gt;1 radio enabled, you&#39;ll always be doing<=
br>
receive-side &quot;diversity&quot; (which is really &quot;combining&quot; (=
MRC) if I<br>
understand the technology correctly on multi-radio atheros 11n cards);<br>
* If your TX chainmask has &gt;1 radio enabled and the TX descriptor has<br=
>
the relevant chainmask bits set, you should be transmitting on both<br>
antennas regardless of the rate. I honestly haven&#39;t verified it (I&#39;=
ve<br>
only verified that behaviour for transmitting legacy rates out of the<br>
11n chips);<br>
<br>
* For rates &lt; MCS8 (and legacy rates) there&#39;s further TX-side tricke=
ry<br>
that can be going on which I&#39;m not too up-to-date on. For example,<br>
some (all?) of the 11n chips allow you to optionally transmit MCS0-7<br>
using STBC. But iirc, STBC is only enabled for 1-stream TX.<br>
<br>
In short, if you&#39;ve got all the radios enabled =C2=A0for RX and ath9k i=
s<br>
enabling both/all radio chains when TX&#39;ing, I think the answer is<br>
&quot;yes&quot; for you. :)<br>
<br>
Adrian<br>
<br>
On 16 February 2011 22:47, Baldomero Coll &lt;<a href=3D"mailto:baldo.ath9k=
@gmail.com">baldo.ath9k at gmail.com</a>&gt; wrote:<br>
&gt; I&#39;m not sure, but I&#39;ve read somewhere that by default the two =
antennas are<br>
&gt; used.<br>
&gt; It is true that I&#39;m not interested in selecting the number of ante=
nnas, what<br>
&gt; I really want is that the MIMO capability is exploited if I&#39;m usin=
g 802.11n<br>
&gt; HT IBSS operation mode.<br>
&gt; Can someone confirm that by default the two antennas (spatial diversit=
y) are<br>
&gt; being used when we create the HT IBSS network?<br>
&gt;<br>
&gt; 2011/2/16 Mohammed Shafi &lt;<a href=3D"mailto:shafi.ath9k@gmail.com">=
shafi.ath9k at gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Tue, Feb 15, 2011 at 2:35 PM, Baldomero Coll &lt;<a href=3D"mai=
lto:baldo.ath9k@gmail.com">baldo.ath9k at gmail.com</a>&gt;<br>
&gt;&gt; wrote:<br>
&gt;&gt; &gt; Hello,<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Can you please tell me how do you select one o two antennas?<=
br>
&gt;&gt;<br>
&gt;&gt; I don&#39;t know why you should do that. I guess changing the tx/r=
x<br>
&gt;&gt; chainmask will do after it was read from eeprom.<br>
&gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I&#39;m using a similar setting than you:<br>
&gt;&gt; &gt; Linux kernel: 2.6.32-28-generic-pae.<br>
&gt;&gt; &gt; Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the pat=
ch<br>
&gt;&gt; &gt; suggested by<br>
&gt;&gt; &gt; Alex.<br>
&gt;&gt; &gt; Radio card: Ubiquiti SR71x<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Thanks in advance,<br>
&gt;&gt; &gt; Baldomero<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Hi all,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I would like to confirm my findings. My test platform con=
figurations<br>
&gt;&gt; &gt;&gt; are<br>
&gt;&gt; &gt;&gt; follow.<br>
&gt;&gt; &gt;&gt; Board: pcengine alix3d2<br>
&gt;&gt; &gt;&gt; Linux kernel: 2.6.35 from linux-wireless git<br>
&gt;&gt; &gt;&gt; Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the=
 patch<br>
&gt;&gt; &gt;&gt; suggested by Alex.<br>
&gt;&gt; &gt;&gt; Radio card: Ubiqiti SR71a on channel 36 with HT40+<br>
&gt;&gt; &gt;&gt; Measurement tool and settings: Iperf, UDP, 100Mb offered =
load<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Recored throughput: 50-54Mbps (one antenna); 78-80Mbps (t=
wo or three<br>
&gt;&gt; &gt;&gt; antennas).<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; ath9k-devel mailing list<br>
&gt;&gt; &gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at li=
sts.ath9k.org</a><br>
&gt;&gt; &gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-dev=
el" target=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel<=
/a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; ath9k-devel mailing list<br>
&gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at lists.ath9k=
.org</a><br>
&gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" targe=
t=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
&gt;<br>
&gt;<br>
</blockquote></div><br>

--002215048f672c1ad2049c7703f8--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

<br>
* If your RX chainmask has &gt;1 radio enabled, you&#39;ll always be doing<=
br>
receive-side &quot;diversity&quot; (which is really &quot;combining&quot; (=
MRC) if I<br>
understand the technology correctly on multi-radio atheros 11n cards);<br>
* If your TX chainmask has &gt;1 radio enabled and the TX descriptor has<br=
>
the relevant chainmask bits set, you should be transmitting on both<br>
antennas regardless of the rate. I honestly haven&#39;t verified it (I&#39;=
ve<br>
only verified that behaviour for transmitting legacy rates out of the<br>
11n chips);<br>
<br>
* For rates &lt; MCS8 (and legacy rates) there&#39;s further TX-side tricke=
ry<br>
that can be going on which I&#39;m not too up-to-date on. For example,<br>
some (all?) of the 11n chips allow you to optionally transmit MCS0-7<br>
using STBC. But iirc, STBC is only enabled for 1-stream TX.<br>
<br>
In short, if you&#39;ve got all the radios enabled =A0for RX and ath9k is<b=
r>
enabling both/all radio chains when TX&#39;ing, I think the answer is<br>
&quot;yes&quot; for you. :)<br>
<br>
Adrian<br>
<br>
On 16 February 2011 22:47, Baldomero Coll &lt;<a href=3D"mailto:baldo.ath9k=
@gmail.com" target=3D"_blank">baldo.ath9k at gmail.com</a>&gt; wrote:<br>
&gt; I&#39;m not sure, but I&#39;ve read somewhere that by default the two =
antennas are<br>
&gt; used.<br>
&gt; It is true that I&#39;m not interested in selecting the number of ante=
nnas, what<br>
&gt; I really want is that the MIMO capability is exploited if I&#39;m usin=
g 802.11n<br>
&gt; HT IBSS operation mode.<br>
&gt; Can someone confirm that by default the two antennas (spatial diversit=
y) are<br>
&gt; being used when we create the HT IBSS network?<br>
&gt;<br>
&gt; 2011/2/16 Mohammed Shafi &lt;<a href=3D"mailto:shafi.ath9k@gmail.com" =
target=3D"_blank">shafi.ath9k at gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Tue, Feb 15, 2011 at 2:35 PM, Baldomero Coll &lt;<a href=3D"mai=
lto:baldo.ath9k@gmail.com" target=3D"_blank">baldo.ath9k at gmail.com</a>&gt;<=
br>
&gt;&gt; wrote:<br>
&gt;&gt; &gt; Hello,<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Can you please tell me how do you select one o two antennas?<=
br>
&gt;&gt;<br>
&gt;&gt; I don&#39;t know why you should do that. I guess changing the tx/r=
x<br>
&gt;&gt; chainmask will do after it was read from eeprom.<br>
&gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I&#39;m using a similar setting than you:<br>
&gt;&gt; &gt; Linux kernel: 2.6.32-28-generic-pae.<br>
&gt;&gt; &gt; Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the pat=
ch<br>
&gt;&gt; &gt; suggested by<br>
&gt;&gt; &gt; Alex.<br>
&gt;&gt; &gt; Radio card: Ubiquiti SR71x<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Thanks in advance,<br>
&gt;&gt; &gt; Baldomero<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Hi all,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I would like to confirm my findings. My test platform con=
figurations<br>
&gt;&gt; &gt;&gt; are<br>
&gt;&gt; &gt;&gt; follow.<br>
&gt;&gt; &gt;&gt; Board: pcengine alix3d2<br>
&gt;&gt; &gt;&gt; Linux kernel: 2.6.35 from linux-wireless git<br>
&gt;&gt; &gt;&gt; Driver: compat-wireless-2011-01-17 and iw-0.9.21 with the=
 patch<br>
&gt;&gt; &gt;&gt; suggested by Alex.<br>
&gt;&gt; &gt;&gt; Radio card: Ubiqiti SR71a on channel 36 with HT40+<br>
&gt;&gt; &gt;&gt; Measurement tool and settings: Iperf, UDP, 100Mb offered =
load<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Recored throughput: 50-54Mbps (one antenna); 78-80Mbps (t=
wo or three<br>
&gt;&gt; &gt;&gt; antennas).<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; ath9k-devel mailing list<br>
&gt;&gt; &gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_bla=
nk">ath9k-devel at lists.ath9k.org</a><br>
&gt;&gt; &gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-dev=
el" target=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel<=
/a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; ath9k-devel mailing list<br>
&gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_blank">ath9k=
-devel at lists.ath9k.org</a><br>
&gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" targe=
t=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
&gt;<br>
&gt;<br>
</blockquote></div></div></div><br>
</blockquote></div><br></div>

--0016362847b84c7571049c7ca7bc--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

interrupt earlier. For example, I send 1st frame  with rate MCS 1 and 2nd
frame with MCS 2, but some time I can get hw tx interrupt for second frame
ealier than the first. I think this may relate to the aggregation. So I have
tried set ATH_AMPDU_SUBFRAME_DEFAULT to 1, but that doesn't help. Then I
tried substitute ath_tx_send_ampdu with ath_tx_send_normal in
ath_tx_start_dma, and I find that disorder issue doesn't happen again. Also,
I find that
in the disorder case, it looks like that transmitter triggers
ath_tx_txqaddbuf for 1st then for 2nd, however, immediately ath_tx_txqaddbuf
is triggered again and for 2nd first, and 1st. But from tx_info.status, I
find that both 1st and 2nd frame is transmitted once and successfully
received.

Moreover, the transmitter may send 1st aggregation frame with sequence from
0-31, and send 2nd aggregation frame with sequence 32-63 immediately, and
then based on the tx_info.status, transmitter send the un-acked frame in the
later frame. In this case, I mean, transmitter can send the 2nd aggregation
frame without knowing the result for the first one, is this right?

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

when the transmitter receive the hw tx interrupt, is there anything wrong or
missing? Actually, I don't quite understand how aggregation works in ath9k,
could you give some information?

Thank you for your time on this.

Best regards,
Jerry Zhao

--0016e649cdb2575291049ce47042
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Dear all,<br>Good day.<br>I have got a question about disorder of hw tx int=
erupt. I am looking for your helps. Thanks in advance.<br>I am using D-link=
 652 and ubuntu 10.04 as my platform.<br>I am running some tests, I set fra=
mes with an cyclic increasing rate from MCS 0 - MCS 15, it&#39;s done per f=
rame. After the transmitter sends the frame, it gets a hw tx interrupt afte=
r successful transmission or no ack.<br>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

rupt earlier. For example, I send 1st frame=A0 with rate MCS 1 and 2nd fram=
e with MCS 2, but some time I can get hw tx interrupt for second frame eali=
er than the first. I think this may relate to the aggregation. So I have tr=
ied set ATH_AMPDU_SUBFRAME_DEFAULT to 1, but that doesn&#39;t help. Then I =
tried substitute ath_tx_send_ampdu with ath_tx_send_normal in ath_tx_start_=
dma, and I find that disorder issue doesn&#39;t happen again. Also, I find =
that <br>
in the disorder case, it looks like that transmitter triggers ath_tx_txqadd=
buf for 1st then for 2nd, however, immediately ath_tx_txqaddbuf is triggere=
d again and for 2nd first, and 1st. But from tx_info.status, I find that bo=
th 1st and 2nd frame is transmitted once and successfully received.<br>
<br>Moreover, the transmitter may send 1st aggregation frame with sequence =
from 0-31, and send 2nd aggregation frame with sequence 32-63 immediately, =
and then based on the tx_info.status, transmitter send the un-acked frame i=
n the later frame. In this case, I mean, transmitter can send the 2nd aggre=
gation frame without knowing the result for the first one, is this right?<b=
r>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

hen the transmitter receive the hw tx interrupt, is there anything wrong or=
 missing? Actually, I don&#39;t quite understand how aggregation works in a=
th9k, could you give some information? <br>
<br>Thank you for your time on this.<br><br>Best regards,<br>Jerry Zhao<br>

--0016e649cdb2575291049ce47042--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

rupt earlier. For example, I send 1st frame=A0 with rate MCS 1 and 2nd fram=
e with MCS 2, but some time I can get hw tx interrupt for second frame eali=
er than the first. I think this may relate to the aggregation. So I have tr=
ied set ATH_AMPDU_SUBFRAME_DEFAULT to 1, but that doesn&#39;t help. Then I =
tried substitute ath_tx_send_ampdu with ath_tx_send_normal in ath_tx_start_=
dma, and I find that disorder issue doesn&#39;t happen again. Also, I find =
that <br>

in the disorder case, it looks like that transmitter triggers ath_tx_txqadd=
buf for 1st then for 2nd, however, immediately ath_tx_txqaddbuf is triggere=
d again and for 2nd first, and 1st. But from tx_info.status, I find that bo=
th 1st and 2nd frame is transmitted once and successfully received.<br>

<br>Moreover, the transmitter may send 1st aggregation frame with sequence =
from 0-31, and send 2nd aggregation frame with sequence 32-63 immediately, =
and then based on the tx_info.status, transmitter send the un-acked frame i=
n the later frame. In this case, I mean, transmitter can send the 2nd aggre=
gation frame without knowing the result for the first one, is this right?<b=
r>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

hen the transmitter receive the hw tx interrupt, is there anything wrong or=
 missing? Actually, I don&#39;t quite understand how aggregation works in a=
th9k, could you give some information? <br>

<br>Thank you for your time on this.<br><br>Best regards,<br>Jerry Zhao<br>
<br>_______________________________________________<br>
ath9k-devel mailing list<br>
<a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at lists.ath9k.org<=
/a><br>
<a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" target=3D"=
_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
<br></blockquote></div><br></div></div>

--bcaec53f8e215e2cfc049ce55219--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

rupt earlier. For example, I send 1st frame=A0 with rate MCS 1 and 2nd fram=
e with MCS 2, but some time I can get hw tx interrupt for second frame eali=
er than the first. I think this may relate to the aggregation. So I have tr=
ied set ATH_AMPDU_SUBFRAME_DEFAULT to 1, but that doesn&#39;t help. Then I =
tried substitute ath_tx_send_ampdu with ath_tx_send_normal in ath_tx_start_=
dma, and I find that disorder issue doesn&#39;t happen again. Also, I find =
that <br>

in the disorder case, it looks like that transmitter triggers ath_tx_txqadd=
buf for 1st then for 2nd, however, immediately ath_tx_txqaddbuf is triggere=
d again and for 2nd first, and 1st. But from tx_info.status, I find that bo=
th 1st and 2nd frame is transmitted once and successfully received.<br>

<br>Moreover, the transmitter may send 1st aggregation frame with sequence =
from 0-31, and send 2nd aggregation frame with sequence 32-63 immediately, =
and then based on the tx_info.status, transmitter send the un-acked frame i=
n the later frame. In this case, I mean, transmitter can send the 2nd aggre=
gation frame without knowing the result for the first one, is this right?<b=
r>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

hen the transmitter receive the hw tx interrupt, is there anything wrong or=
 missing? Actually, I don&#39;t quite understand how aggregation works in a=
th9k, could you give some information? <br>

<br>Thank you for your time on this.<br><br>Best regards,<br>Jerry Zhao<br>
</blockquote></div><br>

--0016e659f780473917049cfe2f87--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

discarded. But for ping packet __ieee80211_parse_tx_radiotap function
returns false. Surprisingly radtap_hdr_len is getting printed to be 65535,
which I assumed will be 0 at this point.

So in function  ieee80211_monitor_start_xmit(), i tried following
approaches:
1) pulling radio tap header from skb and disabling RADIOTAP flag and send
rest of skb as it is.
2) allocate a new skb of size  ieee80211_hdr and assigning  first 2 bytes of
skb->data to  0x08 and 0x02 and pass this skb to the called functions.
However i could not see any activity over the air. :(.
I am not using packetspammer like utlity to send packets to driver, but just
ping packets.
Any suggestion over this will be appreciated.

Thanks
-Sagar

--20cf3079bdf4c2e5cd049d932c1c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi, <br>For my research, I want to send the packet at a specified time. I g=
uess monitor mode is suitable for this. <br>From code it looks like in moni=
tor mode the radiotap header is parsed and discarded. But for ping packet _=
_ieee80211_parse_tx_radiotap function returns false. Surprisingly radtap_hd=
r_len is getting printed to be 65535, which I assumed will be 0 at this poi=
nt.<br>

<br>So in function=A0 ieee80211_monitor_start_xmit(), i tried following app=
roaches:<br>1) pulling radio tap header from skb and disabling RADIOTAP fla=
g and send rest of skb as it is. <br>2) allocate a new skb of size=A0 ieee8=
0211_hdr and assigning=A0 first 2 bytes of skb-&gt;data to=A0 0x08 and 0x02=
 and pass this skb to the called functions.<br>

However i could not see any activity over the air. :(. <br>I am not using p=
acketspammer like utlity to send packets to driver, but just ping packets.<=
br>Any suggestion over this will be appreciated. <br><br>Thanks<br>-Sagar<b=
r>


--20cf3079bdf4c2e5cd049d932c1c--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2010-12-19 23:59 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2010-12-19 23:59 UTC (permalink / raw)
  To: ath9k-devel

MIMO, but with only two spatial streams, so it should handle MCS0
through MCS15.  Check the output of "iw list" for a line like the
following:

HT TX/RX MCS rate indexes supported: 0-15

It is possible for a card to support multiple spatial streams without
having support for space-time block coding.

-Brian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-01-05 11:39 davidgg
  0 siblings, 0 replies; 409+ messages in thread
From: davidgg @ 2011-01-05 11:39 UTC (permalink / raw)
  To: kvm

Hi all

I'm a computer science student from germany interested in
virtualization technologies and given I have some free time I'd
like to dig into kvm modding, maybe even actual development ;-)

I've been trying to understand the kvm mmu, with a special regard
to paging structures.
I'm having a hard time finding the code that is responsible for
creating the tdp (epml4, epdpt, epd and ept on intel i.e.) 
structures, any
hint(s)?
Using some debug output I'm getting tdp_page_faul(s) where the
paging level is 1, how can this be? does this mean all pages are
2MB pages and there are no page tables with 4 kbyte pages at all?

thanks a lot in advance and kind regards,
David 


^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-01-13  9:13 Uwe Kleine-König
  0 siblings, 0 replies; 409+ messages in thread
From: Uwe Kleine-König @ 2011-01-13  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

<jason77.wang@gmail.com>
Bcc: 
Subject: Re: i.MX & IRQF_ONESHOT
Reply-To: 
In-Reply-To: <4D2EB6EF.7030608@eukrea.com>

Hello,

[adding tglx who AFAIK invented threaded irqs and the people involved
in 2991a1ca6e9b to Cc]

On Thu, Jan 13, 2011 at 09:25:19AM +0100, Eric B?nard wrote:
> while testing 2.6.37 on our i.MX27 based board - code in
> arch/arm/mach-imx/eukrea_mbimx27-baseboard.c - I noticed the
> touchscreen controller (ADS7846) doesn't work anymore.
> 
> A few IRQ are generated when probing for the chipset and starting
> calibration (usually first point works), then nothing more (even if
> the IRQ signals is generated as seen on the scope, the irq count
> doesn't increase anymore and stays <= 4 and no data is reported to
> the input layer).
> 
> drivers/input/touchscreen/ads7846.c was switched to threaded IRQ in
> commit 2991a1ca6e9b13b639a82c0eec0cbc191bf1f42f where was added :
> irq_flags |= IRQF_ONESHOT;
AFAIK this is how threaded irq usually work.  The irq should get
reenabled by irq_thread -> irq_finalize_oneshot then.

> Commenting out this line in the ads7846 driver makes it work again.
> Am I missing something obvious or is there a reason for IRQF_ONESHOT
> creating trouble with gpio irq or SPI on i.MX ?
I don't know.  Is the irq masked?  pending?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-02-26  6:20 Aldyth Maharsha
  0 siblings, 0 replies; 409+ messages in thread
From: Aldyth Maharsha @ 2011-02-26  6:20 UTC (permalink / raw)
  To: kernelnewbies


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110226/cfa13c75/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-03-01 14:02 Javier Martin
  0 siblings, 0 replies; 409+ messages in thread
From: Javier Martin @ 2011-03-01 14:02 UTC (permalink / raw)
  To: linux-arm-kernel

This series of patches provides support for audio in Visstrim_M10 boards.

This second version has some fixes in the aic32x4 codec driver as asked by
Mark Brown.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-03-22 18:13 nijil yes
  0 siblings, 0 replies; 409+ messages in thread
From: nijil yes @ 2011-03-22 18:13 UTC (permalink / raw)
  To: kernelnewbies

Hi,
could anyone mention what are the projects available for beginners to do in gsoc 
this time from kernel newbies.I am comfortable with c/c++.I would be glad if 
someone could suggest a few

Regards,
Nijil



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110322/1858b878/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-04-07  5:55 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-04-07  5:55 UTC (permalink / raw)
  To: ath9k-devel

the silicon itself at power-on. 'abcd' sounds a bit too convenient to be
what's in EEPROM/OTP; so maybe it's a default value in the silicon?

(All just conjecture here at this point.)


Adrian

On 10 April 2011 23:17, Mohammed Shafi <shafi.ath9k@gmail.com> wrote:

> On Sun, Apr 10, 2011 at 8:41 PM, Peter Stuge <peter@stuge.se> wrote:
> > Mohammed Shafi wrote:
> >> > Is this a serious proposal from Atheros, or just your attempt at
> >> > a quick fix?
> >>
> >> No! its purely a personal idea (am completely responsible for the
> >> mistake),and I will take a look at it carefully to fix this.
> >
> > Sorry, I didn't mean that you made a mistake, just that the
> > suggestion probably would not get us closer to the actual issue.
> >
> > Bus level issues are indeed difficult. :\
>
> thanks, i did not know that. thought simple as adding another device id.
> >
> >
> >> > A device having an unexpected PCI id means that something is really
> >> > wrong in the device or on the bus, and the solution is rarely to
> >> > pretend that it didn't happen.]
> >>
> >> Yeah I can see that, hoping that I may get a correct Device ID from
> >> the reporter. I dont think 'abcd' is a proper vendor id.
> >
> > Yes, it's easy to spot. The question is how we can find out *why*
> > this happened, so that this error case can be prevented.
>
> Yes sure.
> >
> >
> >> > Since this card should work fine in principle, maybe it's some issue
> >> > with missing, or wrong, firmware stored on the Linux system.
> >>
> >> AR9382 does not seems to have firmware
> >
> > Aha! That's only for the USB devices maybe. I don't know much detail
> > for these latest devices.
> >
> currently only  ath9k_htc needs firmware.
>
> >
> >> and you have any idea what might went wrong.
> >
> > Sorry, I don't understand what you mean here.
>
> Your suggestions about what might have went wrong, as you had already
> told it might be a bus level issue.
>
> >
> >
> >> Also why its detected as Ethernet Controller rather than
> >> Network controller.
> >
> > This string comes from the pciutils package and could easily have
> > changed. Better look at the numerical device class code, which is
> > what is read from hardware.
>
> thanks, I will look into that.
>
> >
> > But I expect that when one thing in config space (device id) is bogus
> > then the rest of config space is also quite possibly bogus, for the
> > same reason, whatever it is.
> >
> >
> > //Peter
> > _______________________________________________
> > ath9k-devel mailing list
> > ath9k-devel at lists.ath9k.org
> > https://lists.ath9k.org/mailman/listinfo/ath9k-devel
> >
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel at lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>

--20cf300256ecb39f7b04a09232d4
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Incorrect or misplaced EEPROM/OTP data, perhaps?<div><br></div><div>From wh=
at I gather, the PCI ID on earlier devices is loaded out of EEPROM by the s=
ilicon itself at power-on. &#39;abcd&#39; sounds a bit too convenient to be=
 what&#39;s in EEPROM/OTP; so maybe it&#39;s a default value in the silicon=
?</div>
<div><br></div><div>(All just conjecture here at this point.)</div><div><br=
></div><div><br></div><div>Adrian</div><div><br><div class=3D"gmail_quote">=
On 10 April 2011 23:17, Mohammed Shafi <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:shafi.ath9k@gmail.com">shafi.ath9k at gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex;"><div class=3D"im">On Sun, Apr 10, 2011 at 8=
:41 PM, Peter Stuge &lt;<a href=3D"mailto:peter@stuge.se">peter at stuge.se</a=
>&gt; wrote:<br>

&gt; Mohammed Shafi wrote:<br>
&gt;&gt; &gt; Is this a serious proposal from Atheros, or just your attempt=
 at<br>
&gt;&gt; &gt; a quick fix?<br>
&gt;&gt;<br>
&gt;&gt; No! its purely a personal idea (am completely responsible for the<=
br>
&gt;&gt; mistake),and I will take a look at it carefully to fix this.<br>
&gt;<br>
&gt; Sorry, I didn&#39;t mean that you made a mistake, just that the<br>
&gt; suggestion probably would not get us closer to the actual issue.<br>
&gt;<br>
&gt; Bus level issues are indeed difficult. :\<br>
<br>
</div>thanks, i did not know that. thought simple as adding another device =
id.<br>
<div class=3D"im">&gt;<br>
&gt;<br>
&gt;&gt; &gt; A device having an unexpected PCI id means that something is =
really<br>
&gt;&gt; &gt; wrong in the device or on the bus, and the solution is rarely=
 to<br>
&gt;&gt; &gt; pretend that it didn&#39;t happen.]<br>
&gt;&gt;<br>
&gt;&gt; Yeah I can see that, hoping that I may get a correct Device ID fro=
m<br>
&gt;&gt; the reporter. I dont think &#39;abcd&#39; is a proper vendor id.<b=
r>
&gt;<br>
&gt; Yes, it&#39;s easy to spot. The question is how we can find out *why*<=
br>
&gt; this happened, so that this error case can be prevented.<br>
<br>
</div>Yes sure.<br>
<div class=3D"im">&gt;<br>
&gt;<br>
&gt;&gt; &gt; Since this card should work fine in principle, maybe it&#39;s=
 some issue<br>
&gt;&gt; &gt; with missing, or wrong, firmware stored on the Linux system.<=
br>
&gt;&gt;<br>
&gt;&gt; AR9382 does not seems to have firmware<br>
&gt;<br>
&gt; Aha! That&#39;s only for the USB devices maybe. I don&#39;t know much =
detail<br>
&gt; for these latest devices.<br>
&gt;<br>
</div>currently only =A0ath9k_htc needs firmware.<br>
<div class=3D"im"><br>
&gt;<br>
&gt;&gt; and you have any idea what might went wrong.<br>
&gt;<br>
&gt; Sorry, I don&#39;t understand what you mean here.<br>
<br>
</div>Your suggestions about what might have went wrong, as you had already=
<br>
told it might be a bus level issue.<br>
<div class=3D"im"><br>
&gt;<br>
&gt;<br>
&gt;&gt; Also why its detected as Ethernet Controller rather than<br>
&gt;&gt; Network controller.<br>
&gt;<br>
&gt; This string comes from the pciutils package and could easily have<br>
&gt; changed. Better look at the numerical device class code, which is<br>
&gt; what is read from hardware.<br>
<br>
</div>thanks, I will look into that.<br>
<div><div></div><div class=3D"h5"><br>
&gt;<br>
&gt; But I expect that when one thing in config space (device id) is bogus<=
br>
&gt; then the rest of config space is also quite possibly bogus, for the<br=
>
&gt; same reason, whatever it is.<br>
&gt;<br>
&gt;<br>
&gt; //Peter<br>
&gt; _______________________________________________<br>
&gt; ath9k-devel mailing list<br>
&gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at lists.ath9k=
.org</a><br>
&gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" targe=
t=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
&gt;<br>
_______________________________________________<br>
ath9k-devel mailing list<br>
<a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at lists.ath9k.org<=
/a><br>
<a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" target=3D"=
_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
</div></div></blockquote></div><br></div>

--20cf300256ecb39f7b04a09232d4--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-04-07  5:55 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-04-07  5:55 UTC (permalink / raw)
  To: ath9k-devel

ATTITUDE ADJUSTMENT (bleeding edge, r26358) ----------

root at jv-2400-ap1:~# uptime
 16:57:14 up 3 days, 14:15, load average: 0.00, 0.01, 0.04
root at jv-2400-ap1:~# iw wlan0 station dump | grep -i failed
	tx failed:	0
	tx failed:	0
	tx failed:	0
	tx failed:	0
	tx failed:	0
	tx failed:	0
	tx failed:	7
	tx failed:	0
	tx failed:	0
root at jv-2400-ap1:~#

-- 
Larry Vaden, CoFounder
Internet Texoma, Inc.
Serving Rural Texomaland Since 1995
We Care About Your Connection!

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-04-07  5:55 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-04-07  5:55 UTC (permalink / raw)
  To: ath9k-devel

-------------------------------
Device Instance Id:
PCI\VEN_168C&DEV_0030&SUBSYS_3116168C&REV_01\4&492937F&0&00E2

Hardware Ids:
PCI\VEN_168C&DEV_0030&SUBSYS_3116168C&REV_01
PCI\VEN_168C&DEV_0030&SUBSYS_3116168C
PCI\VEN_168C&DEV_0030&CC_028000
PCI\VEN_168C&DEV_0030&CC_0280

Compatible Ids:
PCI\VEN_168C&DEV_0030&REV_01
PCI\VEN_168C&DEV_0030
PCI\VEN_168C&CC_028000
PCI\VEN_168C&CC_0280
PCI\VEN_168C
PCI\CC_028000
PCI\CC_0280

Matching Device Id:
pci\ven_168c&dev_0030&subsys_3116168c


Here is the interesting bit, when I first hooked this card I booted my=
 machine in Ubuntu I saw the same 168c:ABCD. After using it under Window=
s, I booted in to Linux today and found that it is reporting the expecte=
d IDs. Now ath9k works right out of the box, no Vendor ID hacking requir=
ed. I am using it as station right now. The other card is in a different=
 machine. I will try to swap the cards to verify my theory. I am thinkin=
g the Windows driver applied a firmware update to the card. Or, the othe=
r card skipped quality checks and has bogus EEPROM data. Any thoughts?

0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300=
 Wireless LAN adaptor [168c:0030] (rev 01)

lspci -vvvnn returns

0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300=
 Wireless LAN adaptor [168c:0030] (rev 01)
	Subsystem: Atheros Communications Inc. Device [168c:3116]
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Ste=
pping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfast >TAbort- <TAbor=
t- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 18
	Region 0: Memory at fa000000 (64-bit, non-prefetchable) [size=3D128K]
	[virtual] Expansion ROM@f2000000 [disabled] [size=3D64K]
	Capabilities: <access denied>
	Kernel driver in use: ath9k
	Kernel modules: ath9k


Hasan R.

-----Original Message-----
From: Mohammed Shafi [mailto:shafi.ath9k at gmail.com]=20
Sent: Tuesday, April 12, 2011 7:47 AM
To: Hasan Rashid
Cc: ath9k-devel at lists.ath9k.org
Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd

On Mon, Apr 11, 2011 at 11:24 PM, Hasan Rashid <hrashad@avionica.com>=
 wrote:
>
> I have attached the driver load output in dmesg.
>
> By the way why does AR9382 require Kernel 2.6.36 or higher? Can you=20
> list the major requirements?

because the hardware code(HAL) will be present from that kernel version=
 only.
>
> Hasan R.
>
> -----Original Message-----
> From: ath9k-devel-bounces at lists.ath9k.org
> [mailto:ath9k-devel-bounces at lists.ath9k.org] On Behalf Of Peter Stuge
> Sent: Monday, April 11, 2011 12:20 PM
> To: ath9k-devel at lists.ath9k.org
> Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd
>
> Mohammed Shafi wrote:
>> to make sure that HT is configured in driver please do this
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/hw.c
>> b/drivers/net/wireless/ath/ath9k/hw.c
>> index 1b5bd13..720a866 100644
>> --- a/drivers/net/wireless/ath/ath9k/hw.c
>> +++ b/drivers/net/wireless/ath/ath9k/hw.c
>> @@ -1855,6 +1855,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
>> =A0 =A0 =A0 =A0 else
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap->hw_caps &=3D ~ATH9K_HW_CAP_HT;
>>
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap->hw_caps |=3D ATH9K_HW_CAP_HT;
>> +
>
> The indentation is off, or do you mean to include the added line only=20
> within the else block? If so, remember to add braces.
>
>
> //Peter
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel at lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>
> This communication contains information that may be confidential or=20
> privileged. The information is solely intended for the use of the addr=
essee. If you are not the intended recipient, be advised that any disclo=
sure, copy, distribution, or use of the contents of this communication=
 is prohibited. If you have received this communication in error, please=
 immediately notify the sender by telephone or by electronic mail.
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel at lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>
>


This communication contains information that may be confidential or priv=
ileged. The information is solely intended for the use of the addressee.=
 If you are not the intended recipient, be advised that any disclosure,=
 copy, distribution, or use of the contents of this communication is pro=
hibited. If you have received this communication in
error, please immediately notify the sender by telephone or by electroni=
c mail.
------_=_NextPart_001_01CBF922.E6EB9838
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; charset=3Diso-88=
59-1">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version 6.5.7654.=
12">
<TITLE>RE: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=3D2>I put another Sparklan card in a Windows XP machine=
 and following are the device ids reported by the Atheros driver on Wind=
ows. It seems it is reporting the correct 0x168c, and 0x0030.<BR>
<BR>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-04-07  5:55 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-04-07  5:55 UTC (permalink / raw)
  To: ath9k-devel

-------------------------------<BR>
Device Instance Id:<BR>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C&amp;REV_01\4&amp;492937F&a=
mp;0&amp;00E2<BR>
<BR>
Hardware Ids:<BR>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C&amp;REV_01<BR>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C<BR>
PCI\VEN_168C&amp;DEV_0030&amp;CC_028000<BR>
PCI\VEN_168C&amp;DEV_0030&amp;CC_0280<BR>
<BR>
Compatible Ids:<BR>
PCI\VEN_168C&amp;DEV_0030&amp;REV_01<BR>
PCI\VEN_168C&amp;DEV_0030<BR>
PCI\VEN_168C&amp;CC_028000<BR>
PCI\VEN_168C&amp;CC_0280<BR>
PCI\VEN_168C<BR>
PCI\CC_028000<BR>
PCI\CC_0280<BR>
<BR>
Matching Device Id:<BR>
pci\ven_168c&amp;dev_0030&amp;subsys_3116168c<BR>
<BR>
<BR>
Here is the interesting bit, when I first hooked this card I booted my=
 machine in Ubuntu I saw the same 168c:ABCD. After using it under Window=
s, I booted in to Linux today and found that it is reporting the expecte=
d IDs. Now ath9k works right out of the box, no Vendor ID hacking requir=
ed. I am using it as station right now. The other card is in a different=
 machine. I will try to swap the cards to verify my theory. I am thinkin=
g the Windows driver applied a firmware update to the card. Or, the othe=
r card skipped quality checks and has bogus EEPROM data. Any thoughts?<B=
R>
<BR>
0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300=
 Wireless LAN adaptor [168c:0030] (rev 01)<BR>
<BR>
lspci -vvvnn returns<BR>
<BR>
0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300=
 Wireless LAN adaptor [168c:0030] (rev 01)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subsystem: Atheros Communicat=
ions Inc. Device [168c:3116]<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Control: I/O+ Mem+ BusMaster+=
 SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-=
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Status: Cap+ 66MHz- UDF- Fast=
B2B- ParErr- DEVSEL=3Dfast &gt;TAbort- &lt;TAbort- &lt;MAbort- &gt;SERR-=
 &lt;PERR- INTx-<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Latency: 0, Cache Line Size:=
 64 bytes<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Interrupt: pin A routed to=
 IRQ 18<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Region 0: Memory at fa000000=
 (64-bit, non-prefetchable) [size=3D128K]<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [virtual] Expansion ROM at=
 f2000000 [disabled] [size=3D64K]<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Capabilities: &lt;access deni=
ed&gt;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Kernel driver in use: ath9k<B=
R>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Kernel modules: ath9k<BR>
<BR>
<BR>
Hasan R.<BR>
<BR>
-----Original Message-----<BR>
From: Mohammed Shafi [<A HREF=3D"mailto:shafi.ath9k@gmail.com">mailto:sh=
afi.ath9k at gmail.com</A>]<BR>
Sent: Tuesday, April 12, 2011 7:47 AM<BR>
To: Hasan Rashid<BR>
Cc: ath9k-devel at lists.ath9k.org<BR>
Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd<BR>
<BR>
On Mon, Apr 11, 2011 at 11:24 PM, Hasan Rashid &lt;hrashad at avionica.com&=
gt; wrote:<BR>
&gt;<BR>
&gt; I have attached the driver load output in dmesg.<BR>
&gt;<BR>
&gt; By the way why does AR9382 require Kernel 2.6.36 or higher? Can you=
<BR>
&gt; list the major requirements?<BR>
<BR>
because the hardware code(HAL) will be present from that kernel version=
 only.<BR>
&gt;<BR>
&gt; Hasan R.<BR>
&gt;<BR>
&gt; -----Original Message-----<BR>
&gt; From: ath9k-devel-bounces at lists.ath9k.org<BR>
&gt; [<A HREF=3D"mailto:ath9k-devel-bounces@lists.ath9k.org">mailto:ath9=
k-devel-bounces at lists.ath9k.org</A>] On Behalf Of Peter Stuge<BR>
&gt; Sent: Monday, April 11, 2011 12:20 PM<BR>
&gt; To: ath9k-devel at lists.ath9k.org<BR>
&gt; Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd<BR>
&gt;<BR>
&gt; Mohammed Shafi wrote:<BR>
&gt;&gt; to make sure that HT is configured in driver please do this<BR>
&gt;&gt;<BR>
&gt;&gt; diff --git a/drivers/net/wireless/ath/ath9k/hw.c<BR>
&gt;&gt; b/drivers/net/wireless/ath/ath9k/hw.c<BR>
&gt;&gt; index 1b5bd13..720a866 100644<BR>
&gt;&gt; --- a/drivers/net/wireless/ath/ath9k/hw.c<BR>
&gt;&gt; +++ b/drivers/net/wireless/ath/ath9k/hw.c<BR>
&gt;&gt; @@ -1855,6 +1855,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw=
 *ah)<BR>
&gt;&gt; =A0 =A0 =A0 =A0 else<BR>
&gt;&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap-&gt;hw_caps &amp;=3D ~ATH9=
K_HW_CAP_HT;<BR>
&gt;&gt;<BR>
&gt;&gt; + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap-&gt;hw_caps |=3D ATH9K_HW_CA=
P_HT;<BR>
&gt;&gt; +<BR>
&gt;<BR>
&gt; The indentation is off, or do you mean to include the added line=
 only<BR>
&gt; within the else block? If so, remember to add braces.<BR>
&gt;<BR>
&gt;<BR>
&gt; //Peter<BR>
&gt; _______________________________________________<BR>
&gt; ath9k-devel mailing list<BR>
&gt; ath9k-devel at lists.ath9k.org<BR>
&gt; <A HREF=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel">ht=
tps://lists.ath9k.org/mailman/listinfo/ath9k-devel</A><BR>
&gt;<BR>
&gt; This communication contains information that may be confidential=
 or<BR>
&gt; privileged. The information is solely intended for the use of the=
 addressee. If you are not the intended recipient, be advised that any=
 disclosure, copy, distribution, or use of the contents of this communic=
ation is prohibited. If you have received this communication in error,=
 please immediately notify the sender by telephone or by electronic mail=
.<BR>
&gt; _______________________________________________<BR>
&gt; ath9k-devel mailing list<BR>
&gt; ath9k-devel at lists.ath9k.org<BR>
&gt; <A HREF=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel">ht=
tps://lists.ath9k.org/mailman/listinfo/ath9k-devel</A><BR>
&gt;<BR>
&gt;<BR>
<BR>
</FONT>
</P>


<!-- Begin Ninja Disclaimer ID 06d1f63c-a7f2-4bdd-9832-359e6e93159e -->
This communication contains information that may be confidential or priv=
ileged. The information is solely intended for the use of the addressee.=
 If you are not the intended recipient, be advised that any disclosure,=
 copy, distribution, or use of the contents of this communication is pro=
hibited. If you have received this communication in<BR>error, please imm=
ediately notify the sender by telephone or by electronic mail.
</BODY>
</HTML>
------_=_NextPart_001_01CBF922.E6EB9838--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-04-07  5:55 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-04-07  5:55 UTC (permalink / raw)
  To: ath9k-devel

-------------------------------<br>
Device Instance Id:<br>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C&amp;REV_01\4&amp;492937F&amp;=
0&amp;00E2<br>
<br>
Hardware Ids:<br>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C&amp;REV_01<br>
PCI\VEN_168C&amp;DEV_0030&amp;SUBSYS_3116168C<br>
PCI\VEN_168C&amp;DEV_0030&amp;CC_028000<br>
PCI\VEN_168C&amp;DEV_0030&amp;CC_0280<br>
<br>
Compatible Ids:<br>
PCI\VEN_168C&amp;DEV_0030&amp;REV_01<br>
PCI\VEN_168C&amp;DEV_0030<br>
PCI\VEN_168C&amp;CC_028000<br>
PCI\VEN_168C&amp;CC_0280<br>
PCI\VEN_168C<br>
PCI\CC_028000<br>
PCI\CC_0280<br>
<br>
Matching Device Id:<br>
pci\ven_168c&amp;dev_0030&amp;subsys_3116168c<br>
<br>
<br>
Here is the interesting bit, when I first hooked this card I booted my mach=
ine in Ubuntu I saw the same 168c:ABCD. After using it under Windows, I boo=
ted in to Linux today and found that it is reporting the expected IDs. Now =
ath9k works right out of the box, no Vendor ID hacking required. I am using=
 it as station right now. The other card is in a different machine. I will =
try to swap the cards to verify my theory. I am thinking the Windows driver=
 applied a firmware update to the card. Or, the other card skipped quality =
checks and has bogus EEPROM data. Any thoughts?<br>

<br>
0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300 Wirel=
ess LAN adaptor [168c:0030] (rev 01)<br>
<br>
lspci -vvvnn returns<br>
<br>
0e:00.0 Network controller [0280]: Atheros Communications Inc. AR9300 Wirel=
ess LAN adaptor [168c:0030] (rev 01)<br>
=A0=A0=A0=A0=A0=A0=A0 Subsystem: Atheros Communications Inc. Device [168c:3=
116]</font></p><div class=3D"im"><font size=3D"2"><br>
=A0=A0=A0=A0=A0=A0=A0 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGA=
Snoop- ParErr- Stepping- SERR- FastB2B- DisINTx-<br>
=A0=A0=A0=A0=A0=A0=A0 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfa=
st &gt;TAbort- &lt;TAbort- &lt;MAbort- &gt;SERR- &lt;PERR- INTx-<br></font>=
</div><font size=3D"2">
=A0=A0=A0=A0=A0=A0=A0 Latency: 0, Cache Line Size: 64 bytes<br>
=A0=A0=A0=A0=A0=A0=A0 Interrupt: pin A routed to IRQ 18<br>
=A0=A0=A0=A0=A0=A0=A0 Region 0: Memory at fa000000 (64-bit, non-prefetchabl=
e) [size=3D128K]<br>
=A0=A0=A0=A0=A0=A0=A0 [virtual] Expansion ROM at f2000000 [disabled] [size=
=3D64K]<br>
=A0=A0=A0=A0=A0=A0=A0 Capabilities: &lt;access denied&gt;<br>
=A0=A0=A0=A0=A0=A0=A0 Kernel driver in use: ath9k<br>
=A0=A0=A0=A0=A0=A0=A0 Kernel modules: ath9k<br>
<br>
<br>
Hasan R.<div class=3D"im"><br>
<br>
-----Original Message-----<br>
From: Mohammed Shafi [<a href=3D"mailto:shafi.ath9k@gmail.com" target=3D"_b=
lank">mailto:shafi.ath9k at gmail.com</a>]<br></div><div class=3D"im">
Sent: Tuesday, April 12, 2011 7:47 AM<br>
To: Hasan Rashid<br></div><div><div></div><div class=3D"h5">
Cc: <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_blank">ath9k-=
devel at lists.ath9k.org</a><br>
Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd<br>
<br>
On Mon, Apr 11, 2011 at 11:24 PM, Hasan Rashid &lt;<a href=3D"mailto:hrasha=
d@avionica.com" target=3D"_blank">hrashad at avionica.com</a>&gt; wrote:<br>
&gt;<br>
&gt; I have attached the driver load output in dmesg.<br>
&gt;<br>
&gt; By the way why does AR9382 require Kernel 2.6.36 or higher? Can you<br=
>
&gt; list the major requirements?<br>
<br>
because the hardware code(HAL) will be present from that kernel version onl=
y.<br>
&gt;<br>
&gt; Hasan R.<br>
&gt;<br>
&gt; -----Original Message-----<br>
&gt; From: <a href=3D"mailto:ath9k-devel-bounces@lists.ath9k.org" target=3D=
"_blank">ath9k-devel-bounces at lists.ath9k.org</a><br>
&gt; [<a href=3D"mailto:ath9k-devel-bounces@lists.ath9k.org" target=3D"_bla=
nk">mailto:ath9k-devel-bounces at lists.ath9k.org</a>] On Behalf Of Peter Stug=
e<br>
&gt; Sent: Monday, April 11, 2011 12:20 PM<br>
&gt; To: <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_blank">a=
th9k-devel at lists.ath9k.org</a><br>
&gt; Subject: Re: [ath9k-devel] Sparklan WPEA-121N AR9382 168c:abcd<br>
&gt;<br>
&gt; Mohammed Shafi wrote:<br>
&gt;&gt; to make sure that HT is configured in driver please do this<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/drivers/net/wireless/ath/ath9k/hw.c<br>
&gt;&gt; b/drivers/net/wireless/ath/ath9k/hw.c<br>
&gt;&gt; index 1b5bd13..720a866 100644<br>
&gt;&gt; --- a/drivers/net/wireless/ath/ath9k/hw.c<br>
&gt;&gt; +++ b/drivers/net/wireless/ath/ath9k/hw.c<br>
&gt;&gt; @@ -1855,6 +1855,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah=
)<br>
&gt;&gt; =A0 =A0 =A0 =A0 else<br>
&gt;&gt; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap-&gt;hw_caps &amp;=3D ~ATH9K_H=
W_CAP_HT;<br>
&gt;&gt;<br>
&gt;&gt; + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pCap-&gt;hw_caps |=3D ATH9K_HW_CAP_H=
T;<br>
&gt;&gt; +<br>
&gt;<br>
&gt; The indentation is off, or do you mean to include the added line only<=
br>
&gt; within the else block? If so, remember to add braces.<br>
&gt;<br>
&gt;<br>
&gt; //Peter<br>
&gt; _______________________________________________<br>
&gt; ath9k-devel mailing list<br>
&gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_blank">ath9k=
-devel at lists.ath9k.org</a><br>
&gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" targe=
t=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
&gt;<br>
&gt; This communication contains information that may be confidential or<br=
>
&gt; privileged. The information is solely intended for the use of the addr=
essee. If you are not the intended recipient, be advised that any disclosur=
e, copy, distribution, or use of the contents of this communication is proh=
ibited. If you have received this communication in error, please immediatel=
y notify the sender by telephone or by electronic mail.<br>

&gt; _______________________________________________<br>
&gt; ath9k-devel mailing list<br>
&gt; <a href=3D"mailto:ath9k-devel@lists.ath9k.org" target=3D"_blank">ath9k=
-devel at lists.ath9k.org</a><br>
&gt; <a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" targe=
t=3D"_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
&gt;<br>
&gt;<br>
<br>
</div></div></font>
<p></p><div><div></div><div class=3D"h5">



This communication contains information that may be confidential or privile=
ged. The information is solely intended for the use of the addressee. If yo=
u are not the intended recipient, be advised that any disclosure, copy, dis=
tribution, or use of the contents of this communication is prohibited. If y=
ou have received this communication in<br>
error, please immediately notify the sender by telephone or by electronic m=
ail.
</div></div></div>
<br>_______________________________________________<br>
ath9k-devel mailing list<br>
<a href=3D"mailto:ath9k-devel@lists.ath9k.org">ath9k-devel at lists.ath9k.org<=
/a><br>
<a href=3D"https://lists.ath9k.org/mailman/listinfo/ath9k-devel" target=3D"=
_blank">https://lists.ath9k.org/mailman/listinfo/ath9k-devel</a><br>
<br></blockquote></div><br>

--002215b031060bfd5704a0c0a00c--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-05-13 19:35 Vadim Bendebury
  0 siblings, 0 replies; 409+ messages in thread
From: Vadim Bendebury @ 2011-05-13 19:35 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-05-17  9:28 Javier Martin
  0 siblings, 0 replies; 409+ messages in thread
From: Javier Martin @ 2011-05-17  9:28 UTC (permalink / raw)
  To: linux-arm-kernel


This series of patches provides support for Aptina mt9p031 sensor on Beagleboard xM.
It has been tested using media-ctl and yavta.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-04 23:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-06-04 23:16 UTC (permalink / raw)
  To: ath9k-devel

"Evidently, some BIOSes have their ASPM support misconfigured and thus
problems can arise if the PCI-E link power mode is dropped on an
unsupported device. There are a few mentions of hangs and other issues
under Linux associated with this power management feature. It's not
really a surprise though that the BIOSes would be misconfigured given
all of the other BIOS-related problems under Linux and the once very
poor suspend-and-resume support due to all of the workarounds and
hacks that BIOS/hardware vendors have done to cater towards Microsoft
Windows power management. In this case, it seems a large number of
mobile systems are supporting ASPM but not properly advertising the
support via the standard BIOS ACPI FADT (Fixed ACPI Description
Table). Some Linux drivers even forcibly disable ASPM on Linux (e.g.
this kernel patch)."

Would someone please take charge of testing an unmodified ath9k (ie,
without my APSM disable fix) and try reverting this kernel patch?

Thanks,


Adrian

On 25 February 2011 04:02, Jonathan Nieder <jrnieder@gmail.com> wrote:
> (just cc-ing some people listed in MAINTAINERS)
> Hi,
>
> Tony Houghton wrote:
>
>> With 2.6.37 I can not use suspend on my Compaq/HP 311c (Intel Atom
>> N270/NVidia Ion LE). Originally the machine just kept locking up without
>> even blanking the display when I tried to suspend (using the GNOME menu
>> or by shutting the lid). I upgraded upower and gnome-power-manager etc
>> to experimental and after that the machine suspended OK but could not
>> resume. The backlight came on but the screen stayed blank and I could
>> not get to a console or anything with Alt+Fn.
> [...]
>> I tried replacing network-manager with wicd but that crashed the system
>> when it connected instead of when disconnected.
> [...]
>> While testing different kernels I found it would crash at different
>> times, usually before the screen turned off for suspending, but
>> sometimes it would crash on resuming and occasionally it locked up while
>> booting, but it's always a complete lock-up ie the keyboard is
>> completely responsive, including caps lock, the mouse won't move if the
>> display is still on, and the only way out is to hold down the power
>> button.
> [...]
>> I haven't tried looking in logs because the crashes are so severe I
>> don't think they'd be able to record anything useful. But using git
>> bisect I think I have tracked down the change that started causing this
>> problem:
>>
>> 53bc7aa08b48e5cd745f986731cc7dc24eef2a9f is the first bad commit
>> commit 53bc7aa08b48e5cd745f986731cc7dc24eef2a9f
>> Author: Vivek Natarajan <vnatarajan@atheros.com>
>> Date: =A0 Mon Apr 5 14:48:04 2010 +0530
>>
>> =A0 =A0 ath9k: Add support for newer AR9285 chipsets.
>>
>> =A0 =A0 This patch adds support for a modified newer version of AR9285
>> =A0 =A0 chipsets.
>>
>> =A0 =A0 Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
>> =A0 =A0 Signed-off-by: John W. Linville <linville@tuxdriver.com>
>
> The adaptor is an AR9285[1].
>
> That commit is based against v2.6.33 and was merged in v2.6.35-rc1
>
> $ git describe 53bc7aa08b48e5cd745f986731cc7dc24eef2a9f
> v2.6.33-3523-g53bc7aa
> $ git name-rev --tags 53bc7aa08b48e5cd745f986731cc7dc24eef2a9f
> 53bc7aa08b48e5cd745f986731cc7dc24eef2a9f tags/v2.6.35-rc1~473^2~167^2~346
>
> Any ideas for tracking this down?
>
> Thanks,
> Jonathan
>
> [1]
>> 84: udi =3D '/org/freedesktop/Hal/devices/pci_168c_2b'
>> =A0 pci.device_protocol =3D 0 =A0(0x0) =A0(int)
>> =A0 pci.vendor =3D 'Atheros Communications Inc.' =A0(string)
>> =A0 info.vendor =3D 'Atheros Communications Inc.' =A0(string)
>> =A0 pci.product =3D 'AR9285 Wireless Network Adapter
>> (PCI-Express)' =A0(string) linux.sysfs_path =3D
>> '/sys/devices/pci0000:00/0000:00:15.0/0000:03:00.0' =A0(strin g)
>> =A0 info.parent =3D '/org/freedesktop/Hal/devices/pci_10de_ac6' =A0(stri=
ng)
>> =A0 info.linux.driver =3D 'ath9k' =A0(string)
>> =A0 pci.subsys_vendor =3D 'Hewlett-Packard Company' =A0(string)
>> =A0 linux.hotplug_type =3D 2 =A0(0x2) =A0(int)
>> =A0 linux.subsystem =3D 'pci' =A0(string)
>> =A0 info.subsystem =3D 'pci' =A0(string)
>> =A0 info.product =3D 'AR9285 Wireless Network Adapter
>> (PCI-Express)' =A0(string) info.udi =3D
>> '/org/freedesktop/Hal/devices/pci_168c_2b' =A0(string)
>> pci.linux.sysfs_path =3D
>> '/sys/devices/pci0000:00/0000:00:15.0/0000:03:00.0' =A0(string)
>> pci.product_id =3D 43 =A0(0x2b) =A0(int) pci.vendor_id =3D 5772 =A0(0x16=
8c)
>> (int) pci.subsys_product_id =3D 12352 =A0(0x3040) =A0(int)
>> pci.subsys_vendor_id =3D 4156 =A0(0x103c) =A0(int) pci.device_class =3D =
2
>> (0x2) =A0(int) pci.device_subclass =3D 128 =A0(0x80) =A0(int)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless"=
 in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at =A0http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-04 23:16 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-06-04 23:16 UTC (permalink / raw)
  To: ath9k-devel

not even used an AR9300 yet, let alone tinkered with the TPC stuff) it
looks all very straightforward. Unless some other chip functionality
is required that hasn't been ported to ath9k, it "should just work".

Sorry, I can't be more helpful than that.

(Also, it'd be nice if someone contributed per-packet TPC support -
proper support at that! - to ath9k. :)


adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-05 18:33 Hector Oron
  0 siblings, 0 replies; 409+ messages in thread
From: Hector Oron @ 2011-06-05 18:33 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-13 17:29 Andre Silva
  0 siblings, 0 replies; 409+ messages in thread
From: Andre Silva @ 2011-06-13 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH 1/2] ARM:mach-mx5/mx53_ard: Add ESDHC support

Signed-off-by: Andre Silva <andre.silva@freescale.com>

---
 arch/arm/mach-mx5/Kconfig          |    1 +
 arch/arm/mach-mx5/board-mx53_ard.c |   22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 695cdf0..9a8e6f8 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -213,6 +213,7 @@ config MACH_MX53_ARD
 	bool "Support MX53 ARD platforms"
 	select SOC_IMX53
 	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	help
 	  Include support for MX53 ARD platform. This includes specific
 	  configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c
index 7e1859b..6049fda 100644
--- a/arch/arm/mach-mx5/board-mx53_ard.c
+++ b/arch/arm/mach-mx5/board-mx53_ard.c
@@ -36,6 +36,8 @@
 #include "devices-imx53.h"
 
 #define ARD_ETHERNET_INT_B	IMX_GPIO_NR(2, 31)
+#define ARD_SD1_CD		IMX_GPIO_NR(1, 1)
+#define ARD_SD1_WP		IMX_GPIO_NR(1, 9)
 
 static iomux_v3_cfg_t mx53_ard_pads[] = {
 	/* UART1 */
@@ -69,6 +71,19 @@ static iomux_v3_cfg_t mx53_ard_pads[] = {
 	MX53_PAD_EIM_OE__EMI_WEIM_OE,
 	MX53_PAD_EIM_RW__EMI_WEIM_RW,
 	MX53_PAD_EIM_CS1__EMI_WEIM_CS_1,
+	/* SDHC1 */
+	MX53_PAD_SD1_CMD__ESDHC1_CMD,
+	MX53_PAD_SD1_CLK__ESDHC1_CLK,
+	MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+	MX53_PAD_PATA_DATA8__ESDHC1_DAT4,
+	MX53_PAD_PATA_DATA9__ESDHC1_DAT5,
+	MX53_PAD_PATA_DATA10__ESDHC1_DAT6,
+	MX53_PAD_PATA_DATA11__ESDHC1_DAT7,
+	MX53_PAD_GPIO_1__GPIO1_1,
+	MX53_PAD_GPIO_9__GPIO1_9,
 };
 
 static struct resource ard_smsc911x_resources[] = {
@@ -100,6 +115,11 @@ static struct platform_device ard_smsc_lan9220_device = {
 	},
 };
 
+static const struct esdhc_platform_data mx53_ard_sd1_data __initconst = {
+	.cd_gpio = ARD_SD1_CD,
+	.wp_gpio = ARD_SD1_WP,
+};
+
 static void __init mx53_ard_io_init(void)
 {
 	mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads,
@@ -156,6 +176,8 @@ static void __init mx53_ard_board_init(void)
 	mx53_ard_io_init();
 	weim_cs_config();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data);
 }
 
 static void __init mx53_ard_timer_init(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-14 12:20 Venkateswarlu P
  0 siblings, 0 replies; 409+ messages in thread
From: Venkateswarlu P @ 2011-06-14 12:20 UTC (permalink / raw)
  To: kernelnewbies

anyone can send
implementation of  *fork()* library call  in the library

i want to know how it is get connected to the system call.















**
P VENKATESWARLU
M.Tech (CSE) II year
NIT Calicut ,Kerala* **
*+91-9995115752
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110614/e1414a9f/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-16 11:41 Venkateswarlu P
  0 siblings, 0 replies; 409+ messages in thread
From: Venkateswarlu P @ 2011-06-16 11:41 UTC (permalink / raw)
  To: kernelnewbies

how to understand the kernerl source  files in a simple way


what header  files i have to understand first


for example  to understand      do_fork()     function  for process
creation  which is defined in  kernel/fork.c



-- 
**
P VENKATESWARLU
M.Tech (CSE) II year
NIT Calicut ,Kerala* **
*+91-9995115752
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110616/e52d0718/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-27 20:47 John Ogness
  0 siblings, 0 replies; 409+ messages in thread
From: John Ogness @ 2011-06-27 20:47 UTC (permalink / raw)
  To: linux-arm-kernel

The alignment exception handler is setup fairly late in
the boot process (fs_initcall). However, with newer gcc
versions and the compiler option -fconserve-stack, code
accessing unaligned data is generated in functions that
are called earlier, for example pcpu_dump_alloc_info().
This results in unhandled alignment exceptions during
boot. By setting up the exception handler sooner, we
reduce the window where a compiler may generate code
accessing unaligned data.

Here is a minimal example that shows the issue seen with
pcpu_dump_alloc_info():

=========== begin align_test.c ==========
extern void exfunc(char *str);
void somefunc(void)
{
        char mystr[] = "--------";  /* 9 bytes */
        exfunc(mystr);
}
============ end align_test.c ===========

Using the cross toolchain:
arm-none-linux-gnueabi-gcc (Sourcery G++ Lite 2011.03-41) 4.5.2

$ arm-none-linux-gnueabi-gcc \
     -march=armv6 \
     -mtune=arm1136j-s \
     -marm \
     -Os \
     -fconserve-stack \
     -c align_test.c

The object dump of align_test.o shows:

00000000 <somefunc>:
   0:   e92d401f        push    {r0, r1, r2, r3, r4, lr}
   4:   e28d0007        add     r0, sp, #7
   8:   e59f3020        ldr     r3, [pc, #32]   ; 30 <somefunc+0x30>
   c:   e5932000        ldr     r2, [r3]
  10:   e58d2007        str     r2, [sp, #7]
  ...
  ...

At address 0x10 there is unaligned access.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
Patch against linux-next-20110831.
 arch/arm/include/asm/setup.h |    1 +
 arch/arm/kernel/setup.c      |    2 ++
 arch/arm/mm/alignment.c      |   10 +++++++---
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index a3ca303..b3e18f8 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -232,6 +232,7 @@ extern struct meminfo meminfo;
 extern int arm_add_memory(phys_addr_t start, unsigned long size);
 extern void early_print(const char *str, ...);
 extern void dump_machine_table(void);
+extern int __init alignment_init(void);
 
 #endif  /*  __KERNEL__  */
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0ca06f7..0f1b2b5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -950,6 +950,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 	early_trap_init();
 
+	alignment_init();
+
 	if (mdesc->init_early)
 		mdesc->init_early();
 }
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 715eb1d..5f013cb 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -950,7 +950,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
  * it isn't a sysctl, and it doesn't contain sysctl information.
  * We now locate it in /proc/cpu/alignment instead.
  */
-static int __init alignment_init(void)
+static int __init alignment_sysfs_init(void)
 {
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry *res;
@@ -960,7 +960,13 @@ static int __init alignment_init(void)
 	if (!res)
 		return -ENOMEM;
 #endif
+	return 0;
+}
+
+fs_initcall(alignment_sysfs_init);
 
+int __init alignment_init(void)
+{
 	if (cpu_is_v6_unaligned()) {
 		cr_alignment &= ~CR_A;
 		cr_no_alignment &= ~CR_A;
@@ -985,5 +991,3 @@ static int __init alignment_init(void)
 
 	return 0;
 }
-
-fs_initcall(alignment_init);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2011-06-27 20:47 Jongpill Lee
  0 siblings, 0 replies; 409+ messages in thread
From: Jongpill Lee @ 2011-06-27 20:47 UTC (permalink / raw)
  To: linux-arm-kernel



>From bogus@does.not.exist.com  Mon Jun 27 16:47:34 2011
From: bogus@does.not.exist.com ()
Date: Mon, 27 Jun 2011 20:47:34 -0000
Subject: No subject
Message-ID: <mailman.139.1316181028.20020.linux-arm-kernel@lists.infradead.org>

- General tidy-up after Thomas' review. I've kept the config option
  for the time being until we can sort out the anonymous union
  problem.

Marc Zyngier (3):
  genirq: add support for per-cpu dev_id interrupts
  ARM: gic: consolidate PPI handling
  ARM: gic, local timers: use the request_percpu_irq() interface

 arch/arm/common/Kconfig                           |    1 +
 arch/arm/common/gic.c                             |   38 +++-
 arch/arm/include/asm/entry-macro-multi.S          |    7 -
 arch/arm/include/asm/hardirq.h                    |    3 -
 arch/arm/include/asm/hardware/entry-macro-gic.S   |   19 +--
 arch/arm/include/asm/hardware/gic.h               |    1 -
 arch/arm/include/asm/localtimer.h                 |   19 +-
 arch/arm/include/asm/smp.h                        |    5 -
 arch/arm/include/asm/smp_twd.h                    |    2 +-
 arch/arm/kernel/irq.c                             |    3 -
 arch/arm/kernel/smp.c                             |   33 +---
 arch/arm/kernel/smp_twd.c                         |   47 +++++-
 arch/arm/mach-exynos4/include/mach/entry-macro.S  |    6 +-
 arch/arm/mach-exynos4/mct.c                       |    5 -
 arch/arm/mach-msm/board-msm8x60.c                 |   11 -
 arch/arm/mach-msm/include/mach/entry-macro-qgic.S |   73 +-------
 arch/arm/mach-msm/timer.c                         |   69 ++++---
 arch/arm/mach-omap2/include/mach/entry-macro.S    |   14 +--
 arch/arm/mach-shmobile/entry-intc.S               |    3 -
 arch/arm/mach-shmobile/include/mach/entry-macro.S |    3 -
 include/linux/interrupt.h                         |   40 +++-
 include/linux/irq.h                               |   16 ++-
 include/linux/irqdesc.h                           |    1 +
 kernel/irq/Kconfig                                |    4 +
 kernel/irq/chip.c                                 |   54 ++++++
 kernel/irq/internals.h                            |    2 +
 kernel/irq/irqdesc.c                              |   25 +++
 kernel/irq/manage.c                               |  209 +++++++++++++++++=
+++-
 kernel/irq/settings.h                             |    7 +
 29 files changed, 471 insertions(+), 249 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-07-21 11:12 Padmavathi Venna
  0 siblings, 0 replies; 409+ messages in thread
From: Padmavathi Venna @ 2011-07-21 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add external interrupt support for S5P64X0.The external interrupt
group 0(0 to 15) is used for wake-up source in stop and sleep mode.
Add generic irq chip support

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
---

Please ignore my previous patch due to wrong return value.

 arch/arm/mach-s5p64x0/Makefile                 |    2 +-
 arch/arm/mach-s5p64x0/include/mach/regs-gpio.h |   10 ++
 arch/arm/mach-s5p64x0/irq-eint.c               |  152 ++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-s5p64x0/irq-eint.c

diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index ae6bf6f..5f6afdf 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -13,7 +13,7 @@ obj-				:=
 # Core support for S5P64X0 system
 
 obj-$(CONFIG_ARCH_S5P64X0)	+= cpu.o init.o clock.o dma.o gpiolib.o
-obj-$(CONFIG_ARCH_S5P64X0)	+= setup-i2c0.o
+obj-$(CONFIG_ARCH_S5P64X0)	+= setup-i2c0.o irq-eint.o
 obj-$(CONFIG_CPU_S5P6440)	+= clock-s5p6440.o
 obj-$(CONFIG_CPU_S5P6450)	+= clock-s5p6450.o
 
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 0953ef6..6ce2547 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -34,4 +34,14 @@
 #define S5P6450_GPQ_BASE		(S5P_VA_GPIO + 0x0180)
 #define S5P6450_GPS_BASE		(S5P_VA_GPIO + 0x0300)
 
+/* External interrupt control registers for group0 */
+
+#define EINT0CON0_OFFSET		(0x900)
+#define EINT0MASK_OFFSET		(0x920)
+#define EINT0PEND_OFFSET		(0x924)
+
+#define S5P64X0_EINT0CON0		(S5P_VA_GPIO + EINT0CON0_OFFSET)
+#define S5P64X0_EINT0MASK		(S5P_VA_GPIO + EINT0MASK_OFFSET)
+#define S5P64X0_EINT0PEND		(S5P_VA_GPIO + EINT0PEND_OFFSET)
+
 #endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c
new file mode 100644
index 0000000..69ed454
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/irq-eint.c
@@ -0,0 +1,152 @@
+/* arch/arm/mach-s5p64x0/irq-eint.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *		http://www.samsung.com/
+ *
+ * Based on linux/arch/arm/mach-s3c64xx/irq-eint.c
+ *
+ * S5P64X0 - Interrupt handling for External Interrupts.
+ *
+ * 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/kernel.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <plat/regs-irqtype.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+#define eint_offset(irq)	((irq) - IRQ_EINT(0))
+
+static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type)
+{
+	int offs = eint_offset(data->irq);
+	int shift;
+	u32 ctrl, mask;
+	u32 newvalue = 0;
+
+	if (offs > 15)
+		return -EINVAL;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No edge setting!\n");
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		newvalue = S3C2410_EXTINT_RISEEDGE;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		newvalue = S3C2410_EXTINT_FALLEDGE;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		newvalue = S3C2410_EXTINT_BOTHEDGE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		newvalue = S3C2410_EXTINT_LOWLEV;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		newvalue = S3C2410_EXTINT_HILEV;
+		break;
+	default:
+		printk(KERN_ERR "No such irq type %d", type);
+		return -EINVAL;
+	}
+
+	shift = (offs / 2) * 4;
+	mask = 0x7 << shift;
+
+	ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask;
+	ctrl |= newvalue << shift;
+	__raw_writel(ctrl, S5P64X0_EINT0CON0);
+
+	/* Configure the GPIO pin for 6450 or 6440 based on CPU ID */
+	if (0x50000 == (__raw_readl(S5P64X0_SYS_ID) & 0xFF000))
+		s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2));
+	else
+		s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2));
+
+	return 0;
+}
+
+/*
+ * s5p64x0_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into
+ * the specific handlers s5p64x0_irq_demux_eintX_Y.
+ */
+static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end)
+{
+	u32 status = __raw_readl(S5P64X0_EINT0PEND);
+	u32 mask = __raw_readl(S5P64X0_EINT0MASK);
+	unsigned int irq;
+
+	status &= ~mask;
+	status >>= start;
+	status &= (1 << (end - start + 1)) - 1;
+
+	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+		if (status & 1)
+			generic_handle_irq(irq);
+		status >>= 1;
+	}
+}
+
+static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+	s5p64x0_irq_demux_eint(0, 3);
+}
+
+static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+	s5p64x0_irq_demux_eint(4, 11);
+}
+
+static void s5p64x0_irq_demux_eint12_15(unsigned int irq,
+					struct irq_desc *desc)
+{
+	s5p64x0_irq_demux_eint(12, 15);
+}
+
+static int s5p64x0_alloc_gc(void)
+{
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE,
+				    S5P_VA_GPIO, handle_level_irq);
+	if (!gc) {
+		printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0"
+			"external interrupts failed\n", __func__);
+		return -EINVAL;
+	}
+
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_ack;
+	ct->chip.irq_mask = irq_gc_mask_set_bit;
+	ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+	ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
+	ct->regs.ack = EINT0PEND_OFFSET;
+	ct->regs.mask = EINT0MASK_OFFSET;
+	irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+	return 0;
+}
+
+static int __init s5p64x0_init_irq_eint(void)
+{
+	int ret = s5p64x0_alloc_gc();
+	irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3);
+	irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11);
+	irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15);
+
+	return ret;
+}
+arch_initcall(s5p64x0_init_irq_eint);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2011-08-05  3:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-08-05  3:08 UTC (permalink / raw)
  To: ath9k-devel

users on debugging issues like this, even if end users happen to be
competent. The prefered modus operandi is to attempt to reproduce
issues internally, and if that is successful then some time later
there usually comes a patch into wireless-testing.git. This is of
course useless for corner case problems.

This mailing list is a lot like first-line support. You usually don't
get quality engineer time from Atheros here. I can understand that,
because remote debugging is a tremendous pain. But it's also the only
way to resolve odd problems.

I would recommend that you try to reproduce using FreeBSD. I'm unsure
if the driver there supports AR9287, but if it does I think you will
be able to get good help thanks to Adrian, the main fbsd driver
developer, who is also active on this list, but he's obviously not
working on the Linux driver. :)


//Peter

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-08-05  3:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-08-05  3:08 UTC (permalink / raw)
  To: ath9k-devel

1. ASPM is disabled on my machine wherever possible (in fact I think
my mainboard doesn't even support it and this is detected correctly,
at least there I couldn't find any related setting in bios)
2. My wireless card is PCI not PCIe, and if I don't confuse something
here, ASPM is a feature of PCIe and PCIe only.

Power-saving I might check by disabling all the related options, I'll
let you know if it changes anything.

Thanks,
Philipp

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-08-05  3:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-08-05  3:08 UTC (permalink / raw)
  To: ath9k-devel

that'd occur with the NIC awake or having something being written to
it) the NIC shouldn't be generating interrupts if:

* sync/async cause are 0;
* ier is 0;
* imr is 0.

Now maybe some part of ath9k is still trying to write to the NIC when
it's asleep, but it would set some bits in sync_cause/async_cause.

At this point I'd really suggest whacking other devices into the slot
to see if they generate the same kind of behaviour.



Adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-08-05  3:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-08-05  3:08 UTC (permalink / raw)
  To: ath9k-devel

explained in the wireshark documentation.

Cheers,
Julien

-- 
  .''`.   Julien Valroff ~ <julien@kirya.net> ~ <julien@debian.org>    
 : :'  :  Debian Developer & Free software contributor
 `. `'`   http://www.kirya.net/
   `-     4096R/ E1D8 5796 8214 4687 E416  948C 859F EF67 258E 26B1

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-08-05  3:08 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-08-05  3:08 UTC (permalink / raw)
  To: ath9k-devel

so the user should only be allowed to change the value to anything else than
what is stored in the eeprom if we know it's a valid setting.

As far as I understand the EEPROM only stores a single value for the
antenna-switch setting, i.e. if there multiple valid values these must come from
somewhere else.

I don't know the exact electronic details of the implementation, so I'd go with
a list of known-to-be-good values (passed to the driver via platform-data)
instead of a causal check (e.g. don't allow to set the TX and RX to the same
antenna or whatever you imagine to possibly be an invalid setting).


Cheers

Daniel

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-09-15  2:03 Jongpill Lee
  0 siblings, 0 replies; 409+ messages in thread
From: Jongpill Lee @ 2011-09-15  2:03 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-09-19  1:45 Saleem Abdulrasool
  0 siblings, 0 replies; 409+ messages in thread
From: Saleem Abdulrasool @ 2011-09-19  1:45 UTC (permalink / raw)
  To: linux-arm-kernel


Hi.

The attached patch adds polled io methods for the mxcuart.  I needed them in
order to use kgdb during the early boot.  The changes have been sitting in (my
and) Genesi's tree for quite some time now.  I believe that the changes are
generally useful and would like you to consider merging them in the "upstream"
repository.

Thanks.

-- 
Saleem Abdulrasool
compnerd (at) compnerd (dot) org

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-09-23  3:42 毕春雷
  0 siblings, 0 replies; 409+ messages in thread
From: 毕春雷 @ 2011-09-23  3:42 UTC (permalink / raw)
  To: kernelnewbies


nirvanacn2011 at hotmail.com 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110923/b0ee862a/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-11-12 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-11-12 14:39 UTC (permalink / raw)
  To: ath9k-devel

and/or experimental. Am I right?
Either way I would be more than happy to help with debugging this and
maybe get this chipset working
sometime soon! The only problem us that my expertise only stretches so
far. Even though I know C
I've never done any kernel or driver work.
So what can I do? I'll see if I can get my hands on one (or two) of
those usb-to-serial adapters and see what happens, but I live on a
very tight budget so I can't hope for too much.

// Kim

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-11-12 14:39 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2011-11-12 14:39 UTC (permalink / raw)
  To: ath9k-devel

masked out and then unmasked. So I bet ath_rx_tasklet() is actually
running somehow and not doing anything useful.

Kim - can you please add a debug statement inside ath_rx_tasklet() -
at the beginning, then at the end of the function where it's
re-enabling RXEOL. Just to confirm that it _is_ running and causing
the RXEOL bit to be re-enabled.

Thanks,


Adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-11-21 15:22 Jimmy Pan
  0 siblings, 0 replies; 409+ messages in thread
From: Jimmy Pan @ 2011-11-21 15:22 UTC (permalink / raw)
  To: kernelnewbies

..Do you want to feel something new? Do you want to feel new
unforgettable sensations? This is for you!
http://un-ocean.fr/p.g.php?wellink_friend_id=14ox0

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-11-28  2:35 Jett.Zhou
  0 siblings, 0 replies; 409+ messages in thread
From: Jett.Zhou @ 2011-11-28  2:35 UTC (permalink / raw)
  To: linux-arm-kernel


1 remove unnecesary spinlock when release
2 remove change id

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-12-02 16:01 Will Deacon
  0 siblings, 0 replies; 409+ messages in thread
From: Will Deacon @ 2011-12-02 16:01 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-12-16  2:18 Swapnil Gaikwad
  0 siblings, 0 replies; 409+ messages in thread
From: Swapnil Gaikwad @ 2011-12-16  2:18 UTC (permalink / raw)
  To: kernelnewbies

Hi ,
     Tell me procedure or system call for-
     How to copy metadata of all files in a ext4 filesystem.

-- 
    Regards,

Swapnil Gaikwad.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-12-28 14:01 Shawn Guo
  0 siblings, 0 replies; 409+ messages in thread
From: Shawn Guo @ 2011-12-28 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

[Resend to cc LAKML.  Sorry.]

Hi Arnd, Olof,

Please consider to pull mxs/clk-prepare for 3.3.  I have not collected
the ack tag from every single subsystem maintainer, but I do not want
to hold this any longer, since it's close to merge window now.

Hi Sascha,

I send a couple of Richard's patch you have collected here for
completeness.

Regards,
Shawn

The following changes since commit 384703b8e6cd4c8ef08512e596024e028c91c339:

  Linux 3.2-rc6 (2011-12-16 18:36:26 -0800)

are available in the git repository at:
  git://git.linaro.org/people/shawnguo/linux-2.6.git mxs/clk-prepare

Richard Zhao (2):
      clk: add helper functions clk_prepare_enable and clk_disable_unprepare
      net: fec: add clk_prepare/clk_unprepare

Shawn Guo (10):
      ARM: mxs: convert platform code to clk_prepare/clk_unprepare
      dma: mxs-dma: convert to clk_prepare/clk_unprepare
      mmc: mxs-mmc: convert to clk_prepare/clk_unprepare
      mtd: gpmi-lib: convert to clk_prepare/clk_unprepare
      net: flexcan: convert to clk_prepare/clk_unprepare
      serial: mxs-auart: convert to clk_prepare/clk_unprepare
      video: mxsfb: convert to clk_prepare/clk_unprepare
      ASoC: mxs-saif: convert to clk_prepare/clk_unprepare
      clk: add config option HAVE_CLK_PREPARE into Kconfig
      ARM: mxs: select HAVE_CLK_PREPARE for clock

 arch/arm/Kconfig                      |    1 +
 arch/arm/mach-mxs/clock-mx23.c        |   10 +++++-----
 arch/arm/mach-mxs/clock-mx28.c        |   10 +++++-----
 arch/arm/mach-mxs/clock.c             |   33 +++++++++++++++++++++++----------
 arch/arm/mach-mxs/mach-mx28evk.c      |    2 +-
 arch/arm/mach-mxs/system.c            |    2 +-
 arch/arm/mach-mxs/timer.c             |    2 +-
 drivers/clk/Kconfig                   |    3 +++
 drivers/dma/mxs-dma.c                 |    8 ++++----
 drivers/mmc/host/mxs-mmc.c            |   10 +++++-----
 drivers/mtd/nand/gpmi-nand/gpmi-lib.c |   12 ++++++------
 drivers/net/can/flexcan.c             |   10 +++++-----
 drivers/net/ethernet/freescale/fec.c  |   10 +++++-----
 drivers/tty/serial/mxs-auart.c        |    8 ++++----
 drivers/video/mxsfb.c                 |    8 ++++----
 include/linux/clk.h                   |   22 ++++++++++++++++++++++
 sound/soc/mxs/mxs-saif.c              |    4 ++--
 17 files changed, 97 insertions(+), 58 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2011-12-30 17:16 Philip Anil-QBW348
  0 siblings, 0 replies; 409+ messages in thread
From: Philip Anil-QBW348 @ 2011-12-30 17:16 UTC (permalink / raw)
  To: kernelnewbies

I want the drivers to be owned by a user, Foo. Whenever the drivers are
called by application Duh, I want a program Bar to run after the driver
has done its work, since Foo is now running the driver. Is it possible?

Anil 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20111230/30642c9f/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-01-15  8:24 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-01-15  8:24 UTC (permalink / raw)
  To: ath9k-devel

=A0=A0=A0 /* Only use status info from the last fragment */
=A0=A0=A0 if (rx_stats->rs_more)
=A0=A0=A0 =A0=A0=A0 return 0=3B

rs_more is set from the receive descriptor in ath9k_hw_rxprocdesc=2C so if =
"fragment" is an A-MPDU subframe=2C each subframe gets its own descriptor. =
This looks promising.
 		 	   		  =

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-02-27  5:00 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-02-27  5:00 UTC (permalink / raw)
  To: ath9k-devel

actually useful for narrowing down the source of this issue...

- Felix

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-02-27  5:00 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-02-27  5:00 UTC (permalink / raw)
  To: ath9k-devel

The lower you go on the level of abstraction, the more data any kind of
debugging approach generates, meaning way more effort to analyze the
data and make sense of it.
I don't typically start with the part that's hardest to analyze. High
level states are easier to look into and make sense of, so they're also
easier to rule out.
Code review is also a very good starting point. I actually found and
fixed more user visible bugs through code review than any other
debugging method.

>> > but hardware development information in the community is not
>> > really available.
>> 
>> I found that people that have shown enough interest in improving ath9k
>> and have proven to be experienced in working on such drivers tend to get
>> access to documentation.
> 
> Well, let's say that in my experience the threshold for "approval"
> was set too high. As I said, and as you may remember, I was
> repeatedly shot down or ignored, offering to try to get to the bottom
> of the issues. I understand now that it may not really be legally
> possible for Atheros to provide the information that is actually
> required to get to the bottom of the issues, but that makes working
> on the driver too inefficient.
Most issues can be fixed with a good understanding of the code alone,
detailed hardware knowledge is often not as important.
This isn't unique to ath9k. I've fixed bugs in other drivers as well
without having any form of hardware documentation, because I'm able to
read and understand code and my brain can handle a bit of complexity.

>> > Being told to try to reverse engineer the hardware using the
>> > driver source code or any other source code does not qualify.
>> 
>> Your definition of 'reverse engineering' is quite funny.
> 
> There's not just one type of reverse engineering.
> 
> Suggesting hardware reverse engineering in an open source driver
> development effort is, well, not what I expect.
> 
> 
>> To me it looks somewhat ridiculous that you claim to know better what's
>> required to debug this issue than people working with the hardware on a
>> daily basis (Adrian, Mohammed, me).
> 
> I've developed both hardware and software for more than 20 years, and
> neither problems nor solutions have changed much, so I think I still
> have a clue.
OK, so let me get this straight: You can't imagine how the test result
from disabling PS could be useful for tracking down the problem, so you
automatically assume that it *must* be a lame workaround suggestion?
That seems rather narrow-minded of you.

Of course I can see multiple ways in which this information would be
useful, but I guess that may not matter to you.

- Felix

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-02-27  5:00 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-02-27  5:00 UTC (permalink / raw)
  To: ath9k-devel

;f=3Dhostapd/hostapd.conf),  I
cannot find what wme_enabled is.

=20

-          What does wme_enabled do ? Is it needed in conjunction with =
ht_capab ?

Another question, I live in CH, a reboot shows=20

[    9.201363] ath: Country alpha2 being used: AU

And changed it to CH.=20

=20

-          Which limitation can I expect, for not being a European Card, =
as it propagates AU ?

=20

Below I added lspci, iw list, hostapd.conf, dmesg output.

http://www.tp-link.com/en/products/details/?model=3DTL-WDN4800#spec

=20

Thanks for your help

Angela

=20

# lspci -vvd 168c:

02:00.0 Network controller: Atheros Communications Inc. AR9300 Wireless =
LAN adaptor (rev 01)

        Subsystem: Atheros Communications Inc. Device 3112

        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- =
ParErr- Stepping- SERR- FastB2B- DisINTx-

        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfast >TAbort- =
<TAbort- <MAbort- >SERR- <PERR- INTx-

        Latency: 0, Cache Line Size: 64 bytes

        Interrupt: pin A routed to IRQ 17

        Region 0: Memory at fbe00000 (64-bit, non-prefetchable) =
[size=3D128K]

        Expansion ROM at fbe20000 [disabled] [size=3D64K]

        Capabilities: [40] Power Management version 3

                Flags: PMEClk- DSI- D1+ D2- AuxCurrent=3D375mA =
PME(D0+,D1+,D2-,D3hot+,D3cold-)

                Status: D0 NoSoftRst- PME-Enable- DSel=3D0 DScale=3D0 =
PME-

        Capabilities: [50] MSI: Enable- Count=3D1/4 Maskable+ 64bit+

                Address: 0000000000000000  Data: 0000

                Masking: 00000000  Pending: 00000000

        Capabilities: [70] Express (v2) Endpoint, MSI 00

                DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s =
<1us, L1 <8us

                        ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-

                DevCtl: Report errors: Correctable- Non-Fatal- Fatal- =
Unsupported-

                        RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-

                        MaxPayload 128 bytes, MaxReadReq 512 bytes

                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- =
TransPend-

                LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, =
Latency L0 <2us, L1 <64us

                        ClockPM- Surprise- LLActRep- BwNot-

                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- =
CommClk+

                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-

                LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ =
DLActive- BWMgmt- ABWMgmt-

                DevCap2: Completion Timeout: Not Supported, TimeoutDis+

                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-

                LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- =
SpeedDis-, Selectable De-emphasis: -6dB

                         Transmit Margin: Normal Operating Range, =
EnterModifiedCompliance- ComplianceSOS-

                         Compliance De-emphasis: -6dB

                LnkSta2: Current De-emphasis Level: -6dB

        Capabilities: [100 v1] Advanced Error Reporting

                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- =
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-

                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- =
UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-

                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- =
UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-

                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- =
NonFatalErr-

                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- =
NonFatalErr+

                AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- =
ChkEn-

        Capabilities: [140 v1] Virtual Channel

                Caps:   LPEVC=3D0 RefClk=3D100ns PATEntryBits=3D1

                Arb:    Fixed- WRR32- WRR64- WRR128-

                Ctrl:   ArbSelect=3DFixed

                Status: InProgress-

                VC0:    Caps:   PATOffset=3D00 MaxTimeSlots=3D1 =
RejSnoopTrans-

                       Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- =
WRR256-

                        Ctrl:   Enable+ ID=3D0 ArbSelect=3DFixed =
TC/VC=3D01

                        Status: NegoPending- InProgress-

        Capabilities: [300 v1] Device Serial Number =
00-00-00-00-00-00-00-00

        Kernel driver in use: ath9k

        Kernel modules: ath9k

=20

=20

# iw list

Wiphy phy0

        Band 1:

                Capabilities: 0x11ef

                        RX LDCP

                        HT20/HT40

                        SM Power Save disabled

                        RX HT20 SGI

                        RX HT40 SGI

                        TX STBC

                        RX STBC 1-stream

                        Max AMSDU length: 7935 bytes

                        DSSS/CCK HT40

                Maximum RX AMPDU length 65535 bytes (exponent: 0x003)

                Minimum RX AMPDU time spacing: 8 usec (0x06)

                HT TX/RX MCS rate indexes supported: 0-23

                Frequencies:

                        * 2412 MHz [1] (20.0 dBm)

                        * 2417 MHz [2] (20.0 dBm)

                        * 2422 MHz [3] (20.0 dBm)

                        * 2427 MHz [4] (20.0 dBm)

                        * 2432 MHz [5] (20.0 dBm)

                        * 2437 MHz [6] (20.0 dBm)

                        * 2442 MHz [7] (20.0 dBm)

                        * 2447 MHz [8] (20.0 dBm)

                        * 2452 MHz [9] (20.0 dBm)

                        * 2457 MHz [10] (20.0 dBm)

                        * 2462 MHz [11] (20.0 dBm)

                        * 2467 MHz [12] (20.0 dBm)

                        * 2472 MHz [13] (20.0 dBm)

                        * 2484 MHz [14] (disabled)

                Bitrates (non-HT):

                        * 1.0 Mbps

                        * 2.0 Mbps (short preamble supported)

                        * 5.5 Mbps (short preamble supported)

                        * 11.0 Mbps (short preamble supported)

                        * 6.0 Mbps

                        * 9.0 Mbps

                        * 12.0 Mbps

                        * 18.0 Mbps

                        * 24.0 Mbps

                        * 36.0 Mbps

                        * 48.0 Mbps

                        * 54.0 Mbps

        Band 2:

                Capabilities: 0x11ef

                        RX LDCP

                        HT20/HT40

                        SM Power Save disabled

                        RX HT20 SGI

                        RX HT40 SGI

                        TX STBC

                        RX STBC 1-stream

                        Max AMSDU length: 7935 bytes

                        DSSS/CCK HT40

                Maximum RX AMPDU length 65535 bytes (exponent: 0x003)

                Minimum RX AMPDU time spacing: 8 usec (0x06)

                HT TX/RX MCS rate indexes supported: 0-23

                Frequencies:

                        * 5180 MHz [36] (20.0 dBm)

                        * 5200 MHz [40] (20.0 dBm)

                        * 5220 MHz [44] (20.0 dBm)

                        * 5240 MHz [48] (20.0 dBm)

                        * 5260 MHz [52] (20.0 dBm) (passive scanning, no =
IBSS, radar detection)

                        * 5280 MHz [56] (20.0 dBm) (passive scanning, no =
IBSS, radar detection)

                        * 5300 MHz [60] (20.0 dBm) (passive scanning, no =
IBSS, radar detection)

                        * 5320 MHz [64] (20.0 dBm) (passive scanning, no =
IBSS, radar detection)

                        * 5500 MHz [100] (disabled)

                        * 5520 MHz [104] (disabled)

                        * 5540 MHz [108] (disabled)

                        * 5560 MHz [112] (disabled)

                        * 5580 MHz [116] (disabled)

                        * 5600 MHz [120] (disabled)

                        * 5620 MHz [124] (disabled)

                        * 5640 MHz [128] (disabled)

                        * 5660 MHz [132] (disabled)

                        * 5680 MHz [136] (disabled)

                        * 5700 MHz [140] (disabled)

                        * 5745 MHz [149] (disabled)

                        * 5765 MHz [153] (disabled)

                        * 5785 MHz [157] (disabled)

                        * 5805 MHz [161] (disabled)

                        * 5825 MHz [165] (disabled)

                Bitrates (non-HT):

                        * 6.0 Mbps

                        * 9.0 Mbps

                        * 12.0 Mbps

                        * 18.0 Mbps

                        * 24.0 Mbps

                        * 36.0 Mbps

                        * 48.0 Mbps

                        * 54.0 Mbps

        max # scan SSIDs: 4

        Supported interface modes:

                 * IBSS

                 * managed

                 * AP

                 * AP/VLAN

                 * WDS

                 * monitor

                 * mesh point

                 * Unknown mode (8)

                 * Unknown mode (9)

        Supported commands:

                 * new_interface

                 * set_interface

                 * new_key

                 * new_beacon

                 * new_station

                 * new_mpath

                 * set_mesh_params

                 * set_bss

                 * authenticate

                 * associate

                 * deauthenticate

                 * disassociate

                 * join_ibss

                 * Unknown command (68)

                 * Unknown command (55)

                 * Unknown command (57)

                 * Unknown command (59)

                 * Unknown command (67)

                 * set_wiphy_netns

                 * Unknown command (65)

                 * Unknown command (66)

                 * Unknown command (82)

                 * Unknown command (81)

                 * Unknown command (84)

                 * Unknown command (87)

                 * Unknown command (85)

                 * testmode

                 * connect

                 * disconnect

=20

=20

# cat /etc/hostapd.conf

# Schnittstelle und Treiber

interface=3Dwlan0

driver=3Dnl80211

=20

# WLAN-Konfiguration

ssid=3Dxxxx

channel=3D6

=20

# ESSID sichtbar

ignore_broadcast_ssid=3D0

=20

# L=E4ndereinstellungen

country_code=3DCH

ieee80211d=3D1

=20

# =DCbertragungsmodus

hw_mode=3Dg

# Optionale Einstellungen

# supported_rates=3D10 20 55 110 60 90 120 180 240 360 480 540

=20

# Draft-N Modus aktivieren / optional nur f=FCr entsprechende Karten

# ieee80211n=3D1

ieee80211n=3D1

=20

# Beacons

beacon_int=3D100

dtim_period=3D2

=20

# MAC-Authentifizierung

macaddr_acl=3D0

=20

# max. Anzahl der Clients

max_num_sta=3D255

=20

# Gr=F6=DFe der Datenpakete/Begrenzung

rts_threshold=3D2347

fragm_threshold=3D2346

=20

# hostapd Log Einstellungen

logger_syslog=3D-1

logger_syslog_level=3D2

logger_stdout=3D-1

logger_stdout_level=3D2

=20

# tempor=E4re Konfigurationsdateien

dump_file=3D/tmp/hostapd.dump

ctrl_interface=3D/var/run/hostapd

ctrl_interface_group=3D0

=20

# Authentifizierungsoptionen

auth_algs=3D1

=20

# wmm-Funktionalit=E4t

wmm_enabled=3D0

=20

# Verschl=FCsselung / hier rein WPA2

macaddr_acl=3D0

wpa=3D2

rsn_preauth=3D1

rsn_preauth_interfaces=3Dwlan0

wpa_key_mgmt=3DWPA-PSK

wpa_pairwise=3DTKIP

rsn_pairwise=3DCCMP

=20

# Schl=FCsselintervalle / Standardkonfiguration

wpa_group_rekey=3D600

wpa_ptk_rekey=3D600

wpa_gmk_rekey=3D86400

=20

# Zugangsschl=FCssel (PSK) / hier in Klartext (ASCII)

wpa_passphrase=3Dxxxx

=20

=20

[    0.000000] Linux version 3.3.0-rc2-1+ (root@linux) (gcc version =
4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) ) #1 SMP Tue Feb 14
13:17:34 CET 2012

[    0.000000] Command line: BOOT_IMAGE=3D/vmlinuz-3.3.0-rc2-1+ =
root=3DUUID=3Dcfc15d9c-2cd1-4bad-9e9d-f2fa1ded76e2 ro

[    9.201360] ath: EEPROM regdomain: 0x21

[    9.201362] ath: EEPROM indicates we should expect a direct regpair =
map

[    9.201363] ath: Country alpha2 being used: AU

[    9.201364] ath: Regpair used: 0x21

[    9.531824] ieee80211 phy0: Selected rate control algorithm =
'ath9k_rate_control'

[    9.532132] Registered led device: ath9k-phy0

[    7.594696] cfg80211: Calling CRDA to update world regulatory domain

[    8.966680] cfg80211: World regulatory domain updated:

[    8.966682] cfg80211:   (start_freq - end_freq @ bandwidth), =
(max_antenna_gain, max_eirp)

[    8.966684] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    8.966686] cfg80211:   (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 =
mBi, 2000 mBm)

[    8.966687] cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 =
mBi, 2000 mBm)

[    8.966688] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    8.966689] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.201366] cfg80211: Updating information on frequency 2412 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201368] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201369] cfg80211: Updating information on frequency 2417 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201370] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201371] cfg80211: Updating information on frequency 2422 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201373] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201374] cfg80211: Updating information on frequency 2427 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201375] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201376] cfg80211: Updating information on frequency 2432 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201378] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201379] cfg80211: Updating information on frequency 2437 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201380] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201381] cfg80211: Updating information on frequency 2442 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201383] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201384] cfg80211: Updating information on frequency 2447 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201385] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201386] cfg80211: Updating information on frequency 2452 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201388] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201389] cfg80211: Updating information on frequency 2457 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201390] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201391] cfg80211: Updating information on frequency 2462 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201393] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.201394] cfg80211: Disabling freq 2467 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201395] cfg80211: Disabling freq 2472 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201396] cfg80211: Disabling freq 2484 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201398] cfg80211: Updating information on frequency 5180 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201399] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201400] cfg80211: Updating information on frequency 5200 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201402] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201403] cfg80211: Updating information on frequency 5220 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201404] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201405] cfg80211: Updating information on frequency 5240 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201407] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201408] cfg80211: Updating information on frequency 5260 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201409] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201410] cfg80211: Updating information on frequency 5280 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201412] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201413] cfg80211: Updating information on frequency 5300 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201414] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201415] cfg80211: Updating information on frequency 5320 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201417] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201418] cfg80211: Disabling freq 5500 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201419] cfg80211: Disabling freq 5520 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201420] cfg80211: Disabling freq 5540 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201422] cfg80211: Disabling freq 5560 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201423] cfg80211: Disabling freq 5580 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201424] cfg80211: Disabling freq 5600 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201425] cfg80211: Disabling freq 5620 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201426] cfg80211: Disabling freq 5640 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201428] cfg80211: Disabling freq 5660 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201429] cfg80211: Disabling freq 5680 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201430] cfg80211: Disabling freq 5700 MHz as custom regd has no =
rule that fits a 20 MHz wide channel

[    9.201431] cfg80211: Updating information on frequency 5745 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201433] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201434] cfg80211: Updating information on frequency 5765 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201435] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201436] cfg80211: Updating information on frequency 5785 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201438] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201439] cfg80211: Updating information on frequency 5805 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201440] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.201441] cfg80211: Updating information on frequency 5825 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.201443] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A =
mBi, 3000 mBm)

[    9.202827] cfg80211: Updating information on frequency 2412 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202829] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202830] cfg80211: Updating information on frequency 2417 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202831] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202833] cfg80211: Updating information on frequency 2422 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202834] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202845] cfg80211: Updating information on frequency 2427 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202847] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202848] cfg80211: Updating information on frequency 2432 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202849] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202851] cfg80211: Updating information on frequency 2437 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202852] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202853] cfg80211: Updating information on frequency 2442 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202855] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202856] cfg80211: Updating information on frequency 2447 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202857] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202859] cfg80211: Updating information on frequency 2452 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202860] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202861] cfg80211: Updating information on frequency 2457 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202863] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202864] cfg80211: Updating information on frequency 2462 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202865] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202867] cfg80211: Updating information on frequency 2467 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202868] cfg80211: 2457000 KHz - 2482000 KHz @ 20000 KHz), (300 =
mBi, 2000 mBm)

[    9.202869] cfg80211: Updating information on frequency 2472 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202871] cfg80211: 2457000 KHz - 2482000 KHz @ 20000 KHz), (300 =
mBi, 2000 mBm)

[    9.202872] cfg80211: Updating information on frequency 2484 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202874] cfg80211: 2474000 KHz - 2494000 KHz @ 20000 KHz), (300 =
mBi, 2000 mBm)

[    9.202875] cfg80211: Updating information on frequency 5180 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202877] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202878] cfg80211: Updating information on frequency 5200 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202879] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202881] cfg80211: Updating information on frequency 5220 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202882] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202884] cfg80211: Updating information on frequency 5240 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202885] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202887] cfg80211: Disabling freq 5260 MHz

[    9.202897] cfg80211: Disabling freq 5280 MHz

[    9.202898] cfg80211: Disabling freq 5300 MHz

[    9.202899] cfg80211: Disabling freq 5320 MHz

[    9.202900] cfg80211: Disabling freq 5500 MHz

[    9.202901] cfg80211: Disabling freq 5520 MHz

[    9.202901] cfg80211: Disabling freq 5540 MHz

[    9.202902] cfg80211: Disabling freq 5560 MHz

[    9.202903] cfg80211: Disabling freq 5580 MHz

[    9.202904] cfg80211: Disabling freq 5600 MHz

[    9.202905] cfg80211: Disabling freq 5620 MHz

[    9.202905] cfg80211: Disabling freq 5640 MHz

[    9.202916] cfg80211: Disabling freq 5660 MHz

[    9.202917] cfg80211: Disabling freq 5680 MHz

[    9.202918] cfg80211: Disabling freq 5700 MHz

[    9.202919] cfg80211: Updating information on frequency 5745 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202920] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202921] cfg80211: Updating information on frequency 5765 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202923] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202924] cfg80211: Updating information on frequency 5785 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202925] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202926] cfg80211: Updating information on frequency 5805 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202928] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.202929] cfg80211: Updating information on frequency 5825 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.202930] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 2000 mBm)

[    9.532113] cfg80211: Calling CRDA for country: AU

[    9.533522] cfg80211: Updating information on frequency 2412 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533524] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533525] cfg80211: Updating information on frequency 2417 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533527] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533528] cfg80211: Updating information on frequency 2422 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533530] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533531] cfg80211: Updating information on frequency 2427 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533533] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533534] cfg80211: Updating information on frequency 2432 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533535] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533537] cfg80211: Updating information on frequency 2437 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533538] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533539] cfg80211: Updating information on frequency 2442 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533541] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533542] cfg80211: Updating information on frequency 2447 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533544] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533545] cfg80211: Updating information on frequency 2452 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533546] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533547] cfg80211: Updating information on frequency 2457 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533549] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533550] cfg80211: Updating information on frequency 2462 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533552] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533553] cfg80211: Updating information on frequency 2467 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533554] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533556] cfg80211: Updating information on frequency 2472 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533557] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)

[    9.533558] cfg80211: Disabling freq 2484 MHz

[    9.533559] cfg80211: Updating information on frequency 5180 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533561] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533562] cfg80211: Updating information on frequency 5200 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533564] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533565] cfg80211: Updating information on frequency 5220 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533566] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533568] cfg80211: Updating information on frequency 5240 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533569] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533570] cfg80211: Updating information on frequency 5260 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533572] cfg80211: 5250000 KHz - 5330000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533573] cfg80211: Updating information on frequency 5280 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533575] cfg80211: 5250000 KHz - 5330000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533576] cfg80211: Updating information on frequency 5300 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533577] cfg80211: 5250000 KHz - 5330000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533579] cfg80211: Updating information on frequency 5320 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533580] cfg80211: 5250000 KHz - 5330000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533581] cfg80211: Disabling freq 5500 MHz

[    9.533582] cfg80211: Disabling freq 5520 MHz

[    9.533583] cfg80211: Disabling freq 5540 MHz

[    9.533584] cfg80211: Disabling freq 5560 MHz

[    9.533585] cfg80211: Disabling freq 5580 MHz

[    9.533585] cfg80211: Disabling freq 5600 MHz

[    9.533586] cfg80211: Disabling freq 5620 MHz

[    9.533587] cfg80211: Disabling freq 5640 MHz

[    9.533588] cfg80211: Disabling freq 5660 MHz

[    9.533589] cfg80211: Disabling freq 5680 MHz

[    9.533590] cfg80211: Disabling freq 5700 MHz

[    9.533591] cfg80211: Updating information on frequency 5745 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533592] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)

[    9.533593] cfg80211: Updating information on frequency 5765 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533595] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)

[    9.533596] cfg80211: Updating information on frequency 5785 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533597] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)

[    9.533599] cfg80211: Updating information on frequency 5805 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533600] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)

[    9.533601] cfg80211: Updating information on frequency 5825 MHz for =
a 20 MHz width channel with regulatory rule:

[    9.533603] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)

[    9.533606] cfg80211: Regulatory domain changed to country: AU

[    9.533607] cfg80211:   (start_freq - end_freq @ bandwidth), =
(max_antenna_gain, max_eirp)

[    9.533608] cfg80211:   (2402000 KHz - 2482000 KHz @ 40000 KHz), =
(N/A, 2000 mBm)

[    9.533609] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533611] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (300 =
mBi, 2300 mBm)

[    9.533612] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 =
mBi, 3000 mBm)


------=_NextPart_000_0CFF_01CD01BB.A7359070
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" =
xmlns=3D"http://www.w3.org/TR/REC-html40"><head><meta =
http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1"><meta name=3DGenerator content=3D"Microsoft Word =
12 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0cm;
	margin-bottom:.0001pt;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:purple;
	text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
	{mso-style-priority:34;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:36.0pt;
	margin-bottom:.0001pt;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";}
span.EmailStyle17
	{mso-style-type:personal-compose;
	font-family:"Calibri","sans-serif";
	color:windowtext;}
.MsoChpDefault
	{mso-style-type:export-only;}
@page WordSection1
	{size:612.0pt 792.0pt;
	margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
	{page:WordSection1;}
/* List Definitions */
@list l0
	{mso-list-id:1667975767;
	mso-list-type:hybrid;
	mso-list-template-ids:1557444888 -1730749342 67698691 67698693 67698689 =
67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
	{mso-level-start-at:2012;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:none;
	mso-level-number-position:left;
	text-indent:-18.0pt;
	font-family:"Calibri","sans-serif";
	mso-fareast-font-family:Calibri;
	mso-bidi-font-family:"Times New Roman";}
ol
	{margin-bottom:0cm;}
ul
	{margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3Dblue =
vlink=3Dpurple><div class=3DWordSection1><p =
class=3DMsoNormal>Hello<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>I have a TP =
Link WDN4800 (ar9380). A Windows 802.11n client showed 72Mb connection, =
150Mb should be possible. inSSIDer showed 195Mb. I want to have it =
optimized for 2.4Ghz. <o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>iw =
list:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX LDCP<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0=A0HT20/HT40<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 SM Power Save disabled<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX HT20 SGI<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX HT40 SGI<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 TX STBC<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX STBC 1-stream<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 Max AMSDU length: 7935 bytes<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 DSSS/CCK HT40<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>I =
haven&#8217;t found a complete guide (<a =
href=3D"http://linuxwireless.org/en/users/Documentation/hostapd">http://l=
inuxwireless.org/en/users/Documentation/hostapd</a>) for the ht_capab =
settings or some guidance to map them from iw list. Iw list shows HT20, =
what should/can be used, HT20, or HT20- or HT20+, with or without HT40*. =
Mapping to much seems also not to good.<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoListParagraph =
style=3D'text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if =
!supportLists]><span style=3D'mso-list:Ignore'>-<span =
style=3D'font:7.0pt "Times New =
Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
</span></span><![endif]>What are the most optimized settings for =
ht_capab ?<o:p></o:p></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><p =
class=3DMsoNormal>From the guide and hostapd.conf (<a =
href=3D"http://hostap.epitest.fi/gitweb/gitweb.cgi?p=3Dhostap.git;a=3Dblo=
b_plain;f=3Dhostapd/hostapd.conf">http://hostap.epitest.fi/gitweb/gitweb.=
cgi?p=3Dhostap.git;a=3Dblob_plain;f=3Dhostapd/hostapd.conf</a>), =A0I =
cannot find what wme_enabled is.<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoListParagraph =
style=3D'text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if =
!supportLists]><span style=3D'mso-list:Ignore'>-<span =
style=3D'font:7.0pt "Times New =
Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
</span></span><![endif]>What does wme_enabled do ? Is it needed in =
conjunction with ht_capab ?<o:p></o:p></p><p class=3DMsoNormal> =
<o:p></o:p></p><p class=3DMsoNormal>Another question, I live in CH, a =
reboot shows <o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201363] =
ath: Country alpha2 being used: AU<o:p></o:p></p><p =
class=3DMsoNormal>And changed it to CH. <o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoListParagraph =
style=3D'text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if =
!supportLists]><span style=3D'mso-list:Ignore'>-<span =
style=3D'font:7.0pt "Times New =
Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
</span></span><![endif]>Which limitation can I expect, for not being a =
European Card, as it propagates AU ?<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>Below I =
added lspci, iw list, hostapd.conf, dmesg output.<o:p></o:p></p><p =
class=3DMsoNormal><a =
href=3D"http://www.tp-link.com/en/products/details/?model=3DTL-WDN4800#sp=
ec">http://www.tp-link.com/en/products/details/?model=3DTL-WDN4800#spec</=
a><o:p></o:p></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><p =
class=3DMsoNormal>Thanks for your help<o:p></o:p></p><p =
class=3DMsoNormal>Angela<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># lspci -vvd =
168c:<o:p></o:p></p><p class=3DMsoNormal>02:00.0 Network controller: =
Atheros Communications Inc. AR9300 Wireless LAN adaptor (rev =
01)<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Subsystem: =
Atheros Communications Inc. Device 3112<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Control: I/O+ Mem+ BusMaster+ =
SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- =
DisINTx-<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 <span =
lang=3DDE-CH>Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfast =
&gt;TAbort- &lt;TAbort- &lt;MAbort- &gt;SERR- &lt;PERR- =
INTx-<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>=A0=A0=A0=A0=A0=A0=A0 </span>Latency: 0, Cache Line Size: =
64 bytes<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 =
Interrupt: pin A routed to IRQ 17<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Region 0: Memory at fbe00000 =
(64-bit, non-prefetchable) [size=3D128K]<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Expansion ROM at fbe20000 =
[disabled] [size=3D64K]<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [40] Power =
Management version 3<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Flags: =
PMEClk- DSI- D1+ D2- AuxCurrent=3D375mA =
PME(D0+,D1+,D2-,D3hot+,D3cold-)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Status: =
D0 NoSoftRst- PME-Enable- DSel=3D0 DScale=3D0 PME-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [50] MSI: Enable- =
Count=3D1/4 Maskable+ 64bit+<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Address: =
0000000000000000=A0 Data: 0000<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Masking: =
00000000=A0 Pending: 00000000<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [70] Express (v2) =
Endpoint, MSI 00<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 DevCap: =
MaxPayload 128 bytes, PhantFunc 0, Latency L0s &lt;1us, L1 =
&lt;8us<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 <span lang=3DDE-CH>ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ =
FLReset-<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
</span>DevCtl: Report errors: Correctable- Non-Fatal- Fatal- =
Unsupported-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RlxdOrd- ExtTag- PhantFunc- AuxPwr- =
NoSnoop-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 MaxPayload 128 bytes, MaxReadReq 512 bytes<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 DevSta: =
CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- =
TransPend-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LnkCap: =
Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 &lt;2us, L1 =
&lt;64us<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 ClockPM- Surprise- LLActRep- BwNot-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LnkCtl: =
ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 ExtSynch- ClockPM- AutWidDis- BWInt- =
AutBWInt-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LnkSta: =
Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- =
ABWMgmt-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 DevCap2: =
Completion Timeout: Not Supported, TimeoutDis+<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 DevCtl2: =
Completion Timeout: 50us to 50ms, TimeoutDis-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LnkCtl2: =
Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable =
De-emphasis: -6dB<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 Transmit Margin: Normal Operating Range, =
EnterModifiedCompliance- ComplianceSOS-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 Compliance De-emphasis: -6dB<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LnkSta2: =
Current De-emphasis Level: -6dB<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [100 v1] Advanced =
Error Reporting<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
UESta:=A0 DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- =
MalfTLP- ECRC- UnsupReq- ACSViol-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
=A0=A0UEMsk:=A0 DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- =
MalfTLP- ECRC- UnsupReq- ACSViol-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 UESvrt: =
DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- =
UnsupReq- ACSViol-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
CESta:=A0 RxErr- BadTLP- BadDLLP- Rollover- Timeout- =
NonFatalErr-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
CEMsk:=A0 RxErr- BadTLP- BadDLLP- Rollover- Timeout- =
NonFatalErr+<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 AERCap: =
First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [140 v1] Virtual =
Channel<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0Caps:=A0=A0 LPEVC=3D0 RefClk=3D100ns =
PATEntryBits=3D1<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Arb:=A0=A0=A0 Fixed- WRR32- WRR64- WRR128-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Ctrl:=A0=A0 ArbSelect=3DFixed<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Status: =
InProgress-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
VC0:=A0=A0=A0 Caps:=A0=A0 PATOffset=3D00 MaxTimeSlots=3D1 =
RejSnoopTrans-<o:p></o:p></p><p class=3DMsoNormal> =
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0Arb:=
=A0=A0=A0 Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 Ctrl:=A0=A0 Enable+ ID=3D0 ArbSelect=3DFixed =
TC/VC=3D01<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 Status: NegoPending- InProgress-<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Capabilities: [300 v1] Device =
Serial Number 00-00-00-00-00-00-00-00<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Kernel driver in use: =
ath9k<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Kernel =
modules: ath9k<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># iw =
list<o:p></o:p></p><p class=3DMsoNormal>Wiphy phy0<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Band 1:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Capabilities: 0x11ef<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX LDCP<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 HT20/HT40<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 SM Power Save disabled<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX HT20 SGI<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX HT40 SGI<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 TX STBC<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX STBC 1-stream<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 Max AMSDU length: 7935 bytes<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 DSSS/CCK HT40<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Maximum =
RX AMPDU length 65535 bytes (exponent: 0x003)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Minimum =
RX AMPDU time spacing: 8 usec (0x06)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 HT TX/RX =
MCS rate indexes supported: 0-23<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Frequencies:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2412 MHz [1] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2417 MHz [2] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2422 MHz [3] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2427 MHz [4] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2432 MHz [5] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2437 MHz [6] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2442 MHz [7] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2447 MHz [8] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2452 MHz [9] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2457 MHz [10] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2462 MHz [11] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2467 MHz [12] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0* 2472 =
MHz [13] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2484 MHz [14] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Bitrates =
(non-HT):<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 1.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 2.0 Mbps (short preamble supported)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5.5 Mbps (short preamble supported)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 11.0 Mbps (short preamble supported)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 6.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 9.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 12.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 18.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 24.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 36.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 48.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 54.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Band 2:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Capabilities: 0x11ef<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX LDCP<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0=A0HT20/HT40<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 SM Power Save disabled<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 <span lang=3DDE-CH>RX HT20 SGI<o:p></o:p></span></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 RX HT40 SGI<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 </span>TX STBC<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 RX STBC 1-stream<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 Max AMSDU length: 7935 bytes<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 DSSS/CCK HT40<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Maximum =
RX AMPDU length 65535 bytes (exponent: 0x003)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Minimum =
RX AMPDU time spacing: 8 usec (0x06)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 HT TX/RX =
MCS rate indexes supported: 0-23<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
Frequencies:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5180 MHz [36] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5200 MHz [40] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5220 MHz [44] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5240 MHz [48] (20.0 dBm)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5260 MHz [52] (20.0 dBm) (passive scanning, no IBSS, =
radar detection)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5280 MHz [56] (20.0 dBm) (passive scanning, no IBSS, =
radar detection)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5300 MHz [60] (20.0 dBm) (passive scanning, no IBSS, =
radar detection)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5320 MHz [64] (20.0 dBm) (passive scanning, no IBSS, =
radar detection)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5500 MHz [100] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5520 MHz [104] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5540 MHz [108] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5560 MHz [112] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5580 MHz [116] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5600 MHz [120] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5620 MHz [124] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
 =A0=A0=A0=A0* 5640 MHz [128] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5660 MHz [132] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5680 MHz [136] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5700 MHz [140] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5745 MHz [149] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0=A0* 5765 MHz [153] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5785 MHz [157] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5805 MHz [161] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 5825 MHz [165] (disabled)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Bitrates =
(non-HT):<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 6.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 9.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 12.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 18.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 24.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 36.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 48.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 * 54.0 Mbps<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 max # scan SSIDs: =
4<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Supported =
interface modes:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
IBSS<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
managed<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
AP<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
AP/VLAN<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
WDS<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
monitor<o:p></o:p></p><p class=3DMsoNormal>=A0=A0=A0=A0=A0=A0 =
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0* mesh point<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown mode (8)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown mode (9)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0 Supported =
commands:<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
new_interface<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
set_interface<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
new_key<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
new_beacon<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0* =
new_station<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
new_mpath<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
set_mesh_params<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
set_bss<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
authenticate<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
associate<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
deauthenticate<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
disassociate<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
join_ibss<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (68)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (55)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (57)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (59)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (67)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
set_wiphy_netns<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (65)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (66)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (82)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (81)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (84)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
Unknown command (87)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0* =
Unknown command (85)<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
testmode<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
connect<o:p></o:p></p><p =
class=3DMsoNormal>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * =
disconnect<o:p></o:p></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal><span =
lang=3DDE-CH># cat /etc/hostapd.conf<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># Schnittstelle und =
Treiber<o:p></o:p></span></p><p =
class=3DMsoNormal>interface=3Dwlan0<o:p></o:p></p><p =
class=3DMsoNormal>driver=3Dnl80211<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># =
WLAN-Konfiguration<o:p></o:p></p><p =
class=3DMsoNormal>ssid=3Dxxxx<o:p></o:p></p><p =
class=3DMsoNormal>channel=3D6<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># ESSID =
sichtbar<o:p></o:p></p><p =
class=3DMsoNormal>ignore_broadcast_ssid=3D0<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal><span =
lang=3DDE-CH># L=E4ndereinstellungen<o:p></o:p></span></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>country_code=3DCH<o:p></o:p></span></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>ieee80211d=3D1<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># =
=DCbertragungsmodus<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>hw_mode=3Dg<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH># Optionale Einstellungen<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># supported_rates=3D10 20 55 110 60 =
90 120 180 240 360 480 540<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># Draft-N Modus aktivieren / =
optional nur f=FCr entsprechende Karten<o:p></o:p></span></p><p =
class=3DMsoNormal># ieee80211n=3D1<o:p></o:p></p><p =
class=3DMsoNormal>ieee80211n=3D1<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># =
Beacons<o:p></o:p></p><p =
class=3DMsoNormal>beacon_int=3D100<o:p></o:p></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>dtim_period=3D2<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># =
MAC-Authentifizierung<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>macaddr_acl=3D0<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># max. Anzahl der =
Clients<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>max_num_sta=3D255<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># Gr=F6=DFe der =
Datenpakete/Begrenzung<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>rts_threshold=3D2347<o:p></o:p></span></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>fragm_threshold=3D2346<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># hostapd Log =
Einstellungen<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>logger_syslog=3D-1<o:p></o:p></span></p><p =
class=3DMsoNormal>logger_syslog_level=3D2<o:p></o:p></p><p =
class=3DMsoNormal>logger_stdout=3D-1<o:p></o:p></p><p =
class=3DMsoNormal>logger_stdout_level=3D2<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># =
tempor=E4re Konfigurationsdateien<o:p></o:p></p><p =
class=3DMsoNormal>dump_file=3D/tmp/hostapd.dump<o:p></o:p></p><p =
class=3DMsoNormal>ctrl_interface=3D/var/run/hostapd<o:p></o:p></p><p =
class=3DMsoNormal>ctrl_interface_group=3D0<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal><span =
lang=3DDE-CH># Authentifizierungsoptionen<o:p></o:p></span></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>auth_algs=3D1<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># =
wmm-Funktionalit=E4t<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>wmm_enabled=3D0<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># Verschl=FCsselung / hier rein =
WPA2<o:p></o:p></span></p><p class=3DMsoNormal><span =
lang=3DDE-CH>macaddr_acl=3D0<o:p></o:p></span></p><p =
class=3DMsoNormal>wpa=3D2<o:p></o:p></p><p =
class=3DMsoNormal>rsn_preauth=3D1<o:p></o:p></p><p =
class=3DMsoNormal>rsn_preauth_interfaces=3Dwlan0<o:p></o:p></p><p =
class=3DMsoNormal>wpa_key_mgmt=3DWPA-PSK<o:p></o:p></p><p =
class=3DMsoNormal>wpa_pairwise=3DTKIP<o:p></o:p></p><p =
class=3DMsoNormal>rsn_pairwise=3DCCMP<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal># =
Schl=FCsselintervalle / Standardkonfiguration<o:p></o:p></p><p =
class=3DMsoNormal>wpa_group_rekey=3D600<o:p></o:p></p><p =
class=3DMsoNormal>wpa_ptk_rekey=3D600<o:p></o:p></p><p =
class=3DMsoNormal><span =
lang=3DDE-CH>wpa_gmk_rekey=3D86400<o:p></o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH><o:p>&nbsp;</o:p></span></p><p =
class=3DMsoNormal><span lang=3DDE-CH># Zugangsschl=FCssel (PSK) / hier =
in Klartext (ASCII)<o:p></o:p></span></p><p =
class=3DMsoNormal>wpa_passphrase=3Dxxxx<o:p></o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p =
class=3DMsoNormal><o:p>&nbsp;</o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
0.000000] Linux version 3.3.0-rc2-1+ (root at linux) (gcc version 4.6.1 =
(Ubuntu/Linaro 4.6.1-9ubuntu3) ) #1 SMP Tue Feb 14 13:17:34 CET =
2012<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 0.000000] Command =
line: BOOT_IMAGE=3D/vmlinuz-3.3.0-rc2-1+ =
root=3DUUID=3Dcfc15d9c-2cd1-4bad-9e9d-f2fa1ded76e2 ro<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201360] ath: EEPROM regdomain: =
0x21<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201362] ath: EEPROM =
indicates we should expect a direct regpair map<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201363] ath: Country alpha2 being used: =
AU<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201364] ath: Regpair =
used: 0x21<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.531824] =
ieee80211 phy0: Selected rate control algorithm =
'ath9k_rate_control'<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.532132] Registered led device: ath9k-phy0<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 7.594696] cfg80211: Calling CRDA to update =
world regulatory domain<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
8.966680] cfg80211: World regulatory domain updated:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966682] cfg80211:=A0=A0 (start_freq - =
end_freq @ bandwidth), (max_antenna_gain, max_eirp)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966684] cfg80211:=A0=A0 (2402000 KHz - =
2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966686] cfg80211:=A0=A0 (2457000 KHz - =
2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966687] cfg80211:=A0=A0 (2474000 KHz - =
2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966688] cfg80211:=A0=A0 (5170000 KHz - =
5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 8.966689] cfg80211:=A0=A0 (5735000 KHz - =
5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201366] cfg80211: Updating information on =
frequency 2412 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201368] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201369] cfg80211: =
Updating information on frequency 2417 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201370] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201371] =
cfg80211: Updating information on frequency 2422 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201373] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201374] cfg80211: Updating information on =
frequency 2427 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201375] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201376] cfg80211: =
Updating information on frequency 2432 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0 =
=A0=A09.201378] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A =
mBi, 2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201379] =
cfg80211: Updating information on frequency 2437 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201380] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201381] cfg80211: Updating information on =
frequency 2442 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201383] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201384] cfg80211: =
Updating information on frequency 2447 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201385] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201386] =
cfg80211: Updating information on frequency 2452 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201388] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201389] cfg80211: Updating information on =
frequency 2457 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201390] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201391] cfg80211: =
Updating information on frequency 2462 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201393] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201394] =
cfg80211: Disabling freq 2467 MHz as custom regd has no rule that fits a =
20 MHz wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201395] cfg80211: Disabling freq 2472 MHz as custom regd has no rule =
that fits a 20 MHz wide channel<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201396] cfg80211: Disabling freq 2484 MHz =
as custom regd has no rule that fits a 20 MHz wide =
channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201398] =
cfg80211: Updating information on frequency 5180 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201399] cfg80211: 5140000 KHz - 5360000 =
KHz @ 40000 KHz), (N/A mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201400] cfg80211: Updating information on =
frequency 5200 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201402] cfg80211: =
5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201403] cfg80211: =
Updating information on frequency 5220 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201404] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A mBi, =
3000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201405] =
cfg80211: Updating information on frequency 5240 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201407] cfg80211: 5140000 KHz - 5360000 =
KHz @ 40000 KHz), (N/A mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201408] cfg80211: Updating information on =
frequency 5260 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201409] cfg80211: =
5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201410] cfg80211: =
Updating information on frequency 5280 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201412] cfg80211: 5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A mBi, =
3000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201413] =
cfg80211: Updating information on frequency 5300 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201414] cfg80211: 5140000 KHz - 5360000 =
KHz @ 40000 KHz), (N/A mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201415] cfg80211: Updating information on =
frequency 5320 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201417] cfg80211: =
5140000 KHz - 5360000 KHz @ 40000 KHz), (N/A mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201418] cfg80211: =
Disabling freq 5500 MHz as custom regd has no rule that fits a 20 MHz =
wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201419] =
cfg80211: Disabling freq 5520 MHz as custom regd has no rule that fits a =
20 MHz wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201420] cfg80211: Disabling freq 5540 MHz as custom regd has no rule =
that fits a 20 MHz wide channel<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201422] cfg80211: Disabling freq 5560 MHz =
as custom regd has no rule that fits a 20 MHz wide =
channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201423] =
cfg80211: Disabling freq 5580 MHz as custom regd has no rule that fits a =
20 MHz wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201424] cfg80211: Disabling freq 5600 MHz as custom regd has no rule =
that fits a 20 MHz wide channel<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201425] cfg80211: Disabling freq 5620 MHz =
as custom regd has no rule that fits a 20 MHz wide =
channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201426] =
cfg80211: Disabling freq 5640 MHz as custom regd has no rule that fits a =
20 MHz wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201428] cfg80211: Disabling freq 5660 MHz as custom regd has no rule =
that fits a 20 MHz wide channel<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201429] cfg80211: Disabling freq 5680 MHz =
as custom regd has no rule that fits a 20 MHz wide =
channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201430] =
cfg80211: Disabling freq 5700 MHz as custom regd has no rule that fits a =
20 MHz wide channel<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201431] cfg80211: Updating information on frequency 5745 MHz for a 20 =
MHz width channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201433] cfg80211: 5715000 KHz - 5860000 =
KHz @ 40000 KHz), (N/A mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201434] cfg80211: Updating information on =
frequency 5765 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201435] cfg80211: =
5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201436] cfg80211: =
Updating information on frequency 5785 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.201438] cfg80211: 5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A mBi, =
3000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201439] =
cfg80211: Updating information on frequency 5805 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201440] cfg80211: 5715000 KHz - 5860000 =
KHz @ 40000 KHz), (N/A mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.201441] cfg80211: Updating information on =
frequency 5825 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.201443] cfg80211: =
5715000 KHz - 5860000 KHz @ 40000 KHz), (N/A mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202827] cfg80211: =
Updating information on frequency 2412 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202829] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202830] =
cfg80211: Updating information on frequency 2417 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202831] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202833] cfg80211: Updating information on =
frequency 2422 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202834] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202845] cfg80211: =
Updating information on frequency 2427 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202847] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202848] =
cfg80211: Updating information on frequency 2432 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202849] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202851] cfg80211: Updating information on =
frequency 2437 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202852] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202853] cfg80211: =
Updating information on frequency 2442 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202855] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202856] =
cfg80211: Updating information on frequency 2447 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202857] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202859] cfg80211: Updating information on =
frequency 2452 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202860] cfg80211: =
2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202861] cfg80211: =
Updating information on frequency 2457 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202863] cfg80211: 2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202864] =
cfg80211: Updating information on frequency 2462 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202865] cfg80211: 2402000 KHz - 2472000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202867] cfg80211: Updating information on =
frequency 2467 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202868] cfg80211: =
2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202869] cfg80211: =
Updating information on frequency 2472 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202871] cfg80211: 2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202872] =
cfg80211: Updating information on frequency 2484 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202874] cfg80211: 2474000 KHz - 2494000 =
KHz @ 20000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202875] cfg80211: Updating information on =
frequency 5180 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202877] cfg80211: =
5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202878] cfg80211: =
Updating information on frequency 5200 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202879] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202881] =
cfg80211: Updating information on frequency 5220 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202882] cfg80211: 5170000 KHz - 5250000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202884] cfg80211: Updating information on =
frequency 5240 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202885] cfg80211: =
5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202887] cfg80211: =
Disabling freq 5260 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202897] cfg80211: Disabling freq 5280 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202898] cfg80211: Disabling freq 5300 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202899] cfg80211: =
Disabling freq 5320 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202900] cfg80211: Disabling freq 5500 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202901] cfg80211: Disabling freq 5520 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202901] cfg80211: =
Disabling freq 5540 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202902] cfg80211: Disabling freq 5560 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202903] cfg80211: Disabling freq 5580 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202904] cfg80211: =
Disabling freq 5600 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202905] cfg80211: Disabling freq 5620 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202905] cfg80211: Disabling freq 5640 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202916] cfg80211: =
Disabling freq 5660 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202917] cfg80211: Disabling freq 5680 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202918] cfg80211: Disabling freq 5700 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202919] cfg80211: =
Updating information on frequency 5745 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202920] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202921] =
cfg80211: Updating information on frequency 5765 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202923] cfg80211: 5735000 KHz - 5835000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202924] cfg80211: Updating information on =
frequency 5785 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202925] cfg80211: =
5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202926] cfg80211: =
Updating information on frequency 5805 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.202928] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.202929] =
cfg80211: Updating information on frequency 5825 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.202930] cfg80211: 5735000 KHz - 5835000 =
KHz @ 40000 KHz), (300 mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.532113] cfg80211: Calling CRDA for =
country: AU<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533522] =
cfg80211: Updating information on frequency 2412 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533524] cfg80211: 2402000 KHz - 2482000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533525] cfg80211: Updating information on =
frequency 2417 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533527] cfg80211: =
2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533528] cfg80211: =
Updating information on frequency 2422 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533530] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533531] =
cfg80211: Updating information on frequency 2427 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533533] cfg80211: 2402000 KHz - 2482000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533534] cfg80211: Updating information on =
frequency 2432 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533535] cfg80211: =
2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533537] cfg80211: =
Updating information on frequency 2437 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533538] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533539] =
cfg80211: Updating information on frequency 2442 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533541] cfg80211: 2402000 KHz - 2482000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533542] cfg80211: Updating information on =
frequency 2447 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533544] cfg80211: =
2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533545] cfg80211: =
Updating information on frequency 2452 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533546] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533547] =
cfg80211: Updating information on frequency 2457 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533549] cfg80211: 2402000 KHz - 2482000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533550] cfg80211: Updating information on =
frequency 2462 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533552] cfg80211: =
2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, 2000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533553] cfg80211: =
Updating information on frequency 2467 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533554] cfg80211: 2402000 KHz - 2482000 KHz @ 40000 KHz), (N/A mBi, =
2000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533556] =
cfg80211: Updating information on frequency 2472 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533557] cfg80211: 2402000 KHz - 2482000 =
KHz @ 40000 KHz), (N/A mBi, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533558] cfg80211: Disabling freq 2484 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533559] cfg80211: =
Updating information on frequency 5180 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533561] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, =
2300 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533562] =
cfg80211: Updating information on frequency 5200 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533564] cfg80211: 5170000 KHz - 5250000 =
KHz @ 40000 KHz), (300 mBi, 2300 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533565] cfg80211: Updating information on =
frequency 5220 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533566] cfg80211: =
5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2300 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533568] cfg80211: =
Updating information on frequency 5240 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533569] cfg80211: 5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, =
2300 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533570] =
cfg80211: Updating information on frequency 5260 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533572] cfg80211: 5250000 KHz - 5330000 =
KHz @ 40000 KHz), (300 mBi, 2300 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533573] cfg80211: Updating information on =
frequency 5280 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533575] cfg80211: =
5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, 2300 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533576] cfg80211: =
Updating information on frequency 5300 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533577] cfg80211: 5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, =
2300 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533579] =
cfg80211: Updating information on frequency 5320 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533580] cfg80211: 5250000 KHz - 5330000 =
KHz @ 40000 KHz), (300 mBi, 2300 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[ =A0=A0=A09.533581] cfg80211: Disabling freq 5500 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533582] cfg80211: =
Disabling freq 5520 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533583] cfg80211: Disabling freq 5540 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533584] cfg80211: Disabling freq 5560 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533585] cfg80211: =
Disabling freq 5580 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533585] cfg80211: Disabling freq 5600 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533586] cfg80211: Disabling freq 5620 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533587] cfg80211: =
Disabling freq 5640 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533588] cfg80211: Disabling freq 5660 MHz<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533589] cfg80211: Disabling freq 5680 =
MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533590] cfg80211: =
Disabling freq 5700 MHz<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533591] cfg80211: Updating information on frequency 5745 MHz for a 20 =
MHz width channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533592] cfg80211: 5735000 KHz - 5835000 =
KHz @ 40000 KHz), (300 mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533593] cfg80211: Updating information on =
frequency 5765 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533595] cfg80211: =
5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533596] cfg80211: =
Updating information on frequency 5785 MHz for a 20 MHz width channel =
with regulatory rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 =
9.533597] cfg80211: 5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, =
3000 mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533599] =
cfg80211: Updating information on frequency 5805 MHz for a 20 MHz width =
channel with regulatory rule:<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533600] cfg80211: 5735000 KHz - 5835000 =
KHz @ 40000 KHz), (300 mBi, 3000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533601] cfg80211: Updating information on =
frequency 5825 MHz for a 20 MHz width channel with regulatory =
rule:<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533603] cfg80211: =
5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 =
mBm)<o:p></o:p></p><p class=3DMsoNormal>[=A0=A0=A0 9.533606] cfg80211: =
Regulatory domain changed to country: AU<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533607] cfg80211:=A0=A0 (start_freq - =
end_freq @ bandwidth), (max_antenna_gain, max_eirp)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533608] cfg80211:=A0=A0 (2402000 KHz - =
2482000 KHz @ 40000 KHz), (N/A, 2000 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533609] cfg80211:=A0=A0 (5170000 KHz - =
5250000 KHz @ 40000 KHz), (300 mBi, 2300 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533611] cfg80211:=A0=A0 (5250000 KHz - =
5330000 KHz @ 40000 KHz), (300 mBi, 2300 mBm)<o:p></o:p></p><p =
class=3DMsoNormal>[=A0=A0=A0 9.533612] cfg80211:=A0=A0 (5735000 KHz - =
5835000 KHz @ 40000 KHz), (300 mBi, 3000 =
mBm)<o:p></o:p></p></div></body></html>
------=_NextPart_000_0CFF_01CD01BB.A7359070--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-03-20 18:28 John Szakmeister
  0 siblings, 0 replies; 409+ messages in thread
From: John Szakmeister @ 2012-03-20 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

We've been running into several issues on the cache flushing front,
and I'm hoping that someone here can help clarify what should be
happening from a kernel perspective.

Late last year we discovered a few interesting problems.  One of them
is definitely our fault: we weren't flushing the cache after we read
data from a block device a wrote it into the page.  However, there was
another issue we noticed that made less sense: we had to flush a page
before writing it to our block device, otherwise we end up writing
some stale data.  The brd device ran into this issue before, and fixed
it in commit c2572f2b[1].  In that commit Nick Pidgin says:
    "brd is missing a flush_dcache_page. On 2nd thoughts, perhaps it is the
     pagecache's responsibility to flush user virtual aliases (the driver of
     course should flush kernel virtual mappings)... but anyway, there
     already exists cache flushing for one direction of transfer, so we
     should add the other."

I can't help but to feel he's right.  It was very surprising to me
that I had to flush the user virtual aliases before writing the data
to the device.  Is it expected that we (as device driver writers) have
to do that for block device drivers?  I love Linux, but one of the
aspects I find most frustrating is that I don't know what I can safely
assume at interface boundaries.  Even modeling my work after existing
code yields problems, because a number of drivers in the tree seem to
be broken in this regard.

But it leads to another concern.  Since I do have to flush on writes,
it got me thinking about whether it's necessary to flush user mode
aliases before conducting a read.  Consider the fact that a page can
span multiple blocks.  Is it possible that:
  * we're asked to read a block of data
  * a user app has scribbled on the page (so it's dirty, but not flushed)
  * we read the requested data from the device
  * load it into the page
  * do a flush_dcache_page()
  * then the data read from the device becomes corrupt because cached user data
    is written to RAM?

Or, instead of that, the cached data gets dropped entirely because it
was on the page, but shouldn't have been because we didn't read new
data into that area, and now that user data is lost?  I confess this
may all be my lack of understanding about Linux's block i/o subsystem,
but I'm thoroughly confused at this point.  What I do know is that
other device drivers are not flushing the page before writing the data
to a device.  For instance, the mmc driver for the at91 architecture
suffers from this problem, and I've been able to see that problem
using mmap.  My concern is that many other drivers also suffer from
this problem, so I'm not sure what the fix needs to be: fix the page
cache, fix the driver, or both.

Also, is there somewhere that says what's guaranteed on entry into my
block device driver?  I've scoured everything I could find... the
Documentation area (including cachetlb.txt), Linux sites, books...
I've yet to find anything mentioning the need to call
flush_dcache_page() much less talk about what the assumptions are.

Thanks in advance for the help.

-John

[1]: <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=c2572f2b4ffc27ba79211aceee3bef53a59bb5cd>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-04-05  7:54 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-04-05  7:54 UTC (permalink / raw)
  To: ath9k-devel

relative to noise floor in dB."



Adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-04-05  7:54 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-04-05  7:54 UTC (permalink / raw)
  To: ath9k-devel

relative to noise floor in dB.&quot;<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
<br>
<br>
Adrian<br>
</font></span></blockquote></div><br></div>

--bcaec52be6d10f215404c0d1b26d--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-04-09 17:56 Martynov Semen
  2012-04-10  2:26 ` Vladimir Murzin
  0 siblings, 1 reply; 409+ messages in thread
From: Martynov Semen @ 2012-04-09 17:56 UTC (permalink / raw)
  To: kernelnewbies

Good afternoon,

I would like to understand, why I can't make the built-in object, when my code is in a folder /samples...

I have my module-code and if I put it in a folder /samples, I can receive only loadable module (.ko) but if I want to receive the built-in object - it turns out nothing (.?-file is created, but my code doesn't get in a kernel). When I allocate my module-code in any other folder (for example, /drivers) it works normally - I can receive .ko and I can make the built-in object.

Question - why I can't receive the built-in object when my code is in the folder /samples? What instruction in a make-file restricts it, and how?

P.S.: Sorry for my english.
-- 
Best regards,
Semen A Martynov.

Saint Petersburg, Russia.
https://www.facebook.com/semen.martynov

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2012-04-09 17:56 Martynov Semen
@ 2012-04-10  2:26 ` Vladimir Murzin
  2012-04-10  4:03   ` Martynov Semen
  2012-04-10  4:48   ` Martynov Semen
  0 siblings, 2 replies; 409+ messages in thread
From: Vladimir Murzin @ 2012-04-10  2:26 UTC (permalink / raw)
  To: kernelnewbies

Hi Semen

Could you share a Makefile for your module?

Best wishes,
Vladimir Murzin

-----Original Message-----
From: Martynov Semen <semen-martynov@yandex.ru>
Sender: kernelnewbies-bounces at kernelnewbies.org
Date: Mon, 09 Apr 2012 23:56:15 
To: kernelnewbies at kernelnewbies.org<kernelnewbies@kernelnewbies.org>
Subject: No subject

Good afternoon,

I would like to understand, why I can't make the built-in object, when my code is in a folder /samples...

I have my module-code and if I put it in a folder /samples, I can receive only loadable module (.ko) but if I want to receive the built-in object - it turns out nothing (.?-file is created, but my code doesn't get in a kernel). When I allocate my module-code in any other folder (for example, /drivers) it works normally - I can receive .ko and I can make the built-in object.

Question - why I can't receive the built-in object when my code is in the folder /samples? What instruction in a make-file restricts it, and how?

P.S.: Sorry for my english.
-- 
Best regards,
Semen A Martynov.

Saint Petersburg, Russia.
https://www.facebook.com/semen.martynov

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies at kernelnewbies.org
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2012-04-10  2:26 ` Vladimir Murzin
@ 2012-04-10  4:03   ` Martynov Semen
  2012-04-10  4:48   ` Martynov Semen
  1 sibling, 0 replies; 409+ messages in thread
From: Martynov Semen @ 2012-04-10  4:03 UTC (permalink / raw)
  To: kernelnewbies

An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20120410/f5f9ee0c/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2012-04-10  2:26 ` Vladimir Murzin
  2012-04-10  4:03   ` Martynov Semen
@ 2012-04-10  4:48   ` Martynov Semen
  2012-04-10 16:08     ` Vladimir Murzin
  1 sibling, 1 reply; 409+ messages in thread
From: Martynov Semen @ 2012-04-10  4:48 UTC (permalink / raw)
  To: kernelnewbies

<one more time in plain text>

Yes, of course.
It contains only one line:

obj-$(CONFIG_MY_PROCLISTOUTPUT) += proclistoutput.o

and works with Kconfig

config MY_PROCLISTOUTPUT
    tristate "Display a list of processes"
    default y
    ---help---
     This module prints a list of processes


But I'm sure that the reason is not in my file, because:
- If I put my code in a folder /drivers (and include my Makefile and Kconfig) then everything works perfectly (I can build kernel object and I can built-in my code to the kernel)
- If I put my code in a folder /samples (and include my Makefile and Kconfig) then build-in the code I can't, but with .ko it works fine...

I suppose that the reason in the kernel Makefile. The root Makefile contains this code (http://lxr.free-electrons.com/source/Makefile#L914)

ifdef CONFIG_SAMPLES
         $(Q)$(MAKE) $(build)=samples
endif

where
$(Q) = @
$(build) = -f scripts/Makefile.build obj

and further I lose understanding of the events...


10.04.2012, 08:26, "Vladimir Murzin" <murzin.v@gmail.com>:
> Hi Semen
>
> Could you share a Makefile for your module?
>
> Best wishes,
> Vladimir Murzin
>
> -----Original Message-----
> From: Martynov Semen <semen-martynov@yandex.ru>
> Sender: kernelnewbies-bounces at kernelnewbies.org
> Date: Mon, 09 Apr 2012 23:56:15
> To: kernelnewbies at kernelnewbies.org<kernelnewbies@kernelnewbies.org>
> Subject: No subject
>
> Good afternoon,
>
> I would like to understand, why I can't make the built-in object, when my code is in a folder /samples...
>
> I have my module-code and if I put it in a folder /samples, I can receive only loadable module (.ko) but if I want to receive the built-in object - it turns out nothing (.?-file is created, but my code doesn't get in a kernel). When I allocate my module-code in any other folder (for example, /drivers) it works normally - I can receive .ko and I can make the built-in object.
>
> Question - why I can't receive the built-in object when my code is in the folder /samples? What instruction in a make-file restricts it, and how?
>
> P.S.: Sorry for my english.
> --
> Best regards,
> Semen A Martynov.
>
> Saint Petersburg, Russia.
> https://www.facebook.com/semen.martynov
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- 


? ?? Facebook: http://www.facebook.com/profile.php?id=1095131825

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2012-04-10  4:48   ` Martynov Semen
@ 2012-04-10 16:08     ` Vladimir Murzin
  2012-04-10 17:00       ` Semen Martynov
  0 siblings, 1 reply; 409+ messages in thread
From: Vladimir Murzin @ 2012-04-10 16:08 UTC (permalink / raw)
  To: kernelnewbies

On Tue, Apr 10, 2012 at 10:48:14AM +0600, Martynov Semen wrote:
> <one more time in plain text>
> 
> Yes, of course.
> It contains only one line:
> 
> obj-$(CONFIG_MY_PROCLISTOUTPUT) += proclistoutput.o
> 
> and works with Kconfig
> 
> config MY_PROCLISTOUTPUT
>     tristate "Display a list of processes"
>     default y
>     ---help---
>      This module prints a list of processes
> 
> 
> But I'm sure that the reason is not in my file, because:
> - If I put my code in a folder /drivers (and include my Makefile and Kconfig) then everything works perfectly (I can build kernel object and I can built-in my code to the kernel)
> - If I put my code in a folder /samples (and include my Makefile and Kconfig) then build-in the code I can't, but with .ko it works fine...
> 
> I suppose that the reason in the kernel Makefile. The root Makefile contains this code (http://lxr.free-electrons.com/source/Makefile#L914)
> 
> ifdef CONFIG_SAMPLES
>          $(Q)$(MAKE) $(build)=samples
> endif
> 
> where
> $(Q) = @
> $(build) = -f scripts/Makefile.build obj
> 
> and further I lose understanding of the events...
> 
> 
> 10.04.2012, 08:26, "Vladimir Murzin" <murzin.v@gmail.com>:
> > Hi Semen
> >
> > Could you share a Makefile for your module?
> >
> > Best wishes,
> > Vladimir Murzin
> >
> > -----Original Message-----
> > From: Martynov Semen <semen-martynov@yandex.ru>
> > Sender: kernelnewbies-bounces at kernelnewbies.org
> > Date: Mon, 09 Apr 2012 23:56:15
> > To: kernelnewbies at kernelnewbies.org<kernelnewbies@kernelnewbies.org>
> > Subject: No subject
> >
> > Good afternoon,
> >
> > I would like to understand, why I can't make the built-in object, when my code is in a folder /samples...
> >
> > I have my module-code and if I put it in a folder /samples, I can receive only loadable module (.ko) but if I want to receive the built-in object - it turns out nothing (.?-file is created, but my code doesn't get in a kernel). When I allocate my module-code in any other folder (for example, /drivers) it works normally - I can receive .ko and I can make the built-in object.
> >
> > Question - why I can't receive the built-in object when my code is in the folder /samples? What instruction in a make-file restricts it, and how?
> >
> > P.S.: Sorry for my english.
> > --
> > Best regards,
> > Semen A Martynov.
> >
> > Saint Petersburg, Russia.
> > https://www.facebook.com/semen.martynov
> >
> > _______________________________________________
> > Kernelnewbies mailing list
> > Kernelnewbies at kernelnewbies.org
> > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
> -- 
> 
> 
> ? ?? Facebook: http://www.facebook.com/profile.php?id=1095131825

Hi Semen

It happens because ./script isn't listed as a subdir for visiting and
linking objects into vmlinux. Please, refer to [1] for details.

[1] http://lxr.linux.no/linux+*/Makefile#L508

Best wishes,
Vladimir Murzin

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2012-04-10 16:08     ` Vladimir Murzin
@ 2012-04-10 17:00       ` Semen Martynov
  0 siblings, 0 replies; 409+ messages in thread
From: Semen Martynov @ 2012-04-10 17:00 UTC (permalink / raw)
  To: kernelnewbies

Yes, this is it! Thank you!

10.04.2012, 20:08, "Vladimir Murzin" <murzin.v@gmail.com>:
> On Tue, Apr 10, 2012 at 10:48:14AM +0600, Martynov Semen wrote:
>
>> ?<one more time in plain text>
>>
>> ?Yes, of course.
>> ?It contains only one line:
>>
>> ?obj-$(CONFIG_MY_PROCLISTOUTPUT) += proclistoutput.o
>>
>> ?and works with Kconfig
>>
>> ?config MY_PROCLISTOUTPUT
>> ?????tristate "Display a list of processes"
>> ?????default y
>> ?????---help---
>> ??????This module prints a list of processes
>>
>> ?But I'm sure that the reason is not in my file, because:
>> ?- If I put my code in a folder /drivers (and include my Makefile and Kconfig) then everything works perfectly (I can build kernel object and I can built-in my code to the kernel)
>> ?- If I put my code in a folder /samples (and include my Makefile and Kconfig) then build-in the code I can't, but with .ko it works fine...
>>
>> ?I suppose that the reason in the kernel Makefile. The root Makefile contains this code (http://lxr.free-electrons.com/source/Makefile#L914)
>>
>> ?ifdef CONFIG_SAMPLES
>> ??????????$(Q)$(MAKE) $(build)=samples
>> ?endif
>>
>> ?where
>> ?$(Q) = @
>> ?$(build) = -f scripts/Makefile.build obj
>>
>> ?and further I lose understanding of the events...
>>
>> ?10.04.2012, 08:26, "Vladimir Murzin" <murzin.v@gmail.com>:
>>> ?Hi Semen
>>>
>>> ?Could you share a Makefile for your module?
>>>
>>> ?Best wishes,
>>> ?Vladimir Murzin
>>>
>>> ?-----Original Message-----
>>> ?From: Martynov Semen <semen-martynov@yandex.ru>
>>> ?Sender: kernelnewbies-bounces at kernelnewbies.org
>>> ?Date: Mon, 09 Apr 2012 23:56:15
>>> ?To: kernelnewbies at kernelnewbies.org<kernelnewbies@kernelnewbies.org>
>>> ?Subject: No subject
>>>
>>> ?Good afternoon,
>>>
>>> ?I would like to understand, why I can't make the built-in object, when my code is in a folder /samples...
>>>
>>> ?I have my module-code and if I put it in a folder /samples, I can receive only loadable module (.ko) but if I want to receive the built-in object - it turns out nothing (.?-file is created, but my code doesn't get in a kernel). When I allocate my module-code in any other folder (for example, /drivers) it works normally - I can receive .ko and I can make the built-in object.
>>>
>>> ?Question - why I can't receive the built-in object when my code is in the folder /samples? What instruction in a make-file restricts it, and how?
>>>
>>> ?P.S.: Sorry for my english.
>>> ?--
>>> ?Best regards,
>>> ?Semen A Martynov.
>>>
>>> ?Saint Petersburg, Russia.
>>> ?https://www.facebook.com/semen.martynov
>>>
>>> ?_______________________________________________
>>> ?Kernelnewbies mailing list
>>> ?Kernelnewbies at kernelnewbies.org
>>> ?http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>> ?--
>>
>> ?? ?? Facebook: http://www.facebook.com/profile.php?id=1095131825
>
> Hi Semen
>
> It happens because ./script isn't listed as a subdir for visiting and
> linking objects into vmlinux. Please, refer to [1] for details.
>
> [1] http://lxr.linux.no/linux+*/Makefile#L508
>
> Best wishes,
> Vladimir Murzin

-- 
Best regards,
Semen A Martynov.

Saint Petersburg, Russia.
https://www.facebook.com/semen.martynov

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-05-18 12:27 Sascha Hauer
  0 siblings, 0 replies; 409+ messages in thread
From: Sascha Hauer @ 2012-05-18 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

The following adds a drm/kms driver for the Freescale i.MX LCDC
controller. Most notable change to the last SDRM based version is that
the SDRM layer has been removed and the driver now is purely i.MX
specific. I hope that this is more acceptable now.

Another change is that the probe is now devicetree based. For now I
took the easy way out and only put an edid blob into the devicetree.
I haven't documented the binding yet, I would add that when the rest
is considered ok.

Comments very welcome.

Thanks
 Sascha

----------------------------------------------------------------
Sascha Hauer (2):
      DRM: add Freescale i.MX LCDC driver
      pcm038 lcdc support

 arch/arm/boot/dts/imx27-phytec-phycore.dts |   39 ++
 arch/arm/boot/dts/imx27.dtsi               |    7 +
 arch/arm/mach-imx/clock-imx27.c            |    1 +
 drivers/gpu/drm/Kconfig                    |    2 +
 drivers/gpu/drm/Makefile                   |    1 +
 drivers/gpu/drm/imx/Kconfig                |   18 +
 drivers/gpu/drm/imx/Makefile               |    8 +
 drivers/gpu/drm/imx/imx-drm-core.c         |  745 ++++++++++++++++++++++++++++
 drivers/gpu/drm/imx/imx-fb.c               |  179 +++++++
 drivers/gpu/drm/imx/imx-fbdev.c            |  275 ++++++++++
 drivers/gpu/drm/imx/imx-gem.c              |  343 +++++++++++++
 drivers/gpu/drm/imx/imx-lcdc-crtc.c        |  517 +++++++++++++++++++
 drivers/gpu/drm/imx/imx-parallel-display.c |  228 +++++++++
 13 files changed, 2363 insertions(+)
 create mode 100644 drivers/gpu/drm/imx/Kconfig
 create mode 100644 drivers/gpu/drm/imx/Makefile
 create mode 100644 drivers/gpu/drm/imx/imx-drm-core.c
 create mode 100644 drivers/gpu/drm/imx/imx-fb.c
 create mode 100644 drivers/gpu/drm/imx/imx-fbdev.c
 create mode 100644 drivers/gpu/drm/imx/imx-gem.c
 create mode 100644 drivers/gpu/drm/imx/imx-lcdc-crtc.c
 create mode 100644 drivers/gpu/drm/imx/imx-parallel-display.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-05-25 15:26 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-05-25 15:26 UTC (permalink / raw)
  To: ath9k-devel

"enabled" in the device driver. I will scour  the ath9k source code for
this config.

=20

Thank you for your input.

=20

Hasan R.

=20

=20

From: adrian.chadd@gmail.com [mailto:adrian.chadd at gmail.com] On Behalf
Of Adrian Chadd
Sent: Sunday, May 27, 2012 7:18 PM
To: Hasan Rashid
Cc: ath9k-devel at lists.ath9k.org
Subject: Re: [ath9k-devel] Atheros AR9382 W_DISABLE_L PIN 20 Mini-PCIe

=20

Hi,

=20

So the 30 second version of rfkill is this:

=20

* it can be software driven (ie, the driver implements rfkill by
stopping TX/RX and baseband activity, possibly shutting down the NIC)

* it can be hardware driven (ie, there's an RFKill line to the NIC via=
 a
GPIO pin)

=20

The pin itself can be controlled by:

=20

* hardware - ie, a physical switch to the rfkill pin;

* software - ie, some ACPI controlled function maps to the rfkill pin.

=20

What you have above seems to be (2) and (1) respectively - ie, that pin
is mapped to GPIO7 on the NIC, and now you need to program GPIO7 to be
an RFkill pin. There's code in ath9k somewhere to configure the GPIO pin
correctly to implement hardware rfkill.

=20

Good luck!

=20

=20

Adrian


This communication contains information that may be confidential or priv=
ileged. The information is solely intended for the use of the addressee.=
 If you are not the intended recipient, be advised that any disclosure,=
 copy, distribution, or use of the contents of this communication is pro=
hibited. If you have received this communication in
error, please immediately notify the sender by telephone or by electroni=
c mail.
------_=_NextPart_001_01CD3DB5.D3C19EF1
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-m=
icrosoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:=
word" xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=
=3D"http://www.w3.org/TR/REC-html40"><head><meta http-equiv=3DContent-Ty=
pe content=3D"text/html; charset=3Dus-ascii"><meta name=3DGenerator cont=
ent=3D"Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:Tahoma;
	panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:purple;
	text-decoration:underline;}
span.EmailStyle17
	{mso-style-type:personal-reply;
	font-family:"Calibri","sans-serif";
	color:#1F497D;}
.MsoChpDefault
	{mso-style-type:export-only;
	font-family:"Calibri","sans-serif";}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3Dblue=
 vlink=3Dpurple><div class=3DWordSection1><p class=3DMsoNormal><span sty=
le=3D'font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'=
From your email I gather I have a RFKILL switch but it needs to be &#82=
20;enabled&#8221; in the device driver. I will scour &nbsp;the ath9k sou=
rce code for this config.<o:p></o:p></span></p><p class=3DMsoNormal><spa=
n style=3D'font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F=
497D'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span style=3D'fo=
nt-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Thank=
 you for your input.<o:p></o:p></span></p><p class=3DMsoNormal><span sty=
le=3D'font-size:10.0pt;font-family:"Arial","sans-serif";color:#1F497D'><=
o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span style=3D'font-size=
:10.0pt;font-family:"Arial","sans-serif";color:#1F497D'>Hasan R.<o:p></o=
:p></span></p><p class=3DMsoNormal><span style=3D'font-size:10.0pt;font-=
family:"Arial","sans-serif";color:#1F497D'>&nbsp;<o:p></o:p></span></p><=
p class=3DMsoNormal><span style=3D'font-size:10.0pt;font-family:"Arial",=
"sans-serif";color:#1F497D'>&nbsp;</span><span style=3D'font-size:11.0pt=
;font-family:"Calibri","sans-serif";color:#1F497D'><o:p></o:p></span></p=
><p class=3DMsoNormal style=3D'margin-left:.5in'><b><span style=3D'font-=
size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span sty=
le=3D'font-size:10.0pt;font-family:"Tahoma","sans-serif"'> adrian.chadd@=
gmail.com [mailto:adrian.chadd at gmail.com] <b>On Behalf Of </b>Adrian Cha=
dd<br><b>Sent:</b> Sunday, May 27, 2012 7:18 PM<br><b>To:</b> Hasan Rash=
id<br><b>Cc:</b> ath9k-devel at lists.ath9k.org<br><b>Subject:</b> Re: [ath=
9k-devel] Atheros AR9382 W_DISABLE_L PIN 20 Mini-PCIe<o:p></o:p></span><=
/p><p class=3DMsoNormal style=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p>=
<p class=3DMsoNormal style=3D'margin-left:.5in'>Hi,<o:p></o:p></p><div><=
p class=3DMsoNormal style=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p></di=
v><div><p class=3DMsoNormal style=3D'margin-left:.5in'>So the 30 second=
 version of rfkill is this:<o:p></o:p></p></div><div><p class=3DMsoNorma=
l style=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p></div><div><p class=3D=
MsoNormal style=3D'margin-left:.5in'>* it can be software driven (ie,=
 the driver implements rfkill by stopping TX/RX and baseband activity,=
 possibly shutting down the NIC)<o:p></o:p></p></div><div><p class=3DMso=
Normal style=3D'margin-left:.5in'>* it can be hardware driven (ie, there=
's an RFKill line to the NIC via a GPIO pin)<o:p></o:p></p></div><div><p=
 class=3DMsoNormal style=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p></div=
><div><p class=3DMsoNormal style=3D'margin-left:.5in'>The pin itself can=
 be controlled by:<o:p></o:p></p></div><div><p class=3DMsoNormal style=
=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNorm=
al style=3D'margin-left:.5in'>* hardware - ie, a physical switch to the=
 rfkill pin;<o:p></o:p></p></div><div><p class=3DMsoNormal style=3D'marg=
in-left:.5in'>* software - ie, some ACPI controlled function maps to the=
 rfkill pin.<o:p></o:p></p></div><div><p class=3DMsoNormal style=3D'marg=
in-left:.5in'><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal style=
=3D'margin-left:.5in'>What you have above seems to be (2) and (1) respec=
tively - ie, that pin is mapped to GPIO7 on the NIC, and now you need=
 to program GPIO7 to be an RFkill pin. There's code in ath9k somewhere=
 to configure the GPIO pin correctly to implement hardware rfkill.<o:p><=
/o:p></p></div><div><p class=3DMsoNormal style=3D'margin-left:.5in'><o:p=
>&nbsp;</o:p></p></div><div><p class=3DMsoNormal style=3D'margin-left:.5=
in'>Good luck!<o:p></o:p></p></div><div><p class=3DMsoNormal style=3D'ma=
rgin-left:.5in'><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal sty=
le=3D'margin-left:.5in'><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNo=
rmal style=3D'margin-left:.5in'>Adrian<o:p></o:p></p></div></div>
<!-- Begin Ninja Disclaimer ID 06d1f63c-a7f2-4bdd-9832-359e6e93159e -->
<P>This communication contains information that may be confidential or=
 privileged. The information is solely intended for the use of the addre=
ssee. If you are not the intended recipient, be advised that any disclos=
ure, copy, distribution, or use of the contents of this communication=
 is prohibited. If you have received this communication in<BR>error, ple=
ase immediately notify the sender by telephone or by electronic mail.</P>
<P>Export Notice: This email may contain technical data controlled under=
 the&nbsp; International Traffic in Arms Regulations (ITAR) by the U.S.=
 Department of State (22 CFR 120-130) or under the U.S Export Administra=
tion Regulations (EAR) by the Department of Commerce (15 CFR 730-744).&n=
bsp; Violations of these export laws are subject to severe criminal pena=
lties.&nbsp; <BR></P>
</body></html>
------_=_NextPart_001_01CD3DB5.D3C19EF1--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-05-25 15:26 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-05-25 15:26 UTC (permalink / raw)
  To: ath9k-devel

it being NULL along the way"
I guess you refer to the comment in mac80211.h, struct tx_info that I
removed:
- * The TX control's sta pointer is only valid during the ->tx call,
- * it may be NULL.

I am not sure what you want me to keep here as comment. As the sta
pointer is moved into the new struct tx_control and the remaining
pointers in the tx_info->control structure (vif, hw_key) are ALL only
valid during the ->tx call and may be NULL. So I could think of adding a
comment to tx_control about the sta been NULL, but anything more ?


>> The tx-path of all affected drivers is restructured to respect the
chaneged
>> layout of struct ieee80211_tx_info. List of modified drivers:
>> ath9k
>
> Please also remove the driver list. git can tell you the modified files
> very easily.

Will do so in v2.

Greetings Thomas

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-06-06 10:33 Sascha Hauer
  0 siblings, 0 replies; 409+ messages in thread
From: Sascha Hauer @ 2012-06-06 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

The following adds i.MX53 nand support and generally devicetree
based probing for i.MX5 boards. The first three patches should go
via mtd, the last patch optionally aswell if all agree.

Sascha

The following changes since commit f8f5701bdaf9134b1f90e5044a82c66324d2073f:

  Linux 3.5-rc1 (2012-06-02 18:29:26 -0700)

are available in the git repository at:

  git://git.pengutronix.de/git/imx/linux-2.6.git imx/nand-mx53

for you to fetch changes up to d55d1479a3bfaedbb9f0c6c956f4dff6bb6d6d61:

  ARM i.MX5: Add nand oftree support (2012-06-06 12:20:24 +0200)

----------------------------------------------------------------
Sascha Hauer (4):
      mtd nand mxc_nand: Use managed resources
      mtd nand mxc_nand: swap iomem resource order
      mtd nand mxc_nand: add i.MX53 support
      ARM i.MX5: Add nand oftree support

 arch/arm/boot/dts/imx51.dtsi                  |    7 ++
 arch/arm/boot/dts/imx53.dtsi                  |    7 ++
 arch/arm/mach-imx/clk-imx51-imx53.c           |    2 +
 arch/arm/plat-mxc/devices/platform-mxc_nand.c |   11 +-
 drivers/mtd/nand/mxc_nand.c                   |  137 ++++++++++++++-----------
 5 files changed, 97 insertions(+), 67 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-06-21 18:26 Paul Walmsley
  0 siblings, 0 replies; 409+ messages in thread
From: Paul Walmsley @ 2012-06-21 18:26 UTC (permalink / raw)
  To: linux-arm-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Tony

The following changes since commit 485802a6c524e62b5924849dd727ddbb1497cc71:

  Linux 3.5-rc3 (2012-06-16 17:25:17 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending.git tags/omap-cleanup-a-for-3.6

for you to fetch changes up to 07b3a13957aa250ff5b5409b8ed756b113544112:

  Merge branches 'clock_cleanup_misc_3.6', 'control_clean_dspbridge_writes_cleanup_3.6', 'hwmod_soc_conditional_cleanup_3.6', 'mcbsp_clock_aliases_cleanup_3.6' and 'remove_clkdm_requirement_from_hwmod_3.6' into omap_cleanup_a_3.6 (2012-06-20 20:11:36 -0600)

- ----------------------------------------------------------------

Some OMAP hwmod, clock, and System Control Module cleanup patches for 3.6.

- ----------------------------------------------------------------

Testing logs are available at

http://www.pwsan.com/omap/bootlogs/20120620/omap_cleanup_a_3.6__07b3a13957aa250ff5b5409b8ed756b113544112/

The summary is that 5912OSK NFS root and N800 MMC don't boot to
userspace; this broke between v3.4-rc2 and v3.5-rc3.  3517 boards are
still broken with NFS root and also several stack tracebacks during
boot.  In terms of PM, core isn't entering idle on OMAP3 or OMAP4.
These problems all exist in v3.5-rc3 - they aren't caused by this
series.

object size (delta in bytes from v3.5-rc3 (485802a6c524e62b5924849dd727ddbb1497cc71)):
  text 	  data 	   bss 	 total 	kernel
     0 	     0 	     0 	     0 	5912osk_testconfig/vmlinux
 +4636 	  -400 	     0 	 +4236 	am33xx_testconfig/vmlinux
  +440 	  -408 	   +32 	   +64 	n800_multi_omap2xxx/vmlinux
  +416 	  -192 	   +32 	  +256 	n800_testconfig/vmlinux
     0 	     0 	     0 	     0 	omap1510_defconfig/vmlinux
     0 	     0 	     0 	     0 	omap1_defconfig/vmlinux
  +732 	  -456 	     0 	  +276 	omap2_4_testconfig/vmlinux
 +4776 	  -624 	     0 	 +4152 	omap2plus_defconfig/vmlinux
  +684 	  -664 	     0 	   +20 	omap2plus_no_pm/vmlinux
  +616 	  -336 	   +64 	  +344 	omap3_4_testconfig/vmlinux
  +360 	  -384 	     0 	   -24 	omap3_testconfig/vmlinux
  +580 	  -120 	   +64 	  +524 	omap4_testconfig/vmlinux


Kevin Hilman (7):
      ARM: OMAP4: hwmod: rename _enable_module to _omap4_enable_module()
      ARM: OMAP2+: hwmod: use init-time function ptrs for enable/disable module
      ARM: OMAP4: hwmod: drop extra cpu_is check from _wait_target_disable()
      ARM: OMAP2+: hwmod: use init-time function pointer for wait_target_ready
      ARM: OMAP2+: hwmod: use init-time function pointer for hardreset
      ARM: OMAP2+: hwmod: use init-time function pointer for _init_clkdm
      ARM: OMAP2+: CLEANUP: Remove ARCH_OMAPx ifdef from struct dpll_data

Omar Ramirez Luna (2):
      ARM: OMAP2+: control: new APIs to configure boot address and mode
      ARM: OMAP: dsp: interface to control module functions

Paul Walmsley (2):
      ARM: OMAP2+: hwmod: remove prm_clkdm, cm_clkdm; allow hwmods to have no clockdomain
      Merge branches 'clock_cleanup_misc_3.6', 'control_clean_dspbridge_writes_cleanup_3.6', 'hwmod_soc_conditional_cleanup_3.6', 'mcbsp_clock_aliases_cleanup_3.6' and 'remove_clkdm_requirement_from_hwmod_3.6' into omap_cleanup_a_3.6

Peter Ujfalusi (3):
      ARM: OMAP2: Move McBSP fck clock alias to hwmod data for OMAP2420
      ARM: OMAP2: Move McBSP fck clock alias to hwmod data for OMAP2430
      ARM: OMAP3: Move McBSP fck clock alias to hwmod data

 arch/arm/mach-omap2/Makefile                       |    1 -
 arch/arm/mach-omap2/clock2420_data.c               |    4 -
 arch/arm/mach-omap2/clock2430_data.c               |   10 -
 arch/arm/mach-omap2/clock3xxx_data.c               |   10 -
 arch/arm/mach-omap2/clockdomain.h                  |    2 -
 arch/arm/mach-omap2/clockdomains2420_data.c        |    2 -
 arch/arm/mach-omap2/clockdomains2430_data.c        |    2 -
 arch/arm/mach-omap2/clockdomains3xxx_data.c        |    2 -
 arch/arm/mach-omap2/clockdomains44xx_data.c        |    2 -
 arch/arm/mach-omap2/clockdomains_common_data.c     |   24 --
 arch/arm/mach-omap2/control.c                      |   43 ++
 arch/arm/mach-omap2/control.h                      |    2 +
 arch/arm/mach-omap2/dsp.c                          |    4 +
 .../include/mach/ctrl_module_core_44xx.h           |    1 +
 arch/arm/mach-omap2/omap_hwmod.c                   |  427 ++++++++++++++------
 arch/arm/mach-omap2/omap_hwmod_2420_data.c         |   10 +
 arch/arm/mach-omap2/omap_hwmod_2430_data.c         |   16 +
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |   23 ++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c         |    4 +-
 arch/arm/plat-omap/include/plat/clock.h            |    2 -
 arch/arm/plat-omap/include/plat/dsp.h              |    3 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h       |    2 +
 22 files changed, 409 insertions(+), 187 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/clockdomains_common_data.c
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iQIcBAEBAgAGBQJP42cFAAoJEMePsQ0LvSpLmMAP/06LRRSFBPklr2hDmFPKBfBD
guF3rAN5zimEyknXp1RhoHJjcH0YCkUdQgD24w51yVwVB9zVW0M6G9hVi91cJj9X
1StRIwTbtb08yPdOlpywEXzHpjXz3AauCMRRxYJHi0FjajwHNKWWv+A/iolM0p8P
5o5ZY+D3AzJqfX/+A0FK2YKn2Z7X9kxg8uTTukhXhe38ldZJ2pHqA4ND2n2F+GnD
DUGqpnYu+QLTmw0x0NbpTNDarnmUEa/tH1NRny5Fh+ujYxH5NPTVvxHTW8tbm5bl
qkleWJaDc+D2pCnD3ch3cUlLgIfTZbo4KUg+Y4uv4QLrLx/QTu6TpyJaP+ZJw3sY
amakgmv3vzYzHMOf/0gxIe6xDZl6YFVXiOdJex4kQ5qodXRgmh82gYUrEKLLHuWn
+EKwIBM8xV5zYzA60vZ05ul7QqeNfwD5D6dd5As96QweVJFMGiIDWINGfxOtI/mH
ygXD6sSZvYhqGk2EVb+hje971urmI4aIrolt/xB4anOATiehaJuwhLjtp+5ZO7tL
5w3bybiUqKh+CN0DlpL/Srw0jaVp/pjZE8+4tzw/Mvm5T8wSVZL2ysJfmX4WffKl
k7RI46jiiQfFLJbSF5pgXUEm00/Ut3g7otp2F+iZLuAplJwoojl7cgezTSAgRc9E
Rhv07SsL5AAZ5OyCOdeQ
=rQK5
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-07-30 19:04 siddhesh phadke
  0 siblings, 0 replies; 409+ messages in thread
From: siddhesh phadke @ 2012-07-30 19:04 UTC (permalink / raw)
  To: kernelnewbies

I am newbie in nested KVM virtualization and I am trying to understand
the code for nested virtualization. I am not able to understand how
nested guest's ioctl calls are intercepted by KVM.Does each ioctl of
nested guest is intercepted by L0 or it is passed to L1?

Can anyone please help me with this or correct me if I am totally off the track?

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-08-06 10:43 =?gb18030?B?wObC5A==?=
  0 siblings, 0 replies; 409+ messages in thread
From: =?gb18030?B?wObC5A==?= @ 2012-08-06 10:43 UTC (permalink / raw)
  To: kernelnewbies

hello   i  want  to  sabrit  the  mailist
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20120806/8156c302/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-08-13 10:09 Vivek Panwar
  0 siblings, 0 replies; 409+ messages in thread
From: Vivek Panwar @ 2012-08-13 10:09 UTC (permalink / raw)
  To: kernelnewbies

HI,

How KGDB works internally or how a gdb stub works internally with source
code for x86_64 arch. Can some one please suggest me the good docs for the
same.I am very new to this so want know whole detailed internally working
procedure for KGDB.

Thanks
Vivek
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20120813/60e980ea/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-08-27  6:40 Simon Horman
  0 siblings, 0 replies; 409+ messages in thread
From: Simon Horman @ 2012-08-27  6:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd, Hi Olaf,

please consider the following enhancements for the Armadillo800EVA board
from Laurent Pinchart for inclusion in 3.7.

I am currently in the processes of taking over maintenance
of shmoble from Rafael Wysocki and this my the first pull request
in that role.

----------------------------------------------------------------
The following changes since commit fea7a08acb13524b47711625eebea40a0ede69a0:

  Linux 3.6-rc3 (2012-08-22 13:29:06 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git armadillo800eva

for you to fetch changes up to 5c1d2d16772e2d7d4e2e8da99a92d6f50b9102f0:

  ARM: mach-shmobile: armadillo800eva: Enable power button as wakeup source (2012-08-25 15:44:53 +0900)

----------------------------------------------------------------
Laurent Pinchart (2):
      ARM: mach-shmobile: armadillo800eva: Fix GPIO buttons descriptions
      ARM: mach-shmobile: armadillo800eva: Enable power button as wakeup source

 arch/arm/mach-shmobile/board-armadillo800eva.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-10-14 10:05 Alexey Dobriyan
  0 siblings, 0 replies; 409+ messages in thread
From: Alexey Dobriyan @ 2012-10-14 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

  http://www.hzsonic.com/en/wp-content/themes/twentyten/career.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-10-15  9:24 Niroj Pokhrel
  0 siblings, 0 replies; 409+ messages in thread
From: Niroj Pokhrel @ 2012-10-15  9:24 UTC (permalink / raw)
  To: kernelnewbies

Hi,
I'm new to linux and kernel . I'm ongoing with the linux device drivers.
I've followed the the book LDD but i'm lost about how to call my driver's
specific method from the user space.
Eg: if have developed a character device and inserted the module then how
can i make sure that when I read or write that it implement the functions
via the methods i have implemented in my module.

-- 
Niroj Pokhrel
NIT Jamshedpur,
B.Tech,Electronics and Communication
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20121015/5d90dec4/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-11-02 10:46 Pritam Bankar
  0 siblings, 0 replies; 409+ messages in thread
From: Pritam Bankar @ 2012-11-02 10:46 UTC (permalink / raw)
  To: kernelnewbies

Hi,
I know very well that memory on 32-bit Linux system is normally split
in following way

First 3GB = user space (High memory)
Last 1GB = kernel space (Low memory)

But I have some questions,

1. How is memory split up on 64-bit architecture
2. Can we override this 3:1 split ?
3. If yes, who can do that user or kernel?

Thanks,
Pritam Bankar

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-11-08  8:07 Abhimanyu Kapur
  0 siblings, 0 replies; 409+ messages in thread
From: Abhimanyu Kapur @ 2012-11-08  8:07 UTC (permalink / raw)
  To: linux-arm-kernel

subscribe  		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121108/ea49c32b/attachment-0001.html>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-11-08  9:33 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2012-11-08  9:33 UTC (permalink / raw)
  To: ath9k-devel

timestamp (first frame?).

Thomas

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-11-11 14:16 Sammy Chan
  0 siblings, 0 replies; 409+ messages in thread
From: Sammy Chan @ 2012-11-11 14:16 UTC (permalink / raw)
  To: linux-arm-kernel

  http://ncompass1.altervista.org/wp-content/plugins/zgstplauaao/ugoogle.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-11-19 11:41 唐忠诚
  0 siblings, 0 replies; 409+ messages in thread
From: 唐忠诚 @ 2012-11-19 11:41 UTC (permalink / raw)
  To: kernelnewbies

thanks
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20121119/5b84e70c/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-12-05 13:48 Niroj Pokhrel
  0 siblings, 0 replies; 409+ messages in thread
From: Niroj Pokhrel @ 2012-12-05 13:48 UTC (permalink / raw)
  To: kernelnewbies

Hi,
I'm trying to work on android audio (pcm_native.c) but got stuck in some
parameters like start threshold, stop threshold, silence zone, silence
threshold. Can anybody please elaborate on what they are each used for ??

-- 
Niroj Pokhrel
Software Engineer,
Samsung India Software Operations
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20121205/9b5d1739/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2012-12-29  9:17 steve.zhan
  0 siblings, 0 replies; 409+ messages in thread
From: steve.zhan @ 2012-12-29  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

    It is good idea add this feature.

1: Can we let the "ret = hwspin_lock_tests(ops, hwlock);" add after
hwspin_lock_register_single have return
succeed, that can avoid test duplicated Or error lockid. Of course, If
this interface is intend to test soc hardware capability only, we can
put it in the arch module not this core framework. For driver hardware
sanity check, i would add it after software have register it.


2:Is it possible that interface add configs that choose which locks
will be test? Because the hwspinlock module is init late in
postcore_initcall phase, Maybe MACH/ARCH code(for example: code in
early_initcall) need use private other interfaces to lock some
hwspinlocks and then register hw locks to hwspinlock framework, Maybe
some hw locks is in lock status but which test failed.




-- 
Steve Zhan


> From: Ido Yariv <ido@wizery.com>
> To: Ohad Ben-Cohen <ohad@wizery.com>, linux-kernel at vger.kernel.org,
> 	linux-arm-kernel at lists.infradead.org, linux-omap at vger.kernel.org
> Cc: Ido Yariv <ido@wizery.com>
> Subject: [PATCH] hwspinlock/core: Add testing capabilities
> Message-ID: <1355344026-17222-1-git-send-email-ido@wizery.com>
>
> Add testing capabilities for verifying correctness of the underlying
> hwspinlock layers. This can be handy especially during development.
> These tests are performed only once as part of the hwspinlock
> registration.
>
> Signed-off-by: Ido Yariv <ido@wizery.com>
> ---
>  drivers/hwspinlock/Kconfig           |    9 +++++
>  drivers/hwspinlock/hwspinlock_core.c |   54
> ++++++++++++++++++++++++++++++++++
>  2 files changed, 63 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
> index c7c3128..ad632cd 100644
> --- a/drivers/hwspinlock/Kconfig
> +++ b/drivers/hwspinlock/Kconfig
> @@ -8,6 +8,15 @@ config HWSPINLOCK
>
>  menu "Hardware Spinlock drivers"
>
> +config HWSPINLOCK_TEST
> +	bool "Verify underlying hwspinlock implementation"
> +	depends on HWSPINLOCK
> +	help
> +	  Say Y here to perform tests on the underlying hwspinlock
> +	  implementation. The tests are only performed once per implementation.
> +
> +	  Say N, unless you absolutely know what you are doing.
> +
>  config HWSPINLOCK_OMAP
>  	tristate "OMAP Hardware Spinlock device"
>  	depends on ARCH_OMAP4
> diff --git a/drivers/hwspinlock/hwspinlock_core.c
> b/drivers/hwspinlock/hwspinlock_core.c
> index 085e28e..1874e85 100644
> --- a/drivers/hwspinlock/hwspinlock_core.c
> +++ b/drivers/hwspinlock/hwspinlock_core.c
> @@ -307,6 +307,53 @@ out:
>  	return hwlock;
>  }
>
> +#ifdef CONFIG_HWSPINLOCK_TEST
> +#define NUM_OF_TEST_ITERATIONS 100
> +static int hwspin_lock_tests(const struct hwspinlock_ops *ops,
> +			     struct hwspinlock *hwlock)
> +{
> +	int i;
> +	int ret;
> +
> +	for (i = 0; i < NUM_OF_TEST_ITERATIONS; i++) {
> +		ret = ops->trylock(hwlock);
> +		if (!ret) {
> +			pr_err("%s: Initial lock failed\n", __func__);
> +			return -EFAULT;
> +		}
> +
> +		/* Verify lock actually works - re-acquiring it should fail */
> +		ret = ops->trylock(hwlock);
> +		if (ret) {
> +			/* Keep locks balanced even in failure cases */
> +			ops->unlock(hwlock);
> +			ops->unlock(hwlock);
> +			pr_err("%s: Recursive lock succeeded unexpectedly\n",
> +			       __func__);
> +			return -EFAULT;
> +		}
> +
> +		/* Verify unlock by re-acquiring the lock after releasing it */
> +		ops->unlock(hwlock);
> +		ret = ops->trylock(hwlock);
> +		if (!ret) {
> +			pr_err("%s: Unlock failed\n", __func__);
> +			return -EINVAL;
> +		}
> +
> +		ops->unlock(hwlock);
> +	}
> +
> +	return 0;
> +}
> +#else /* CONFIG_HWSPINLOCK_TEST*/
> +static int hwspin_lock_tests(const struct hwspinlock_ops *ops,
> +			     struct hwspinlock *hwlock)
> +{
> +	return 0;
> +}
> +#endif
> +
>  /**
>   * hwspin_lock_register() - register a new hw spinlock device
>   * @bank: the hwspinlock device, which usually provides numerous hw locks
> @@ -345,6 +392,13 @@ int hwspin_lock_register(struct hwspinlock_device
> *bank, struct device *dev,
>  		spin_lock_init(&hwlock->lock);
>  		hwlock->bank = bank;
>
> +		ret = hwspin_lock_tests(ops, hwlock);
> +		if (ret) {
> +			pr_err("hwspinlock tests failed on lock %d\n",
> +			       base_id + i);
> +			goto reg_failed;
> +		}
> +
>  		ret = hwspin_lock_register_single(hwlock, base_id + i);
>  		if (ret)
>  			goto reg_failed;
> --
> 1.7.7.6

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-01-16 21:46 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-01-16 21:46 UTC (permalink / raw)
  To: ath9k-devel

driver isn't doing something stupid like running multiple copies of
the reset / setup path on different CPUs/threads, it should be
reliable.

HTH,



Adrian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-01-16 21:46 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-01-16 21:46 UTC (permalink / raw)
  To: ath9k-devel

limitation in that it must not be reset more than once. That seems
like not so reliable PCIe IP, as long as the issue really is well
understood, but I'm not sure?

I would really like to hear the exact details about what the hardware
requires.


//Peter

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-02-06 22:30 Jimmy Pan
  0 siblings, 0 replies; 409+ messages in thread
From: Jimmy Pan @ 2013-02-06 22:30 UTC (permalink / raw)
  To: kernelnewbies

unsuscribe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130207/884e7ffe/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-02-15  5:48 Kaushal Billore
  0 siblings, 0 replies; 409+ messages in thread
From: Kaushal Billore @ 2013-02-15  5:48 UTC (permalink / raw)
  To: kernelnewbies

I have some doubt regarding Linux kernel V4l2 API's.
When capture application calls Reqbuff ioctl to allocate n no of buffer which would belongs to v4l2 layer and display application calls the Reqbuff ioctl to allocate N no of buffer which would also belongs to device memory.

Question:
1. V4l2 maintains the generic layer for all devices in which buffers can be allocated by any device and can be handle by any device?

2. If not then while capturing the data from capture device can capture device allocated buffer gets filled and while displaying the same data  there memory copy happens between capture buffer and output buffers?

3. If not then I want to capture data from capture device and display onto display device through the v4l2 framework layer. 
   
Awaiting for responce!

Thanks in advance 
Kaushal 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130215/f203090c/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-02-25  7:24 Prasad Lakshman
  0 siblings, 0 replies; 409+ messages in thread
From: Prasad Lakshman @ 2013-02-25  7:24 UTC (permalink / raw)
  To: kernelnewbies

Hi ,
I am trying to implement own system call in Linux. Kernel version I
chose is 3.5.7

I am following the steps from Linux Kernel Development 3rd edition.
I got two problems with the implementation.
1.while trying to modify the code in kernel , there is no entry.S file
for Intel x86 32 bit architecture. (my be i am missing some thing.)
2.while I am compiling user application with gcc I am getting

error: unknown type name ?helloworld?

my application is as follows

#define __NR_helloworld 367
__syscall0(long, helloworld)

int main ()
{
printf("The helloworld system call is\n";
helloworld();
return 0;
}


I looked at Link [blog.163.com] which is given by Wanny but i could
not find the solution,I could not locate syscall_table_32.s in my
Linux source.

Please  help me in identifying the entry.S file for Intel x86 32 bit
architecture in 3.5.7 kernel version sources,where i can make an entry
for my system call into system call table.

Help me in resolving  error: unknown type name ?helloworld? in my application.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-03 10:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-04-03 10:31 UTC (permalink / raw)
  To: ath9k-devel

monitor mode (non promiscuous) are corrupted. They
have the QoS Control stripped, with LLC header
finding itself in the QoS Control. Wireshark shows
such packets as A-MSDU corrupted frames. I tried
restoring the QoS Control but it didn't fix that.

I think we'll need to make a copy of skb, work on
that copy and keep the original skbuff pointer as
a "cookie" to use with mac80211 functions
(tx_status, free_txskb). I'm hoping this won't
degrade tx performance (well, we already do a
memmove()).

Yuck. Any comments?


Michal Kazior (2):
  ath10k: make more space in ath10k_skb_cb
  ath10k: copy skb during tx

 drivers/net/wireless/ath/ath10k/core.h |   32 ++++++++++++++++++++------------
 drivers/net/wireless/ath/ath10k/mac.c  |   21 +++++++++++++++++++--
 drivers/net/wireless/ath/ath10k/txrx.c |    8 +++++---
 3 files changed, 44 insertions(+), 17 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-03 10:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-04-03 10:31 UTC (permalink / raw)
  To: ath9k-devel

priority feature. For me most important is to support the real monitor
mode (iw wlan0 set type monitor), anything else is just nice to have.

I haven't even looked at your patches, but I'm worried that if a very
low priority feature jeopardizes normal functionality. What if we just
don't support the monitor mode while associated feature? Can we do that?

Disclaimer: I haven't looked at your patches

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-03 10:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-04-03 10:31 UTC (permalink / raw)
  To: ath9k-devel

Bartosz

On 9 May 2013 12:33, Kalle Valo <kvalo@qca.qualcomm.com> wrote:

> Bartosz Markowski <bartosz.markowski@tieto.com> writes:
>
> > Kalle, could you please submit/review these?
>
> I will not commit any patches which have either RFC or RFT tag. And I
> also review them in lower priority.
>
> So if you want me to commit something I recommend to use only PATCH.
>
> --
> Kalle Valo
>

--f46d04388e55778a4404dc43abee
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>Michal, could you please address Kalle&#39;s comments.</div>
<div>=A0</div>
<div>From me ACK for the series (tested OK)</div>
<div>=A0</div>
<div>Bartosz<br><br></div>
<div class=3D"gmail_quote">On 9 May 2013 12:33, Kalle Valo <span dir=3D"ltr=
">&lt;<a href=3D"mailto:kvalo@qca.qualcomm.com" target=3D"_blank">kvalo at qca=
.qualcomm.com</a>&gt;</span> wrote:<br>
<blockquote style=3D"BORDER-LEFT:#ccc 1px solid;MARGIN:0px 0px 0px 0.8ex;PA=
DDING-LEFT:1ex" class=3D"gmail_quote">
<div class=3D"im">Bartosz Markowski &lt;<a href=3D"mailto:bartosz.markowski=
@tieto.com">bartosz.markowski at tieto.com</a>&gt; writes:<br><br>&gt; Kalle, =
could you please submit/review these?<br><br></div>I will not commit any pa=
tches which have either RFC or RFT tag. And I<br>
also review them in lower priority.<br><br>So if you want me to commit some=
thing I recommend to use only PATCH.<br><span class=3D"HOEnZb"><font color=
=3D"#888888"><br>--<br>Kalle Valo<br></font></span></blockquote></div><br>

--f46d04388e55778a4404dc43abee--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-03 10:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-04-03 10:31 UTC (permalink / raw)
  To: ath9k-devel

supposed to be prepared for reception of the firmware code from the driver.
This normally happens when the device boots up and passes the first stage of
the bootloader.  I suppose (I'm really totally guessing) that the driver
somehow doesn't do something to prepare the device for firmware upload if the
device is already past stage 2.

I would love to have the UART pins connected to some terminal, but I don't
have the soldering tools for such small-scale work...

-- 
A person is shit's way of making more shit.
		-- S. Barnett, anthropologist.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-12  7:08 Callum Hutchinson
  0 siblings, 0 replies; 409+ messages in thread
From: Callum Hutchinson @ 2013-04-12  7:08 UTC (permalink / raw)
  To: b43-dev, linux-wireless

Hi Kernel Maintainers,

Tried to report this properly via email but got some formatting issues
coming back, I've attached the content of the original email report as
'Report.txt'.

It is the same file as found on comment 12 on Launchpad bug.
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1142385

Apologies for any missing information or lack of reporting experience :)
-------------- next part --------------
B43 Wireless Autoconnect Failure

I installed raring to test whether this bug existed in it and quantal too.
In the 3.8+ kernels there seems to be an issue with the b43 drivers, my
wireless works however it won't automatically connect to my hidden wireless
network. I have to go into network manager on each login and manually
select the option to connect, it takes a while but then the connection
works fine.
I know this didn't exist in 3.7.x because I was using those kernels
absolutely fine, it's only when I tried 3.8 on both quantal and raring that
the issue arose.
Note: I can't edit the wireless settings on my network as I am not the
administrator in my house.

ProblemType: Bug
DistroRelease: Ubuntu 13.04
Package: linux-image-3.8.0-9-generic 3.8.0-9.18
ProcVersionSignature: Ubuntu 3.8.0-9.18-generic 3.8.1
Uname: Linux 3.8.0-9-generic x86_64
ApportVersion: 2.9-0ubuntu2
Architecture: amd64
AudioDevicesInUse:
 USER PID ACCESS COMMAND
 /dev/snd/controlC0: callum 1770 F.... pulseaudio
                      callum 3234 F.... pulseaudio
CRDA:
 country GB:
  (2402 - 2482 @ 40), (N/A, 20)
  (5170 - 5250 @ 40), (N/A, 20)
  (5250 - 5330 @ 40), (N/A, 20), DFS
  (5490 - 5710 @ 40), (N/A, 27), DFS
Date: Sun Mar 3 16:13:52 2013
HibernationDevice: RESUME=UUID=53b96653-3e0d-426b-a911-9c34d8657655
InstallationDate: Installed on 2013-03-02 (1 days ago)
InstallationMedia: Ubuntu 13.04 "Raring Ringtail" - Alpha amd64 (20130301)
MachineType: Apple Inc. Macmini5,1
MarkForUpload: True
ProcFB: 0 inteldrmfb
ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-3.8.0-9-generic
root=UUID=b4faf392-19de-4749-bd48-bbda7a7519b3 ro quiet splash vt.handoff=7
RelatedPackageVersions:
 linux-restricted-modules-3.8.0-9-generic N/A
 linux-backports-modules-3.8.0-9-generic N/A
 linux-firmware 1.103
SourcePackage: linux
UpgradeStatus: No upgrade log present (probably fresh install)
dmi.bios.date: 01/24/2012
dmi.bios.vendor: Apple Inc.
dmi.bios.version: MM51.88Z.0077.B10.1201241549
dmi.board.asset.tag: Base Board Asset Tag#
dmi.board.name: Mac-8ED6AF5B48C039E1
dmi.board.vendor: Apple Inc.
dmi.board.version: Macmini5,1
dmi.chassis.type: 16
dmi.chassis.vendor: Apple Inc.
dmi.chassis.version: Mac-8ED6AF5B48C039E1
dmi.modalias:
dmi:bvnAppleInc.:bvrMM51.88Z.0077.B10.1201241549:bd01/24/2012:svnAppleInc.:pnMacmini5,1:pvr1.0:rvnAppleInc.:rnMac-8ED6AF5B48C039E1:rvrMacmini5,1:cvnAppleInc.:ct16:cvrMac-8ED6AF5B48C039E1:
dmi.product.name: Macmini5,1
dmi.product.version: 1.0
dmi.sys.vendor: Apple Inc.

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1142385

amd64, mac, b43, networking, wireless, kernel

Linux version 3.9.0-030900rc4-generic (apw at gomeisa) (gcc version 4.6.3
(Ubuntu/Linaro 4.6.3-1ubuntu5) ) #201303232035 SMP Sun Mar 24 00:36:21 UTC
2013

Description: Ubuntu Raring Ringtail (development branch)

Release: 13.04

If some fields are empty or look unusual you may have an old version.

Compare to the current minimal requirements in Documentation/Changes.



Linux callum-Macmini 3.9.0-030900rc4-generic #201303232035 SMP Sun Mar 24
00:36:21 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux



Gnu C                  4.7

Gnu make               3.81

binutils               2.23.2

util-linux             2.20.1

mount                  support

module-init-tools      9

e2fsprogs              1.42.5

pcmciautils            018

PPP                    2.4.5

Linux C Library        2.17

Dynamic linker (ldd)   2.17

Procps                 3.3.3

Net-tools              1.60

Kbd                    1.15.5

Sh-utils               8.20

wireless-tools         30

Modules Loaded         btrfs raid6_pq zlib_deflate xor ufs qnx4 hfsplus hfs
minix ntfs msdos jfs xfs libcrc32c reiserfs ext2 hid_magicmouse joydev hidp
parport_pc ppdev bnep rfcomm coretemp kvm_intel arc4 kvm snd_hda_codec_hdmi
snd_hda_codec_cirrus snd_hda_intel b43 btusb ghash_clmulni_intel
snd_hda_codec aesni_intel bluetooth aes_x86_64 snd_hwdep xts snd_pcm lrw
gf128mul binfmt_misc ablk_helper mac80211 i915 snd_page_alloc cryptd
snd_seq_midi snd_seq_midi_event snd_rawmidi cfg80211 snd_seq drm_kms_helper
snd_seq_device drm snd_timer ssb snd apple_gmux i2c_algo_bit soundcore
microcode shpchp applesmc mei apple_bl mac_hid input_polldev lpc_ich bcma
video lp parport hid_generic hid_apple usbhid hid firewire_ohci sdhci_pci
sdhci firewire_core tg3 crc_itu_t ptp pps_core
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz
stepping : 7
microcode : 0x1a
cpu MHz : 800.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm
constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3
cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes
xsave avx lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi
flexpriority ept vpid
bogomips : 4589.47
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz
stepping : 7
microcode : 0x1a
cpu MHz : 800.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 2
initial apicid : 2
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm
constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3
cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes
xsave avx lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi
flexpriority ept vpid
bogomips : 4589.47
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 2
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz
stepping : 7
microcode : 0x1a
cpu MHz : 800.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm
constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3
cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes
xsave avx lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi
flexpriority ept vpid
bogomips : 4589.47
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz
stepping : 7
microcode : 0x1a
cpu MHz : 800.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 3
initial apicid : 3
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm
constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc
aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3
cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes
xsave avx lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi
flexpriority ept vpid
bogomips : 4589.47
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

btrfs 843910 0 - Live 0x0000000000000000
raid6_pq 97812 1 btrfs, Live 0x0000000000000000
zlib_deflate 27110 1 btrfs, Live 0x0000000000000000
xor 21411 1 btrfs, Live 0x0000000000000000
ufs 75149 0 - Live 0x0000000000000000
qnx4 13396 0 - Live 0x0000000000000000
hfsplus 103443 0 - Live 0x0000000000000000
hfs 54780 0 - Live 0x0000000000000000
minix 36387 0 - Live 0x0000000000000000
ntfs 101633 0 - Live 0x0000000000000000
msdos 17332 0 - Live 0x0000000000000000
jfs 186589 0 - Live 0x0000000000000000
xfs 888928 0 - Live 0x0000000000000000
libcrc32c 12615 2 btrfs,xfs, Live 0x0000000000000000
reiserfs 248298 0 - Live 0x0000000000000000
ext2 73755 0 - Live 0x0000000000000000
hid_magicmouse 13712 0 - Live 0x0000000000000000
joydev 17613 0 - Live 0x0000000000000000
hidp 22599 2 - Live 0x0000000000000000
parport_pc 32866 0 - Live 0x0000000000000000
ppdev 17106 0 - Live 0x0000000000000000
bnep 18258 2 - Live 0x0000000000000000
rfcomm 47863 12 - Live 0x0000000000000000
coretemp 13596 0 - Live 0x0000000000000000
kvm_intel 138733 0 - Live 0x0000000000000000
arc4 12573 2 - Live 0x0000000000000000
kvm 452835 1 kvm_intel, Live 0x0000000000000000
snd_hda_codec_hdmi 37407 1 - Live 0x0000000000000000
snd_hda_codec_cirrus 14090 1 - Live 0x0000000000000000
snd_hda_intel 44397 3 - Live 0x0000000000000000
b43 391985 0 - Live 0x0000000000000000
btusb 18291 0 - Live 0x0000000000000000
ghash_clmulni_intel 13259 0 - Live 0x0000000000000000
snd_hda_codec 190010 3
snd_hda_codec_hdmi,snd_hda_codec_cirrus,snd_hda_intel, Live
0x0000000000000000
aesni_intel 55449 2 - Live 0x0000000000000000
bluetooth 251354 31 hidp,bnep,rfcomm,btusb, Live 0x0000000000000000
aes_x86_64 17131 1 aesni_intel, Live 0x0000000000000000
snd_hwdep 13613 1 snd_hda_codec, Live 0x0000000000000000
xts 12922 1 aesni_intel, Live 0x0000000000000000
snd_pcm 102477 3 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec, Live
0x0000000000000000
lrw 13294 1 aesni_intel, Live 0x0000000000000000
gf128mul 14951 2 xts,lrw, Live 0x0000000000000000
binfmt_misc 17540 1 - Live 0x0000000000000000
ablk_helper 13597 1 aesni_intel, Live 0x0000000000000000
mac80211 656112 1 b43, Live 0x0000000000000000
i915 631460 4 - Live 0x0000000000000000
snd_page_alloc 18798 2 snd_hda_intel,snd_pcm, Live 0x0000000000000000
cryptd 20501 3 ghash_clmulni_intel,aesni_intel,ablk_helper, Live
0x0000000000000000
snd_seq_midi 13324 0 - Live 0x0000000000000000
snd_seq_midi_event 14899 1 snd_seq_midi, Live 0x0000000000000000
snd_rawmidi 30417 1 snd_seq_midi, Live 0x0000000000000000
cfg80211 547072 2 b43,mac80211, Live 0x0000000000000000
snd_seq 61930 2 snd_seq_midi,snd_seq_midi_event, Live 0x0000000000000000
drm_kms_helper 49082 1 i915, Live 0x0000000000000000
snd_seq_device 14497 3 snd_seq_midi,snd_rawmidi,snd_seq, Live
0x0000000000000000
drm 295908 5 i915,drm_kms_helper, Live 0x0000000000000000
snd_timer 29989 2 snd_pcm,snd_seq, Live 0x0000000000000000
ssb 57592 1 b43, Live 0x0000000000000000
snd 69533 16
snd_hda_codec_hdmi,snd_hda_codec_cirrus,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_rawmidi,snd_seq,snd_seq_device,snd_timer,
Live 0x0000000000000000
apple_gmux 13406 0 - Live 0x0000000000000000
i2c_algo_bit 13564 1 i915, Live 0x0000000000000000
soundcore 12680 1 snd, Live 0x0000000000000000
microcode 22923 0 - Live 0x0000000000000000
shpchp 37201 0 - Live 0x0000000000000000
applesmc 19564 0 - Live 0x0000000000000000
mei 46555 0 - Live 0x0000000000000000
apple_bl 13673 1 apple_gmux, Live 0x0000000000000000
mac_hid 13253 0 - Live 0x0000000000000000
input_polldev 13896 1 applesmc, Live 0x0000000000000000
lpc_ich 17060 0 - Live 0x0000000000000000
bcma 41434 1 b43, Live 0x0000000000000000
video 19467 2 i915,apple_gmux, Live 0x0000000000000000
lp 17799 0 - Live 0x0000000000000000
parport 46562 3 parport_pc,ppdev,lp, Live 0x0000000000000000
hid_generic 12548 0 - Live 0x0000000000000000
hid_apple 13389 0 - Live 0x0000000000000000
usbhid 47346 0 - Live 0x0000000000000000
hid 101248 5 hid_magicmouse,hidp,hid_generic,hid_apple,usbhid, Live
0x0000000000000000
firewire_ohci 44864 0 - Live 0x0000000000000000
sdhci_pci 18720 0 - Live 0x0000000000000000
sdhci 33227 1 sdhci_pci, Live 0x0000000000000000
firewire_core 64836 1 firewire_ohci, Live 0x0000000000000000
tg3 165632 0 - Live 0x0000000000000000
crc_itu_t 12707 1 firewire_core, Live 0x0000000000000000
ptp 18668 1 tg3, Live 0x0000000000000000
pps_core 14080 1 ptp, Live 0x0000000000000000

0000-0cf7 : PCI Bus 0000:00
  0000-001f : dma1
  0020-0021 : pic1
  0040-0043 : timer0
  0050-0053 : timer1
  0060-0060 : keyboard
  0062-0062 : EC data
  0064-0064 : keyboard
  0066-0066 : EC cmd
  0070-0077 : rtc0
  0080-008f : dma page reg
  00a0-00a1 : pic2
  00c0-00df : dma2
  00f0-00ff : fpu
  0300-031f : applesmc
  0400-047f : pnp 00:04
    0400-0403 : ACPI PM1a_EVT_BLK
    0404-0405 : ACPI PM1a_CNT_BLK
    0408-040b : ACPI PM_TMR
    0410-0415 : ACPI CPU throttle
    0420-042f : ACPI GPE0_BLK
    0430-0433 : iTCO_wdt
    0450-0450 : ACPI PM2_CNT_BLK
    0460-047f : iTCO_wdt
  0500-057f : pnp 00:04
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
  1000-100f : pnp 00:04
  2000-203f : 0000:00:02.0
  2060-206f : 0000:00:1f.2
    2060-206f : ata_piix
  20c0-20df : 0000:00:1d.0
    20c0-20df : uhci_hcd
  2120-213f : 0000:00:1a.0
    2120-213f : uhci_hcd
  2140-2147 : 0000:00:1f.2
    2140-2147 : ata_piix
  2148-214f : 0000:00:1f.2
    2148-214f : ata_piix
  2158-215b : 0000:00:1f.2
    2158-215b : ata_piix
  215c-215f : 0000:00:1f.2
    215c-215f : ata_piix
  3000-3fff : PCI Bus 0000:06
  efa0-efbf : 0000:00:1f.3
  ffe0-ffef : 0000:00:1f.2
    ffe0-ffef : ata_piix
00000000-00000fff : reserved
00001000-0008efff : System RAM
0008f000-0008ffff : reserved
00090000-0009fbff : System RAM
0009fc00-000fffff : reserved
  000a0000-000bffff : PCI Bus 0000:00
  000c0000-000cedff : Video ROM
  000f0000-000fffff : System ROM
00100000-1fffffff : System RAM
  01000000-01710dd0 : Kernel code
  01710dd1-01cf3b7f : Kernel data
  01e3c000-01f75fff : Kernel bss
20000000-201fffff : reserved
  20000000-201fffff : pnp 00:09
20200000-3fffffff : System RAM
40000000-401fffff : reserved
  40000000-401fffff : pnp 00:09
40200000-8ad33fff : System RAM
8ad34000-8ad5efff : ACPI Non-volatile Storage
8ad5f000-8afa1fff : ACPI Tables
8afa2000-8affefff : reserved
8afff000-8affffff : ACPI Tables
8b000000-8f9fffff : reserved
8fa00000-feafffff : PCI Bus 0000:00
  90000000-9fffffff : 0000:00:02.0
  a0000000-a03fffff : 0000:00:02.0
  a0400000-a04fffff : PCI Bus 0000:02
    a0400000-a040ffff : 0000:02:00.0
      a0400000-a040ffff : tg3
    a0410000-a041ffff : 0000:02:00.0
      a0410000-a041ffff : tg3
    a0420000-a042ffff : 0000:02:00.1
      a0420000-a042ffff : mmc0
  a0500000-a05fffff : PCI Bus 0000:04
    a0500000-a05fffff : PCI Bus 0000:05
      a0500000-a0503fff : 0000:05:00.0
      a0504000-a05047ff : 0000:05:00.0
        a0504000-a05047ff : firewire_ohci
  a0600000-a06fffff : PCI Bus 0000:03
    a0600000-a0603fff : 0000:03:00.0
      a0600000-a0603fff : bcma-pci-bridge
  a0700000-a07fffff : PCI Bus 0000:02
  a0800000-a08fffff : PCI Bus 0000:01
  a0900000-a0903fff : 0000:00:1b.0
    a0900000-a0903fff : ICH HD audio
  a0906800-a0906bff : 0000:00:1d.7
    a0906800-a0906bff : ehci_hcd
  a0906c00-a0906fff : 0000:00:1a.7
    a0906c00-a0906fff : ehci_hcd
  a0907000-a09070ff : 0000:00:1f.3
  a0907100-a090710f : 0000:00:16.0
    a0907100-a090710f : mei
  a0a00000-a4efffff : PCI Bus 0000:06
  a4f00000-a8efffff : PCI Bus 0000:06
  e0000000-efffffff : reserved
    e0000000-efffffff : pnp 00:08
      e0000000-e9cfffff : PCI MMCONFIG 0000 [bus 00-9c]
fec00000-fec00fff : reserved
  fec00000-fec003ff : IOAPIC 0
fed00000-fed03fff : reserved
  fed00000-fed003ff : HPET 0
    fed00000-fed003ff : pnp 00:02
fed10000-fed13fff : reserved
fed18000-fed19fff : reserved
  fed18000-fed18fff : pnp 00:08
  fed19000-fed19fff : pnp 00:08
fed1c000-fed1ffff : reserved
  fed1c000-fed1ffff : pnp 00:08
    fed1f410-fed1f414 : iTCO_wdt
fed20000-fed3ffff : pnp 00:08
fed40000-fed44fff : PCI Bus 0000:00
fed45000-fed8ffff : pnp 00:08
fed90000-fed93fff : pnp 00:08
fee00000-fee00fff : Local APIC
  fee00000-fee00fff : reserved
ff800000-ffffffff : reserved
100000000-26fdfffff : System RAM
26fe00000-26fffffff : RAM buffer

AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci

00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family
High Definition Audio Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 47
Region 0: Memory@a0900000 (64-bit, non-prefetchable) [size=16K]
 Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
 Address: 00000000fee0f00c  Data: 4162
Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset+
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns,
L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Virtual Channel
 Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
 Ctrl: ArbSelect=Fixed
Status: InProgress-
 VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
 VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=1 ArbSelect=Fixed TC/VC=22
Status: NegoPending- InProgress-
 Capabilities: [130 v1] Root Complex Link
Desc: PortNumber=0f ComponentID=00 EltType=Config
 Link0: Desc: TargetPort=00 TargetComponent=00 AssocRCRB-
LinkType=MemMapped LinkValid+
 Addr: 00000000fed1c000
Kernel driver in use: snd_hda_intel

00:1c.0 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 1 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0700000-a07fffff
 Prefetchable memory behind bridge: 00000000a0400000-00000000a04fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #1, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41d1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.1 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 2 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0600000-a06fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #2, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41e1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.2 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 3 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=04, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #3, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 4122
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1d.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Universal Host Controller #1 (rev 05) (prog-if 00 [UHCI])
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 4: I/O ports@20c0 [size=32]
 Capabilities: [50] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: uhci_hcd

00:1d.7 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Enhanced Host Controller #1 (rev 05) (prog-if 20 [EHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin A routed to IRQ 22
Region 0: Memory@a0906800 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci

00:1f.0 ISA bridge: Intel Corporation HM65 Express Chipset Family LPC
Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich

00:1f.2 IDE interface: Intel Corporation 6 Series/C200 Series Chipset
Family 4 port SATA IDE Controller (rev 05) (prog-if 8f [Master SecP SecO
PriP PriO])
Subsystem: Intel Corporation Device 7270
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 0: I/O ports at 2148 [size=8]
 Region 1: I/O ports at 215c [size=4]
Region 2: I/O ports at 2140 [size=8]
Region 3: I/O ports at 2158 [size=4]
 Region 4: I/O ports at 2060 [size=16]
Region 5: I/O ports@ffe0 [size=16]
Capabilities: [70] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [b0] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: ata_piix

00:1f.3 SMBus: Intel Corporation 6 Series/C200 Series Chipset Family SMBus
Controller (rev 05)
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Interrupt: pin C routed to IRQ 11
 Region 0: Memory at a0907000 (64-bit, non-prefetchable) [size=256]
Region 4: I/O ports@efa0 [size=32]

02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM57765
Gigabit Ethernet PCIe (rev 10)
Subsystem: Broadcom Corporation NetXtreme BCM57765 Gigabit Ethernet PCIe
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 16
Region 0: Memory at a0400000 (64-bit, prefetchable) [size=64K]
 Region 2: Memory@a0410000 (64-bit, prefetchable) [size=64K]
Capabilities: [48] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
 Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
Address: 0000000000000000  Data: 0000
Capabilities: [a0] MSI-X: Enable+ Count=6 Masked-
 Vector table: BAR=2 offset=00000000
PBA: BAR=2 offset=00000120
Capabilities: [ac] Express (v2) Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [13c v1] Device Serial Number 00-00-3c-07-54-52-c0-d1
 Capabilities: [150 v1] Power Budgeting <?>
Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: tg3

02:00.1 SD Host controller: Broadcom Corporation NetXtreme BCM57765 Memory
Card Reader (rev 10) (prog-if 01)
Subsystem: Broadcom Corporation Device 0000
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin B routed to IRQ 17
Region 0: Memory@a0420000 (64-bit, prefetchable) [size=64K]
 Capabilities: [48] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [58] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [ac] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
 ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [150 v1] Power Budgeting <?>
 Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: sdhci-pci

03:00.0 Network controller: Broadcom Corporation BCM4331 802.11a/b/g/n (rev
02)
Subsystem: Apple Inc. Device 00e4
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Interrupt: pin A routed to IRQ 17
Region 0: Memory@a0600000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=2 PME-
 Capabilities: [58] Vendor Specific Information: Len=78 <?>
Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [d0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited
 ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <4us, L1
<64us
ClockPM+ Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-
 Capabilities: [13c v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [160 v1] Device Serial Number 87-7d-6d-ff-ff-57-68-a8
 Capabilities: [16c v1] Power Budgeting <?>
Kernel driver in use: bcma-pci-bridge

04:00.0 PCI bridge: Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI
Bridge [Cheetah Express] (rev 01) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=04, secondary=05, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz+ FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Bridge: PM- B3+
Capabilities: [60] MSI: Enable- Count=1/16 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [80] Subsystem: Device 0000:0000
Capabilities: [90] Express (v1) PCI/PCI-X Bridge, MSI 00
 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ BrConfRtry-
 MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns,
L1 <16us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-

05:00.0 FireWire (IEEE 1394): Texas Instruments XIO2213A/B/XIO2221
IEEE-1394b OHCI Controller [Cheetah Express] (rev 01) (prog-if 10 [OHCI])
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 248 (500ns min, 1000ns max), Cache Line Size: 64 bytes
 Interrupt: pin A routed to IRQ 18
Region 0: Memory at a0504000 (32-bit, non-prefetchable) [size=2K]
Region 1: Memory at a0500000 (32-bit, non-prefetchable) [size=16K]
 Capabilities: [44] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Kernel driver in use: firewire_ohci

callum@callum-Macmini:~$ sudo lspci -vvv
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family
DRAM Controller (rev 09)
Subsystem: Apple Inc. Device 00e6
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ >SERR- <PERR- INTx-
 Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>

00:01.0 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core
Processor Family PCI Express Root Port (rev 09) (prog-if 00 [Normal decode])
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 0000f000-00000fff
 Memory behind bridge: a0800000-a08fffff
Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
 Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
 PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [88] Subsystem: Apple Inc. Device 00e6
 Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
 Address: fee0f00c  Data: 41b1
Capabilities: [a0] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
 LnkCap: Port #2, Speed 5GT/s, Width x8, ASPM L0s L1, Latency L0 <1us, L1
<4us
ClockPM- Surprise- LLActRep- BwNot+
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled+ Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #1, PowerLimit 75.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
 Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Not Supported, TimeoutDis- ARIFwd-
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -3.5dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [140 v1] Root Complex Link
 Desc: PortNumber=02 ComponentID=01 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=01 AssocRCRB- LinkType=MemMapped
LinkValid+
 Addr: 00000000fed19000
Kernel driver in use: pcieport

00:01.1 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core
Processor Family PCI Express Root Port (rev 09) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=06, subordinate=9c, sec-latency=0
I/O behind bridge: 00003000-00003fff
Memory behind bridge: a0a00000-a4efffff
 Prefetchable memory behind bridge: 00000000a4f00000-00000000a8efffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [88] Subsystem: Apple Inc. Device 00e6
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
 Address: fee0f00c  Data: 41c1
Capabilities: [a0] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
 LnkCap: Port #3, Speed 5GT/s, Width x8, ASPM L0s L1, Latency L0 <256ns, L1
<4us
ClockPM- Surprise- LLActRep- BwNot+
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled+ Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #2, PowerLimit 75.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet+ LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Not Supported, TimeoutDis- ARIFwd-
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -3.5dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [140 v1] Root Complex Link
 Desc: PortNumber=03 ComponentID=01 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=01 AssocRCRB- LinkType=MemMapped
LinkValid+
 Addr: 00000000fed19000
Kernel driver in use: pcieport

00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core
Processor Family Integrated Graphics Controller (rev 09) (prog-if 00 [VGA
controller])
Subsystem: Apple Inc. Device 00e6
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin A routed to IRQ 46
Region 0: Memory at a0000000 (64-bit, non-prefetchable) [size=4M]
 Region 2: Memory at 90000000 (64-bit, prefetchable) [size=256M]
Region 4: I/O ports at 2000 [size=64]
 Expansion ROM@<unassigned> [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 4152
 Capabilities: [d0] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a4] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: i915

00:16.0 Communication controller: Intel Corporation 6 Series/C200 Series
Chipset Family MEI Controller #1 (rev 04)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin A routed to IRQ 45
Region 0: Memory@a0907100 (64-bit, non-prefetchable) [size=16]
 Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [8c] MSI: Enable+ Count=1/1 Maskable- 64bit+
 Address: 00000000fee0f00c  Data: 4142
Kernel driver in use: mei

00:1a.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Universal Host Controller #5 (rev 05) (prog-if 00 [UHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin B routed to IRQ 21
Region 4: I/O ports@2120 [size=32]
Capabilities: [50] PCI Advanced Features
 AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
 Kernel driver in use: uhci_hcd

00:1a.7 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Enhanced Host Controller #2 (rev 05) (prog-if 20 [EHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin A routed to IRQ 23
Region 0: Memory@a0906c00 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci

00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family
High Definition Audio Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 47
Region 0: Memory@a0900000 (64-bit, non-prefetchable) [size=16K]
 Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
 Address: 00000000fee0f00c  Data: 4162
Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset+
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns,
L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Virtual Channel
 Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
 Ctrl: ArbSelect=Fixed
Status: InProgress-
 VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
 VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=1 ArbSelect=Fixed TC/VC=22
Status: NegoPending- InProgress-
 Capabilities: [130 v1] Root Complex Link
Desc: PortNumber=0f ComponentID=00 EltType=Config
 Link0: Desc: TargetPort=00 TargetComponent=00 AssocRCRB-
LinkType=MemMapped LinkValid+
 Addr: 00000000fed1c000
Kernel driver in use: snd_hda_intel

00:1c.0 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 1 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0700000-a07fffff
 Prefetchable memory behind bridge: 00000000a0400000-00000000a04fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #1, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41d1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.1 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 2 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0600000-a06fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #2, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41e1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.2 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 3 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=04, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #3, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 4122
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1d.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Universal Host Controller #1 (rev 05) (prog-if 00 [UHCI])
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 4: I/O ports@20c0 [size=32]
 Capabilities: [50] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: uhci_hcd

00:1d.7 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Enhanced Host Controller #1 (rev 05) (prog-if 20 [EHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin A routed to IRQ 22
Region 0: Memory@a0906800 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci

00:1f.0 ISA bridge: Intel Corporation HM65 Express Chipset Family LPC
Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich

00:1f.2 IDE interface: Intel Corporation 6 Series/C200 Series Chipset
Family 4 port SATA IDE Controller (rev 05) (prog-if 8f [Master SecP SecO
PriP PriO])
Subsystem: Intel Corporation Device 7270
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 0: I/O ports at 2148 [size=8]
 Region 1: I/O ports at 215c [size=4]
Region 2: I/O ports at 2140 [size=8]
Region 3: I/O ports at 2158 [size=4]
 Region 4: I/O ports at 2060 [size=16]
Region 5: I/O ports@ffe0 [size=16]
Capabilities: [70] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [b0] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: ata_piix

00:1f.3 SMBus: Intel Corporation 6 Series/C200 Series Chipset Family SMBus
Controller (rev 05)
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Interrupt: pin C routed to IRQ 11
 Region 0: Memory at a0907000 (64-bit, non-prefetchable) [size=256]
Region 4: I/O ports@efa0 [size=32]

02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM57765
Gigabit Ethernet PCIe (rev 10)
Subsystem: Broadcom Corporation NetXtreme BCM57765 Gigabit Ethernet PCIe
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 16
Region 0: Memory at a0400000 (64-bit, prefetchable) [size=64K]
 Region 2: Memory@a0410000 (64-bit, prefetchable) [size=64K]
Capabilities: [48] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
 Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
Address: 0000000000000000  Data: 0000
Capabilities: [a0] MSI-X: Enable+ Count=6 Masked-
 Vector table: BAR=2 offset=00000000
PBA: BAR=2 offset=00000120
Capabilities: [ac] Express (v2) Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [13c v1] Device Serial Number 00-00-3c-07-54-52-c0-d1
 Capabilities: [150 v1] Power Budgeting <?>
Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: tg3

02:00.1 SD Host controller: Broadcom Corporation NetXtreme BCM57765 Memory
Card Reader (rev 10) (prog-if 01)
Subsystem: Broadcom Corporation Device 0000
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin B routed to IRQ 17
Region 0: Memory@a0420000 (64-bit, prefetchable) [size=64K]
 Capabilities: [48] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [58] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [ac] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
 ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [150 v1] Power Budgeting <?>
 Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: sdhci-pci

03:00.0 Network controller: Broadcom Corporation BCM4331 802.11a/b/g/n (rev
02)
Subsystem: Apple Inc. Device 00e4
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Interrupt: pin A routed to IRQ 17
Region 0: Memory@a0600000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=2 PME-
 Capabilities: [58] Vendor Specific Information: Len=78 <?>
Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [d0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited
 ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <4us, L1
<64us
ClockPM+ Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-
 Capabilities: [13c v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [160 v1] Device Serial Number 87-7d-6d-ff-ff-57-68-a8
 Capabilities: [16c v1] Power Budgeting <?>
Kernel driver in use: bcma-pci-bridge

04:00.0 PCI bridge: Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI
Bridge [Cheetah Express] (rev 01) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=04, secondary=05, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz+ FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Bridge: PM- B3+
Capabilities: [60] MSI: Enable- Count=1/16 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [80] Subsystem: Device 0000:0000
Capabilities: [90] Express (v1) PCI/PCI-X Bridge, MSI 00
 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ BrConfRtry-
 MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns,
L1 <16us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-

05:00.0 FireWire (IEEE 1394): Texas Instruments XIO2213A/B/XIO2221
IEEE-1394b OHCI Controller [Cheetah Express] (rev 01) (prog-if 10 [OHCI])
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 248 (500ns min, 1000ns max), Cache Line Size: 64 bytes
 Interrupt: pin A routed to IRQ 18
Region 0: Memory at a0504000 (32-bit, non-prefetchable) [size=2K]
Region 1: Memory at a0500000 (32-bit, non-prefetchable) [size=16K]
 Capabilities: [44] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Kernel driver in use: firewire_ohci

callum at callum-Macmini:~$ clear

callum@callum-Macmini:~$ sudo lspci -vvv
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family
DRAM Controller (rev 09)
 Subsystem: Apple Inc. Device 00e6
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ >SERR- <PERR- INTx-
Latency: 0
 Capabilities: [e0] Vendor Specific Information: Len=0c <?>

00:01.0 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core
Processor Family PCI Express Root Port (rev 09) (prog-if 00 [Normal decode])
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 0000f000-00000fff
 Memory behind bridge: a0800000-a08fffff
Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
 Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
 PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [88] Subsystem: Apple Inc. Device 00e6
 Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
 Address: fee0f00c  Data: 41b1
Capabilities: [a0] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
 LnkCap: Port #2, Speed 5GT/s, Width x8, ASPM L0s L1, Latency L0 <1us, L1
<4us
ClockPM- Surprise- LLActRep- BwNot+
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled+ Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #1, PowerLimit 75.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
 Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Not Supported, TimeoutDis- ARIFwd-
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -3.5dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [140 v1] Root Complex Link
 Desc: PortNumber=02 ComponentID=01 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=01 AssocRCRB- LinkType=MemMapped
LinkValid+
 Addr: 00000000fed19000
Kernel driver in use: pcieport

00:01.1 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core
Processor Family PCI Express Root Port (rev 09) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=06, subordinate=9c, sec-latency=0
I/O behind bridge: 00003000-00003fff
Memory behind bridge: a0a00000-a4efffff
 Prefetchable memory behind bridge: 00000000a4f00000-00000000a8efffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [88] Subsystem: Apple Inc. Device 00e6
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
 Address: fee0f00c  Data: 41c1
Capabilities: [a0] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
 LnkCap: Port #3, Speed 5GT/s, Width x8, ASPM L0s L1, Latency L0 <256ns, L1
<4us
ClockPM- Surprise- LLActRep- BwNot+
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled+ Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #2, PowerLimit 75.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet+ LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Not Supported, TimeoutDis- ARIFwd-
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -3.5dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [140 v1] Root Complex Link
 Desc: PortNumber=03 ComponentID=01 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=01 AssocRCRB- LinkType=MemMapped
LinkValid+
 Addr: 00000000fed19000
Kernel driver in use: pcieport

00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core
Processor Family Integrated Graphics Controller (rev 09) (prog-if 00 [VGA
controller])
Subsystem: Apple Inc. Device 00e6
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin A routed to IRQ 46
Region 0: Memory at a0000000 (64-bit, non-prefetchable) [size=4M]
 Region 2: Memory at 90000000 (64-bit, prefetchable) [size=256M]
Region 4: I/O ports at 2000 [size=64]
 Expansion ROM@<unassigned> [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 4152
 Capabilities: [d0] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [a4] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: i915

00:16.0 Communication controller: Intel Corporation 6 Series/C200 Series
Chipset Family MEI Controller #1 (rev 04)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin A routed to IRQ 45
Region 0: Memory@a0907100 (64-bit, non-prefetchable) [size=16]
 Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [8c] MSI: Enable+ Count=1/1 Maskable- 64bit+
 Address: 00000000fee0f00c  Data: 4142
Kernel driver in use: mei

00:1a.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Universal Host Controller #5 (rev 05) (prog-if 00 [UHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin B routed to IRQ 21
Region 4: I/O ports@2120 [size=32]
Capabilities: [50] PCI Advanced Features
 AFCap: TP+ FLR+
AFCtrl: FLR-
AFStatus: TP-
 Kernel driver in use: uhci_hcd

00:1a.7 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Enhanced Host Controller #2 (rev 05) (prog-if 20 [EHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin A routed to IRQ 23
Region 0: Memory@a0906c00 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP+
Kernel driver in use: ehci-pci

00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family
High Definition Audio Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 47
Region 0: Memory@a0900000 (64-bit, non-prefetchable) [size=16K]
 Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
 Address: 00000000fee0f00c  Data: 4162
Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset+
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns,
L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Virtual Channel
 Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
 Ctrl: ArbSelect=Fixed
Status: InProgress-
 VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
 VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
 Ctrl: Enable+ ID=1 ArbSelect=Fixed TC/VC=22
Status: NegoPending- InProgress-
 Capabilities: [130 v1] Root Complex Link
Desc: PortNumber=0f ComponentID=00 EltType=Config
 Link0: Desc: TargetPort=00 TargetComponent=00 AssocRCRB-
LinkType=MemMapped LinkValid+
 Addr: 00000000fed1c000
Kernel driver in use: snd_hda_intel

00:1c.0 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 1 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0700000-a07fffff
 Prefetchable memory behind bridge: 00000000a0400000-00000000a04fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #1, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41d1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.1 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 2 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0600000-a06fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #2, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 41e1
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1c.2 PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family
PCI Express Root Port 3 (rev b5) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=00, secondary=04, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [40] Express (v2) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
 ExtTag- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported+
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #3, Speed 5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1
<16us
ClockPM- Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt+
ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
 Slot #0, PowerLimit 10.000W; Interlock- NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
 Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
 Changed: MRL- PresDet- LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
 RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range BC, TimeoutDis+ ARIFwd-
 DevCtl2: Completion Timeout: 260ms to 900ms, TimeoutDis- ARIFwd-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0f00c  Data: 4122
Capabilities: [90] Subsystem: Intel Corporation Apple MacBookPro8,2 [Core
i7, 15", 2011]
 Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: pcieport

00:1d.0 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Universal Host Controller #1 (rev 05) (prog-if 00 [UHCI])
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 4: I/O ports@20c0 [size=32]
 Capabilities: [50] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: uhci_hcd

00:1d.7 USB controller: Intel Corporation 6 Series/C200 Series Chipset
Family USB Enhanced Host Controller #1 (rev 05) (prog-if 20 [EHCI])
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0
 Interrupt: pin A routed to IRQ 22
Region 0: Memory@a0906800 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA
PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [58] Debug port: BAR=1 offset=00a0
Capabilities: [98] PCI Advanced Features
AFCap: TP+ FLR+
 AFCtrl: FLR-
AFStatus: TP-
Kernel driver in use: ehci-pci

00:1f.0 ISA bridge: Intel Corporation HM65 Express Chipset Family LPC
Controller (rev 05)
Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
Kernel driver in use: lpc_ich

00:1f.2 IDE interface: Intel Corporation 6 Series/C200 Series Chipset
Family 4 port SATA IDE Controller (rev 05) (prog-if 8f [Master SecP SecO
PriP PriO])
Subsystem: Intel Corporation Device 7270
 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0
Interrupt: pin B routed to IRQ 19
Region 0: I/O ports at 2148 [size=8]
 Region 1: I/O ports at 215c [size=4]
Region 2: I/O ports at 2140 [size=8]
Region 3: I/O ports at 2158 [size=4]
 Region 4: I/O ports at 2060 [size=16]
Region 5: I/O ports@ffe0 [size=16]
Capabilities: [70] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
 Capabilities: [b0] PCI Advanced Features
AFCap: TP+ FLR+
AFCtrl: FLR-
 AFStatus: TP-
Kernel driver in use: ata_piix

00:1f.3 SMBus: Intel Corporation 6 Series/C200 Series Chipset Family SMBus
Controller (rev 05)
 Subsystem: Intel Corporation Apple MacBookPro8,2 [Core i7, 15", 2011]
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Interrupt: pin C routed to IRQ 11
 Region 0: Memory at a0907000 (64-bit, non-prefetchable) [size=256]
Region 4: I/O ports@efa0 [size=32]

02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM57765
Gigabit Ethernet PCIe (rev 10)
Subsystem: Broadcom Corporation NetXtreme BCM57765 Gigabit Ethernet PCIe
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin A routed to IRQ 16
Region 0: Memory at a0400000 (64-bit, prefetchable) [size=64K]
 Region 2: Memory@a0410000 (64-bit, prefetchable) [size=64K]
Capabilities: [48] Power Management version 3
 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
 Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
Address: 0000000000000000  Data: 0000
Capabilities: [a0] MSI-X: Enable+ Count=6 Masked-
 Vector table: BAR=2 offset=00000000
PBA: BAR=2 offset=00000120
Capabilities: [ac] Express (v2) Endpoint, MSI 00
 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop-
 MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [13c v1] Device Serial Number 00-00-3c-07-54-52-c0-d1
 Capabilities: [150 v1] Power Budgeting <?>
Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: tg3

02:00.1 SD Host controller: Broadcom Corporation NetXtreme BCM57765 Memory
Card Reader (rev 10) (prog-if 01)
Subsystem: Broadcom Corporation Device 0000
 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
 Latency: 0, Cache Line Size: 256 bytes
Interrupt: pin B routed to IRQ 17
Region 0: Memory@a0420000 (64-bit, prefetchable) [size=64K]
 Capabilities: [48] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [58] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [ac] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 <64us
 ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd+ ExtTag- PhantFunc- AuxPwr+ NoSnoop+
MaxPayload 128 bytes, MaxReadReq 4096 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <2us, L1
<64us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+
 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable
De-emphasis: -6dB
 Transmit Margin: Normal Operating Range, EnterModifiedCompliance-
ComplianceSOS-
 Compliance De-emphasis: -6dB
 LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-,
EqualizationPhase1-
 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
 Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [150 v1] Power Budgeting <?>
 Capabilities: [160 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Kernel driver in use: sdhci-pci

03:00.0 Network controller: Broadcom Corporation BCM4331 802.11a/b/g/n (rev
02)
Subsystem: Apple Inc. Device 00e4
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Interrupt: pin A routed to IRQ 17
Region 0: Memory@a0600000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=2 PME-
 Capabilities: [58] Vendor Specific Information: Len=78 <?>
Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [d0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited
 ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
 RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr+ TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <4us, L1
<64us
ClockPM+ Surprise- LLActRep+ BwNot-
 LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-
 Capabilities: [13c v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
 Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
 Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
 Status: NegoPending- InProgress-
Capabilities: [160 v1] Device Serial Number 87-7d-6d-ff-ff-57-68-a8
 Capabilities: [16c v1] Power Budgeting <?>
Kernel driver in use: bcma-pci-bridge

04:00.0 PCI bridge: Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI
Bridge [Cheetah Express] (rev 01) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 256 bytes
 Bus: primary=04, secondary=05, subordinate=05, sec-latency=0
I/O behind bridge: 0000f000-00000fff
Memory behind bridge: a0500000-a05fffff
 Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
Secondary status: 66MHz+ FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort+ <SERR- <PERR-
 BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
 Capabilities: [50] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Bridge: PM- B3+
Capabilities: [60] MSI: Enable- Count=1/16 Maskable- 64bit+
 Address: 0000000000000000  Data: 0000
Capabilities: [80] Subsystem: Device 0000:0000
Capabilities: [90] Express (v1) PCI/PCI-X Bridge, MSI 00
 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ BrConfRtry-
 MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns,
L1 <16us
ClockPM+ Surprise- LLActRep- BwNot-
 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol-
 UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 14, GenCap+ CGenEn- ChkCap+ ChkEn-

05:00.0 FireWire (IEEE 1394): Texas Instruments XIO2213A/B/XIO2221
IEEE-1394b OHCI Controller [Cheetah Express] (rev 01) (prog-if 10 [OHCI])
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr-
Stepping- SERR- FastB2B- DisINTx-
 Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort-
<MAbort- >SERR- <PERR- INTx-
Latency: 248 (500ns min, 1000ns max), Cache Line Size: 64 bytes
 Interrupt: pin A routed to IRQ 18
Region 0: Memory at a0504000 (32-bit, non-prefetchable) [size=2K]
Region 1: Memory@a0500000 (32-bit, non-prefetchable) [size=16K]
 Capabilities: [44] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Kernel driver in use: firewire_ohci

Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: Hitachi HTS54505 Rev: PB4A
  Type:   Direct-Access                    ANSI  SCSI revision: 05

(Apologies to the kernel devs for any useless crap/long reading, I'm just
following the guide to reporting a proper bug for you from
https://wiki.ubuntu.com/Bugs/Upstream/kernel )

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-04-24 18:07 Viral Mehta
  0 siblings, 0 replies; 409+ messages in thread
From: Viral Mehta @ 2013-04-24 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I am using Marvell's ARMADA XP platform in my development environment.

Recently, I faced DMA related issue. While moving data from memory to
the device, I  found that sometimes I am getting Junk data. I looked
further to see if this is related to DMA Sync problem. So, basically,
I have following questions,

1. As per [1] ARMADA has Coherency Fabric that sits between CPU and
other devices and takes care of hardware based I/O cache coherency. Do
we need to enable any support for the same in software ? I am running
3.0.29 based linux kernel. How do I verify that I have all the things
enabled in Linux Kernel.

2. Do I still need to use dma_[map,unamp]_* APIs while copying data to
and from device ?


[1] http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf

--
Thanks,
Viral Mehta

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-06-19 10:57 Ben Dooks
  0 siblings, 0 replies; 409+ messages in thread
From: Ben Dooks @ 2013-06-19 10:57 UTC (permalink / raw)
  To: linux-arm-kernel

I found this one whilst testing versatile-express with a -rc kernel
and was considering if this is the correct way to fix this.

[PATCH] atags_to_fdt: take into account root's #size and #cells

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-06-28  5:49 Wang, Yalin
  0 siblings, 0 replies; 409+ messages in thread
From: Wang, Yalin @ 2013-06-28  5:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sboy,

I don't know who should I send this mail to .
If you are not the right person, please forward 
To the right responsible person , Thank you !

I have a question about msm kernel code :

File: Arch/arm/msm/memory.c

reserve_memory_for_mempools()
it call memblock_remove() directly,
I think it's not safe sometimes ,
Should use arm_memblock_steal() function or some other similar
Function to make sure the removed memory is not reserved by memblock driver,
In case the removed memory is reserved by some driver.


Thanks 


Yalin.Wang
Software Engineer 
OS Kernel&Graphics
?
Sony Mobile Communications
Tel: +86 10 5966 9819
Phone: 18610323092
Address: No.16 Guangshun South Street, Chaoyang, Beijing, P.R.C.

sonymobile.com
??

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-07-26 10:05 Haojian Zhuang
  0 siblings, 0 replies; 409+ messages in thread
From: Haojian Zhuang @ 2013-07-26 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v6:
1. Merge clk apbc & apbcp together.
2. Add DT binding document of clock driver.
3. Remove marvell string in properties of clock driver.

v5:
1. Use clk mux table.

v4:
1. Remove .init_irq in mmp & mmp2 DT machine descriptor.
2. Use an argument to replace TIMER_PHYS_BASE. Now transfer virtual
address directly.
3. Merge 10th & 11th patches together. Remove the redundant changes
on drivers/clocksource/Kconfig & drivers/clocksource/Makefile.

v3:
1. Don't use include/linux/irqchip/mmp.h since we don't need to
move <mach/irqs.h> to <include/linux/irqchip/mmp.h>.
2. Move timer-mmp driver into clocksource directory & support
clocksource.
3. Support clksrc in mmp & parse all clock from DTS.

v2:
1. Avoid to include <mach/irqs.h>. Move the head file into
   include/linux/irqchip directory.
2. Avoid to include <mach/pm-pxa910.h> & <mach/pm-mmp2.h>.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-07-30  4:09 PV Juliet
  0 siblings, 0 replies; 409+ messages in thread
From: PV Juliet @ 2013-07-30  4:09 UTC (permalink / raw)
  To: kernelnewbies

HI ,
    I am new to kernel .   I got some stuff on notifier chains  from net.
Where i can more elaborated  documents on notifier chains ? Can i get the
module out put  to user space(eg usb disk added) ?  I don't want to get it
from dmesg.
Thanks and Regards
Juliet
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130730/6f3de789/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-08-24  9:29 Haojian Zhuang
  0 siblings, 0 replies; 409+ messages in thread
From: Haojian Zhuang @ 2013-08-24  9:29 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v8:
1. Drop to support CLK_GATE_SEPERATED_REG in common clock gate driver.
Support this feature in hi3xxx clock driver.
2. Clean unnecessary device node in DTS.
3. Define all clocks in hi3620-clk.dtsi. And all clock nodes are defined
in the clocks node.
4. Fix the clock gate & clock mux for timer.
5. Rename timer0~4 to dual_timer0~4 in DTS file. It's used to make
name clearer.

v7:
1. Add hi3xxx_defconfig.
2. Use reg property in clock node.
3. Drop origin clock divider table.
4. Reuse clock divider register helper.
5. Reuse clock gate register helper.
6. Append CLK_GATE_SEPERATED_REG flag in order to support Hisilicon
   Hi3620 SoC.
7. Rebase DEBUG_LL for Hi3xxx.
8. Add more clock node in DTS file.

v6:
1. Remove hisilicon string from properties in clock driver.
2. Replace array by pointer in clock driver. Since only sctrl parent
   node exists at this time.

v5:
1. Remove HIWORD clk patches since they're merged into clk git tree.
2. Set hisilicon,clk-reset property of clkgate node is optional.
3. Update on commandline args in DTS file. Remove earlyprintk, mem, nfs.
4. Move gpio-keys out of amba node in DTS file.

v4:
1. Add clk gate with HIWORD mask for Rockchip.
2. Update comments and code of HIWORD flags for mux/divider.
3. Append a mux without HIWORD mask in Hisilicon 3620.
4. Fix the pinmux setting in Hi4511.

v3:
1. Use clk_register_mux_table().

v2:
1. Reuse mux & divider driver. So append CLK_MUX_HIWORD_MASK &
CLK_DIVIDER_HIWORD_MASK for Hi3620 SoC.
2. Fix system timer running too fast because wrong divider is choosen.
3. Remove .init_irq in DT machine descriptor.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-09-02 17:01 Drasko DRASKOVIC
  0 siblings, 0 replies; 409+ messages in thread
From: Drasko DRASKOVIC @ 2013-09-02 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,
In socfpga.dts I can see following definitions :

/* Local timer */
timer at fffec600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xfffec600 0x100>;
interrupts = <1 13 0xf04>;
};

timer0: timer0 at ffc08000 {
compatible = "snps,dw-apb-timer-sp";
interrupts = <0 167 4>;
reg = <0xffc08000 0x1000>;
};

timer1: timer1 at ffc09000 {
compatible = "snps,dw-apb-timer-sp";
interrupts = <0 168 4>;
reg = <0xffc09000 0x1000>;
};

timer2: timer2 at ffd00000 {
compatible = "snps,dw-apb-timer-osc";
interrupts = <0 169 4>;
reg = <0xffd00000 0x1000>;
};

timer3: timer3 at ffd01000 {
compatible = "snps,dw-apb-timer-osc";
interrupts = <0 170 4>;
reg = <0xffd01000 0x1000>;
};


However, from my board's shell :
root at socfpga_cyclone5:~# cat /proc/interrupts
           CPU0       CPU1
525:      24935      24717       GIC  twd
648:        801          0       GIC  eth0
653:          0          0       GIC  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
656:          0          0       GIC  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb2
667:     163006          0       GIC  dw-mci
679:          0          0       GIC  ff705000.spi
682:          0          0       GIC  dw_spi0
684:          0          0       GIC  dw_spi1
686:          6          0       GIC  ffc04000.i2c
687:          0          0       GIC  ffc05000.i2c
690:       2390          0       GIC  serial
697:          9          0       GIC  timer2
IPI0:          0          0  CPU wakeup interrupts
IPI1:          0          0  Timer broadcast interrupts
IPI2:       1268       1289  Rescheduling interrupts
IPI3:          0          0  Function call interrupts
IPI4:          3          1  Single function call interrupts
IPI5:          0          0  CPU stop interrupts
Err:          0

So, I can see only timer2.

root at socfpga_cyclone5:~# find / -name "timer*"
/proc/timer_list
/proc/device-tree/soc/timer3 at ffd01000
/proc/device-tree/soc/timer2 at ffd00000
/proc/device-tree/soc/timer1 at ffc09000
/proc/device-tree/soc/timer0 at ffc08000
/proc/device-tree/soc/timer at fffec600
/proc/device-tree/aliases/timer3
/proc/device-tree/aliases/timer2
/proc/device-tree/aliases/timer1
/proc/device-tree/aliases/timer0
/sys/kernel/debug/tracing/events/timer
/sys/kernel/debug/tracing/events/timer/timer_cancel
/sys/kernel/debug/tracing/events/timer/timer_expire_exit
/sys/kernel/debug/tracing/events/timer/timer_expire_entry
/sys/kernel/debug/tracing/events/timer/timer_start
/sys/kernel/debug/tracing/events/timer/timer_init
/sys/module/oprofile/parameters/timer
root at socfpga_cyclone5:~#

Where is defined which timer will be present, activated and
initialized on the board - i.e. only timer2 is active in this case,
and I would like to use timer1.

BR,
Drasko

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-09-15  9:49 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-09-15  9:49 UTC (permalink / raw)
  To: ath9k-devel

selection is just a few days away) -- but June would be better anyway.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-09-15  9:49 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-09-15  9:49 UTC (permalink / raw)
  To: ath9k-devel

generated acks.
Enabling hw acks results in duplicate, identical acks being sent by the
access point on successful frame receipt.
The difference is just in timings: while hw acks is usually received in
less then 10 or 20 microseconds from a successful frame receipt, sw
generated acks arrive in 2-300 microseconds.

We suppose the problem is in Clear Channel Assessment: the hardware waits
the right (CSMA compliant) time to send the frame while we would like it to
send the ack frame ASAP (i.e. wait SIFS instead of AIFS).

Tried a few flags with no success (tested with or without such flags and no
apparent change happened).
Flags are:

AR_DIAG_FORCE_RX_CLEAR
AR_DIAG_FORCE_CH_IDLE_HIGH
AR_DIAG_IGNORE_VIRT_CS
AR_D_GBL_IFS_MISC_IGNORE_BACKOFF


Possible "next steps":

- choose the correct hw queue  (now using queue skb->queue_mapping=3 and
skb->priority=7)
- find out the correct register values for disabling the virtual and
physical carrier sense (AR_DIAG_SW) for ath9k.
- find out if such values are "honored" in our card or if should be better
to simply change the atheros chipset family or card manufacturer
- disabling back-off setting the cwmin and cwmax to zero on the choosen
queue And also setting AIFS=1 (or zero?)
- disabling any debug code possibly inserted during coding phase (according
to
http://adrianchadd.blogspot.it/2012/11/be-careful-of-adding-debugging-as.html
)


Any suggestion?
Is anyone interested in collaborating in softMAC development? Right now we
are thinking about standard ack mechanism (i.e. a/g) but it could be
extended to blockAck (802.11e or "n" versions of a/g)?


Any feedback welcome...
Thnkz in advance!!!

Alex

--047d7b15ad979ce54c04edbbc6dc
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello everybody!<br>I&#39;s my first time writing to the l=
ist, while I&#39;m following it with interest for some time.<br><br>We&#39;=
re developing some MAC functions in software for testing purposes.<br><br>

The most challenging part seems to be generating Acks in software.<br><br>T=
hree main tasks:<br>1. Disabling Link Layer Acks in hardware<br>2. Generati=
ng Acks as &quot;low&quot; as possible in driver stack<br>3. sending such a=
cks as quickly as possible<br>

<br>Now, task 1 and 2 are done in ath9k: task 1 setting the appropriate fla=
g in the register and task 2 coding link layer ack generation in ath9k_rx t=
asklet.<br><br>We have a problem in task 3.<br>It seems that the ack frame =
is sent like regular frames, respecting CCA, while we would need the ack fr=
ames to be sent immediately, as soon as they&#39;ve been put in the tx queu=
e.<br>

<br>Test environment<br>Access Point <br>Hardware: Alix 2d2 board, Compex W=
LM200NX MiniPCI network adapter (should be Chipset AR9220 according to vend=
or datasheet - kernel Dmesg says &quot;ieee80211 phy0: Atheros AR9280 Rev:2=
 mem=3D0xd0ca0000, irq=3D9&quot;) <br>

Software: OpenWRT REVISION r37112<br><br>Client<br>any WiFi compliant clien=
t such as smartphones and laptop<br><br>Sniffer<br>wireshark on a laptop wi=
th a mon interface<br><br><br>Results<br>From a sniffer perspective you can=
not distinguish between hw and sw generated acks.<br>

Enabling hw acks results in duplicate, identical acks being sent by the acc=
ess point on successful frame receipt.<br>The difference is just in timings=
: while hw acks is usually received in less then 10 or 20 microseconds from=
 a successful frame receipt, sw generated acks arrive in 2-300 microseconds=
.<br>

<br>We suppose the problem is in Clear Channel Assessment: the hardware wai=
ts the right (CSMA compliant) time to send the frame while we would like it=
 to send the ack frame ASAP (i.e. wait SIFS instead of AIFS).<br><br>Tried =
a few flags with no success (tested with or without such flags and no appar=
ent change happened).<br>

Flags are:<br><br>AR_DIAG_FORCE_RX_CLEAR<br>AR_DIAG_FORCE_CH_IDLE_HIGH<br>A=
R_DIAG_IGNORE_VIRT_CS<br>AR_D_GBL_IFS_MISC_IGNORE_BACKOFF<br><br><br>Possib=
le &quot;next steps&quot;:<br><br>- choose the correct hw queue =A0(now usi=
ng queue skb-&gt;queue_mapping=3D3 and skb-&gt;priority=3D7)<br>

- find out the correct register values for disabling the virtual and physic=
al carrier sense (AR_DIAG_SW) for ath9k.<br>- find out if such values are &=
quot;honored&quot; in our card or if should be better to simply change the =
atheros chipset family or card manufacturer<br>

- disabling back-off setting the cwmin and cwmax to zero on the choosen que=
ue And also setting AIFS=3D1 (or zero?)<br>- disabling any debug code possi=
bly inserted during coding phase (according to <a href=3D"http://adrianchad=
d.blogspot.it/2012/11/be-careful-of-adding-debugging-as.html">http://adrian=
chadd.blogspot.it/2012/11/be-careful-of-adding-debugging-as.html</a>)<br>

<br><br>Any suggestion?<br>Is anyone interested in collaborating in softMAC=
 development? Right now we are thinking about standard ack mechanism (i.e. =
a/g) but it could be extended to blockAck (802.11e or &quot;n&quot; version=
s of a/g)?<div>

<br></div><div><br>Any feedback welcome...<br>Thnkz in advance!!!</div><div=
><br></div><div>Alex</div><div><br></div><div><br></div></div>

--047d7b15ad979ce54c04edbbc6dc--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-09-15  9:49 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2013-09-15  9:49 UTC (permalink / raw)
  To: ath9k-devel

timestamp.

The question is, how accurated this timestamp is? The precision is in
nanoseconds, but what accuracy i can expect?

My main need is the implement a good precision TDOA algorithm.

I don't know jack about driver development, but is something that interests
me. If the accuracy is low, can i improve it in driver or firmware?
If its possible, i can even trade reception packet speed for a better
accuracy in timestamp.

The other question is, what is the difference between the ath9k_htc and
carl9170 drivers? Both support the AR9287 (from the debian wiki).

Thanks for all

Links:

Wireshark community:
http://ask.wireshark.org/questions/28683/recommended-wireless-adapter-usb-with-linux-wireshark-that-reports-mactime-in-radiotap-header

Debian Wiki ath9k_htc: https://wiki.debian.org/ath9k_htc

Debian Wiki carl9170: https://wiki.debian.org/carl9170

--001a11335f40ad0de604f2af55f8
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<div><br></div><div>I have one question about hardware =
timestamp in Atheros chipsets.</div><div>From a post in Wireshark community=
, the chipset AR9287 can do hardware timestamp.</div><div><br></div><div>Th=
e question is, how accurated this timestamp is? The precision is in nanosec=
onds, but what accuracy i can expect?</div>

<div><br></div><div>My main need is the implement a good precision TDOA alg=
orithm.=A0</div><div><br></div><div>I don&#39;t know jack about driver deve=
lopment, but is something that=A0interests me. If the accuracy is low, can =
i improve it in driver or firmware?=A0</div>

<div>If its possible, i can even trade reception packet speed for a better =
accuracy in timestamp.</div><div><br></div><div>The other question is, what=
 is the difference between the ath9k_htc and carl9170 drivers? Both support=
 the AR9287 (from the debian wiki).</div>

<div><br></div><div>Thanks for all</div><div><br></div><div>Links:</div><di=
v><br></div><div>Wireshark community: <a href=3D"http://ask.wireshark.org/q=
uestions/28683/recommended-wireless-adapter-usb-with-linux-wireshark-that-r=
eports-mactime-in-radiotap-header">http://ask.wireshark.org/questions/28683=
/recommended-wireless-adapter-usb-with-linux-wireshark-that-reports-mactime=
-in-radiotap-header</a></div>

<div><br></div><div>Debian Wiki ath9k_htc:=A0<a href=3D"https://wiki.debian=
.org/ath9k_htc">https://wiki.debian.org/ath9k_htc</a></div><div><br></div><=
div>Debian Wiki carl9170:=A0<a href=3D"https://wiki.debian.org/carl9170">ht=
tps://wiki.debian.org/carl9170</a></div>

</div>

--001a11335f40ad0de604f2af55f8--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-09-24  3:13 Rohit Vaswani
  0 siblings, 0 replies; 409+ messages in thread
From: Rohit Vaswani @ 2013-09-24  3:13 UTC (permalink / raw)
  To: linux-arm-kernel

Date: Mon, 23 Sep 2013 19:51:25 -0700
Subject: [PATCH 1/3] ARM: debug: Create CONFIG_DEBUG_MSM_UART and re-organize
 the selects for MSM

Create the hidden config DEBUG_MSM_UART and clean-up the default selection
for CONFIG_DEBUG_LL_INCLUDE.

Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
---
 arch/arm/Kconfig.debug | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 9762c84..e18a6fc 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -318,6 +318,7 @@ choice
 	config DEBUG_MSM_UART1
 		bool "Kernel low-level debugging messages via MSM UART1"
 		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		select DEBUG_MSM_UART
 		help
 		  Say Y here if you want the debug print routines to direct
 		  their output to the first serial port on MSM devices.
@@ -325,6 +326,7 @@ choice
 	config DEBUG_MSM_UART2
 		bool "Kernel low-level debugging messages via MSM UART2"
 		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		select DEBUG_MSM_UART
 		help
 		  Say Y here if you want the debug print routines to direct
 		  their output to the second serial port on MSM devices.
@@ -332,6 +334,7 @@ choice
 	config DEBUG_MSM_UART3
 		bool "Kernel low-level debugging messages via MSM UART3"
 		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		select DEBUG_MSM_UART
 		help
 		  Say Y here if you want the debug print routines to direct
 		  their output to the third serial port on MSM devices.
@@ -340,6 +343,7 @@ choice
 		bool "Kernel low-level debugging messages via MSM 8660 UART"
 		depends on ARCH_MSM8X60
 		select MSM_HAS_DEBUG_UART_HS
+		select DEBUG_MSM_UART
 		help
 		  Say Y here if you want the debug print routines to direct
 		  their output to the serial port on MSM 8660 devices.
@@ -348,6 +352,7 @@ choice
 		bool "Kernel low-level debugging messages via MSM 8960 UART"
 		depends on ARCH_MSM8960
 		select MSM_HAS_DEBUG_UART_HS
+		select DEBUG_MSM_UART
 		help
 		  Say Y here if you want the debug print routines to direct
 		  their output to the serial port on MSM 8960 devices.
@@ -880,6 +885,10 @@ config DEBUG_STI_UART
 	bool
 	depends on ARCH_STI
 
+config DEBUG_MSM_UART
+	bool
+	depends on ARCH_MSM
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
@@ -895,11 +904,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_IMX53_UART ||\
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART
-	default "debug/msm.S" if DEBUG_MSM_UART1 || \
-				 DEBUG_MSM_UART2 || \
-				 DEBUG_MSM_UART3 || \
-				 DEBUG_MSM8660_UART || \
-				 DEBUG_MSM8960_UART
+	default "debug/msm.S" if DEBUG_MSM_UART
 	default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
 	default "debug/sti.S" if DEBUG_STI_UART
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2013-11-01  7:04 Xiubo Li
  0 siblings, 0 replies; 409+ messages in thread
From: Xiubo Li @ 2013-11-01  7:04 UTC (permalink / raw)
  To: linux-arm-kernel


Hello,

This patch series is mostly Freescale's SAI SoC Digital Audio Interface driver implementation. And the implementation is only compatible with device tree definition.

This patch series is based on linux-next and has been tested on Vybrid VF610 Tower board using device tree.

Changed in v2:
- Use default settings for the generic dmaengine PCM driver.
- Separate receive and transmit setting in most functions, but some couldn't for the HW limitation.
- Drop some not reduntant code.
- Use devm_snd_soc_register_component() instead of snd_soc_register_component().
- Use devm_snd_soc_register_card() instead of devm_snd_soc_register_card().
- Adjust the code sentences sequence.
- Make the namespacing consistent.
- Rename CONFIG_SND_SOC_FSL_SGTL5000 to CONFIG_SND_SOC_FSL_SGTL5000_VF610.
- Drop some meaningless lines.
- Rename the binding document file.

Added in v1:
- Add SAI SoC Digital Audio Interface driver.
- Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610.
- Enables SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
- Add device tree bindings for Freescale SAI.
- Revise the bugs about the sgt15000 codec.
- Add SGT15000 based audio machine driver.
- Enable SGT15000 codec based audio driver node for VF610.
- Add device tree bindings for Freescale VF610 sound.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2013-12-12  7:30 Loc Ho
  0 siblings, 0 replies; 409+ messages in thread
From: Loc Ho @ 2013-12-12  7:30 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for APM X-Gene SoC 15Gbps Multi-purpose PHY. This
is the physical layer interface for the corresponding host controller. This
driver uses the new PHY generic framework posted by Kishon Vijay Abrahm.
In addition, the new PHY generic framework is patched to provide an
function to set the speed of the PHY.

v4
* Update documentation with 'apm,' instead 'apm-'
* Change DTS override parameter to have 'apm,'
* Add select GENERIC_PHY to Kconfig PHY_XGENE
* Make override parameters to be pair of three values instead one
* Some minor comment and indentation changes
* Remove error register addition offset
* Add ULL to constants
* Use module_init instead subsys_initcall
* Make DTS node based on first register address
* Update override setting values

v3
* Major re-write of the code based on various review comments
* Support external clock only at the moment
* Support SATA mode only at the moment
* No UEFI support at the moment

v2
* Remove port knowledge from functions
* Make all functions static
* Remove ID completely
* Make resource requirement based on compatible type
* Rename override PHY parameters with more descriptive name
* Add override PHY parameter for per controller, per port, and per speed
* Patch the generic PHY frame to expose set_speed operation

v1
* Initial version

Signed-off-by: Loc Ho <lho@apm.com>
Signed-off-by: Tuan Phan <tphan@apm.com>
Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
Loc Ho (4):
  PHY: Add function set_speed to generic PHY framework
  Documentation: Add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
    binding documentation
  PHY: add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
  arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries

 .../devicetree/bindings/ata/apm-xgene-phy.txt      |   89 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |   31 +
 drivers/phy/Kconfig                                |    7 +
 drivers/phy/Makefile                               |    2 +
 drivers/phy/phy-core.c                             |   21 +
 drivers/phy/phy-xgene.c                            | 1854 ++++++++++++++++++++
 include/linux/phy/phy.h                            |    8 +
 7 files changed, 2012 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ata/apm-xgene-phy.txt
 create mode 100644 drivers/phy/phy-xgene.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-01-13 10:29 Lothar Waßmann
  0 siblings, 0 replies; 409+ messages in thread
From: Lothar Waßmann @ 2014-01-13 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds support for inverting the PWM output in hardware by
setting the POUTC bit in the PWMCR register. This feature is
controlled via the standard DT flas for PWMs.

The first patch does a minor source cleanup without any functional
change.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-01-13 10:32 Lothar Waßmann
  0 siblings, 0 replies; 409+ messages in thread
From: Lothar Waßmann @ 2014-01-13 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds support for the Ka-Ro electronics i.MX53 based
modules.
The first patch adds a new pingroup for NAND pads that is used by the
modules.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-01-16 16:09 Loc Ho
  0 siblings, 0 replies; 409+ messages in thread
From: Loc Ho @ 2014-01-16 16:09 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for APM X-Gene SoC 15Gbps Multi-purpose PHY. This
is the physical layer interface for the corresponding host controller. This
driver uses the new PHY generic framework posted by Kishon Vijay Abrahm.
In addition, the new PHY generic framework is patched to provide an
function to set the speed of the PHY.

v8
* Update binding documentation
* Remove XGENE_PHY_DTS and XGENE_PHY_EXT_DTS defines
* Remove support for internal clock
* Remove support for external reference CMU
* Remove the need for external reference resource DTS entry and its related
  code

v7
* Add/Update PHY CMU/lane parameters and its default values
* Rename variable enable_manual_cal to preA3Chip
* Remove function phy_rd, phy_wr, and phy_wr_flush
* Change function cmu_wr, cmu_rd, cmu_toggle1to0, cmu_clrbits, cmu_setbits,
  serdes_wr, serdes_rd, serdes_clrbits, and serdes_setbits to take context
  instead void *
* Remove function serdes_toggle1to0
* Decrease the polling time from 10ms to 1ms on CMU calibration complete
  detection
* Move all SATA specify code in function xgene_phy_hw_initialize into
  function xgene_phy_hw_init_sata
* Add usleep_range after starting summer/latch calibrations
* Add usleep_range between receiver reset (function xgene_phy_reset_rxd)
* Save and restore PHY register 31 instead writing 0 in function
  xgene_phy_gen_avg_val
* Update function xgene_phy_sata_force_gen programming sequences
* Add support to reset the receiver lane in function xgene_phy_set_speed
  if speed is 0
* Update PHY parameters in DTS per controller
* Some minor code clean up

v6
* Move PHY document to Documentation/devicetree/binding/phy
* Remove _ADDR from all register defines
* Update clock-names property for sataphy1clk, sataphy2clk, and sataphy3clk

v5
* Update DTS binding documentation
* Remove direct clock access and use clock interface instead
* Change override parameters to decimal instead hex values
* Change apm,tx-amplitude, apm,tx-pre-cursor1, apm,tx-pre-cursor2,
  apm,tx-post-cursor to be unit of uV

v4
* Update documentation with 'apm,' instead 'apm-'
* Change DTS override parameter to have 'apm,'
* Add select GENERIC_PHY to Kconfig PHY_XGENE
* Make override parameters to be pair of three values instead one
* Some minor comment and indentation changes
* Remove error register addition offset
* Add ULL to constants
* Use module_init instead subsys_initcall
* Make DTS node based on first register address
* Update override setting values

v3
* Major re-write of the code based on various review comments
* Support external clock only at the moment
* Support SATA mode only at the moment
* No UEFI support at the moment

v2
* Remove port knowledge from functions
* Make all functions static
* Remove ID completely
* Make resource requirement based on compatible type
* Rename override PHY parameters with more descriptive name
* Add override PHY parameter for per controller, per port, and per speed
* Patch the generic PHY frame to expose set_speed operation

v1
* Initial version

Signed-off-by: Loc Ho <lho@apm.com>
Signed-off-by: Tuan Phan <tphan@apm.com>
Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
Loc Ho (4):
  PHY: Add function set_speed to generic PHY framework
  Documentation: Add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
    binding documentation
  PHY: add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
  arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries

 .../devicetree/bindings/phy/apm-xgene-phy.txt      |   79 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |   75 +
 drivers/phy/Kconfig                                |    7 +
 drivers/phy/Makefile                               |    2 +
 drivers/phy/phy-core.c                             |   21 +
 drivers/phy/phy-xgene.c                            | 1793 ++++++++++++++++++++
 include/linux/phy/phy.h                            |    8 +
 7 files changed, 1985 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/apm-xgene-phy.txt
 create mode 100644 drivers/phy/phy-xgene.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-01-16 16:11 Loc Ho
  0 siblings, 0 replies; 409+ messages in thread
From: Loc Ho @ 2014-01-16 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for the APM X-Gene SoC SATA host controller. In
order for the host controller to work, the corresponding PHY driver
musts also be available.

v10:
 * Update binding documentation

v9:
 * Remove ACPI/EFI include files
 * Remove the IO flush support, interrupt routine, and DTS resources
 * Remove function xgene_rd, xgene_wr, and xgene_wr_flush
 * Remove PMP support (function xgene_ahci_qc_issue, xgene_ahci_qc_prep,
   xgene_ahci_qc_fill_rtf, xgene_ahci_softreset, and xgene_ahci_do_softreset)
 * Rename function xgene_ahci_enable_phy to xgene_ahci_force_phy_rdy
 * Clean up hardreset functions
 * Require v7 of the PHY driver

v8:
 * Remove _ADDR from defines
 * Remove define MSTAWAUX_COHERENT_BYPASS_SET and
   STARAUX_COHERENT_BYPASS_SET and use direct coding
 * Remove the un-necessary check for DTS boot with built in ACPI table
 * Switch to use dma_set_mask_and_coherent for setting DMA mask
 * Remove ACPI table matching code
 * Update clock-names for sata01clk, sata23clk, and sata45clk

v7:
 * Update the clock code by toggle the clock
 * Update the DTS clock mask values due to the clock spilt between host and
   v5 of the PHY drivers

v6:
 * Update binding documentation
 * Change select PHY_XGENE_SATA to PHY_XGENE
 * Add ULL to constants
 * Change indentation and comments
 * Clean up the probe functions a bit more
 * Remove xgene_ahci_remove function
 * Add the flush register to DTS
 * Remove the interrupt-parent from DTS

v5:
 * Sync up to v3 of the PHY driver
 * Remove MSLIM wrapper functions
 * Change the memory shutdown loop to use usleep_range
 * Use devm_ioremap_resource instead devm_ioremap
 * Remove suspend/resume functions as not needed

v4:
 * Remove the ID property in DT
 * Remove the temporary PHY direct function call and use PHY function
 * Change printk to pr_debug
 * Move the IOB flush addresses into the DT
 * Remove the parameters retrieval function as no longer needed
 * Remove the header file as no longer needed
 * Require v2 patch of the SATA PHY driver. Require slightly modification
   in the Kconfig as it is moved to folder driver/phy and use Kconfig
   PHY_XGENE_SATA instead SATA_XGENE_PHY.

v3:
 * Move out the SATA PHY to another driver
 * Remove the clock-cells entry from DTS
 * Remove debug wrapper
 * Remove delay functions wrapper
 * Clean up resource and IRQ query
 * Remove query clock name
 * Switch to use dma_set_mask/dma_coherent_mask
 * Remove un-necessary devm_kfree
 * Update GPL license header to v2
 * Spilt up function xgene_ahci_hardreset
 * Spilt up function xgene_ahci_probe
 * Remove all reference of CONFIG_ARCH_MSLIM
 * Clean up chip revision code

v2:
 * Clean up file sata_xgene.c with Lindent and etc
 * Clean up file sata_xgene_serdes.c with Lindent and etc
 * Add description to each patch

v1:
 * inital version

Signed-off-by: Loc Ho <lho@apm.com>
Signed-off-by: Tuan Phan <tphan@apm.com>
Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
Loc Ho (4):
  ata: Export required functions by APM X-Gene SATA driver
  Documentation: Add documentation for APM X-Gene SoC SATA host
    controller DTS binding
  ata: Add APM X-Gene SoC SATA host controller driver
  arm64: Add APM X-Gene SoC SATA host controller DTS entries

 .../devicetree/bindings/ata/apm-xgene.txt          |   70 +++
 arch/arm64/boot/dts/apm-storm.dtsi                 |   75 +++
 drivers/ata/Kconfig                                |    8 +
 drivers/ata/Makefile                               |    1 +
 drivers/ata/ahci.h                                 |    9 +
 drivers/ata/libahci.c                              |   16 +-
 drivers/ata/sata_xgene.c                           |  630 ++++++++++++++++++++
 7 files changed, 803 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ata/apm-xgene.txt
 create mode 100644 drivers/ata/sata_xgene.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-01-21  4:09 John Tobias
  0 siblings, 0 replies; 409+ messages in thread
From: John Tobias @ 2014-01-21  4:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Guys,

Just wondering if you encountered the error below and if there's any
existing patch?.

Regards,

john



[  860.354231] Unable to handle kernel paging request at virtual
address eaffff9d
[  860.361466] pgd = bf190000
[  860.364177] [eaffff9d] *pgd=00000000
[  860.367773] Internal error: Oops: 5 [#1] ARM
[  860.372048] Modules linked in: bt8xxx(O) sd8xxx(O) mlan(O)
[  860.377597] CPU: 0 PID: 82 Comm: ksdioirqd/mmc1 Tainted: G
 O 3.13.0-rc1 #1
[  860.385344] task: bf05c280 ti: bf01a000 task.ti: bf01a000
[  860.390756] PC is at mmc_io_rw_extended+0x38/0x310
[  860.395552] LR is at mmc_io_rw_extended+0x38/0x310
[  860.400346] pc : [<80319b68>]    lr : [<80319b68>]    psr: 400f0013
[  860.400346] sp : bf01bc90  ip : bf01bd60  fp : bf01bd8c
[  860.411824] r10: 806f9748  r9 : bf9e7800  r8 : eb075fb4
[  860.417051] r7 : eaffff9d  r6 : 80327c24  r5 : 1a000009  r4 : 00000007
[  860.423580] r3 : 00000000  r2 : ffffffc4  r1 : 00000000  r0 : bf01bd1c
[  860.430112] Flags: nZcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[  860.437423] Control: 10c53c7d  Table: bf190059  DAC: 00000015
[  860.443172] Process ksdioirqd/mmc1 (pid: 82, stack limit = 0xbf01a238)
[  860.449702] Stack: (0xbf01bc90 to 0xbf01c000)
[  860.454065] bc80:                                     80319e04
00000440 00000139 00000000
[  860.462246] bca0: 00000139 00000000 817de8c2 000000c0 00000700
beac60c0 3b9aca00 00000000
[  860.470427] bcc0: 00000100 00000007 00000000 00000200 00000700
00000000 bf01bd1c 00000001
[  860.478609] bce0: bf01bca8 00000000 00000035 1a001207 00002000
00000000 00000000 00000000
[  860.486790] bd00: 000001b5 00000000 00000000 00000000 00000000
bf01bcb8 bf01bd1c 00000000
[  860.494971] bd20: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[  860.503153] bd40: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[  860.511334] bd60: bf01bd94 bf01bd70 80324254 80327c24 bf01be04
bf9e7800 806f9748 b600003f
[  860.519515] bd80: bf01bdd4 bf01bd90 8031ade8 80319b3c bf01be04
80327c24 00000007 1a000009
[  860.527697] bda0: bf05c280 000001ff 00100100 bfb52000 00000100
00000007 beac60c0 00010009
[  860.535878] bdc0: 7f03e578 c0adb000 bf01bdec bf01bdd8 8031aef8
8031ad10 beac60c0 00000700
[  860.544059] bde0: bf01be14 bf01bdf0 7f08c2bc 8031aee0 00000000
00000009 00000700 7f03d328
[  860.552240] be00: bfad9a00 00000000 bf01be24 bf01be18 7f0622f0
7f08c278 bf01be6c bf01be28
[  860.560422] be20: 7f0137a8 7f0622ec bf01be44 bf01be38 8004efd4
00000001 bf01be5c 00000000
[  860.568603] be40: 804fc960 c0adb000 c0adbce4 7f03d328 00000000
7f03e578 7f061dec bfb52000
[  860.576784] be60: bf01beac bf01be70 7f001e68 7f0134f8 00000000
00000000 00000000 00000000
[  860.584965] be80: 00000000 bfb52000 7f09a0d4 bfb51800 00000000
bf9e7800 bf01a000 00000001
[  860.593146] bea0: bf01bec4 bf01beb0 7f05a138 7f001ce0 00000001
00000000 bf01bed4 bf01bec8
[  860.601327] bec0: 7f08bfe4 7f05a0cc bf01bf24 bf01bed8 8031ba0c
7f08bfc4 00000000 bf01bef3
[  860.609509] bee0: bfb51800 00000001 bf9e7bb4 7fffffff 0215d9c0
00000001 8031b874 00000000
[  860.617690] bf00: bf15d9c0 bf9e7800 8031b874 00000000 00000000
00000000 bf01bfac bf01bf28
[  860.625871] bf20: 8003c7e8 8031b880 bf01bf44 00000000 8004efd4
bf9e7800 00000000 00000001
[  860.634052] bf40: dead4ead ffffffff ffffffff 80702208 00000000
00000000 80600be8 bf01bf5c
[  860.642233] bf60: bf01bf5c 00000000 00000001 dead4ead ffffffff
ffffffff 80702208 00000000
[  860.650415] bf80: 00000000 80600be8 bf01bf88 bf01bf88 bf15d9c0
8003c724 00000000 00000000
[  860.658595] bfa0: 00000000 bf01bfb0 8000f308 8003c730 00000000
00000000 00000000 00000000
[  860.666776] bfc0: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[  860.674956] bfe0: 00000000 00000000 00000000 00000000 00000013
00000000 00000000 00000000
[  860.683133] Backtrace:
[  860.685607] [<80319b30>] (mmc_io_rw_extended+0x0/0x310) from
[<8031ade8>] (sdio_io_rw_ext_helper+0xe4/0x1a4)
[  860.695442] [<8031ad04>] (sdio_io_rw_ext_helper+0x0/0x1a4) from
[<8031aef8>] (sdio_readsb+0x24/0x2c)
[  860.704676] [<8031aed4>] (sdio_readsb+0x0/0x2c) from [<7f08c2bc>]
(woal_read_data_sync+0x50/0x8c [sd8xxx])
[  860.714455] [<7f08c26c>] (woal_read_data_sync+0x0/0x8c [sd8xxx])
from [<7f0622f0>] (moal_read_data_sync+0x10/0x14 [sd8xxx])
[  860.725586]  r8:00000000 r7:bfad9a00 r6:7f03d328 r5:00000700 r4:00000009
r3:00000000
[  860.733603] [<7f0622e0>] (moal_read_data_sync+0x0/0x14 [sd8xxx])
from [<7f0137a8>] (wlan_process_int_status+0x2bc/0x928 [mlan])
[  860.745139] [<7f0134ec>] (wlan_process_int_status+0x0/0x928 [mlan])
from [<7f001e68>] (mlan_main_process+0x194/0x750 [mlan])
[  860.756436] [<7f001cd4>] (mlan_main_process+0x0/0x750 [mlan]) from
[<7f05a138>] (woal_interrupt+0x78/0x94 [sd8xxx])
[  860.766982] [<7f05a0c0>] (woal_interrupt+0x0/0x94 [sd8xxx]) from
[<7f08bfe4>] (woal_sdio_interrupt+0x2c/0x30 [sd8xxx])
[  860.777677]  r5:00000000 r4:00000001
[  860.781351] [<7f08bfb8>] (woal_sdio_interrupt+0x0/0x30 [sd8xxx])
from [<8031ba0c>] (sdio_irq_thread+0x198/0x368)
[  860.791537] [<8031b874>] (sdio_irq_thread+0x0/0x368) from
[<8003c7e8>] (kthread+0xc4/0xe0)
[  860.799814] [<8003c724>] (kthread+0x0/0xe0) from [<8000f308>]
(ret_from_fork+0x14/0x2c)
[  860.807818]  r7:00000000 r6:00000000 r5:8003c724 r4:bf15d9c0
[  860.813538] Code: e1a09003 e59b400c e59b5010 ebfc3a75 (e5973000)
[  860.819646] ---[ end trace 1920724507aeb8b4 ]---
[  860.824270] Kernel panic - not syncing: Fatal exception

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-02-22 15:53 Hans de Goede
  0 siblings, 0 replies; 409+ messages in thread
From: Hans de Goede @ 2014-02-22 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Here is v7 of my patchset for adding ahci-sunxi support. This is hopefully
the final final version of this set :)

Note I'm going on vacation for a week starting Monday, so if I'm not responding
that is why. Tejun if you feel some small cleanups are still necessary and
you don't want to wait for me to get back feel free to squash in any cleanups
you deem necessary.

This has been tested with Allwinner A10, Allwinner A20 and Freeware imx6x SoCs,
including suspend / resume. Note that the ahci_imx driver now also has imx53
sata support, it would be good if someone could test that with this series.


History:

v1, by Olliver Schinagl:
This was using the approach of having a platform device which probe method
creates a new child platform device which gets driven by ahci_platform.c,
as done by ahci_imx.c .

v2, by Hans de Goede:
Stand-alone platform driver based on Olliver's work

v3, by Hans de Goede:
patch-series, with 4 different parts
a) Make ahci_platform.c more generic, handle more then 1 clk, target pwr
   regulator
b) New ahci-sunxi code only populating ahci_platform_data, passed to
   ahci_platform.c to of_device_id matching.
c) Refactor ahci-imx code to work the same as the new ahci-sunxi code, this
   is the reason why v3 is an RFC, I'm waiting for the wandboard I ordered to
   arrive so that I can actually test this.
d) dts bindings for the sunxi ahci parts

v4, by Hans de Goede:
patch-series, with 5 different parts:
a) Make ahci_platform.c more generic, handle more then 1 clk, target pwr
   regulator
b) Turn parts of ahci_platform.c into a library for use by other drivers
c) New ahci-sunxi driver using the ahci_platform.c library functionality
d) Refactor ahci-imx code to work the same as the new ahci-sunxi code
e) dts bindings for the sunxi ahci parts

v5:
v4 + the following changes:
1) fsl,imx6q driver is now tested
2) fixed suspend / resume on fsl,imx6q
3) Modifed devicetree node naming to match dt spec
4) Reworked the busy waiting code in the sunxi-phy handling as suggested by
   Russell King

v6:
v5 rebased on top of 3.14-rc3 + the following changes
1) Added Roger Quadros' generic phy support series
2) Added a "ARM: sun4i: dt: Remove grouping + simple-bus for regulators" dts
   patch

v7:
v6 + the following changes:
1) Addressed all Tejun's review remarks:
  * Added function header comments to all exported ahci_platform functions
  * Added comments in some other places
  * Removed use of 2 empty lines to separate functions in some cases
  * Use devres to automatically call ahci_platform_put_resources on
    get_resource failure, probe failure and regular device remove
2) Dropped patches to move ahci_host_priv struct declaration to include/linux,
  this was a left-over from v3 and is no longer necessary
3) Updated Roger's "ata: ahci_platform: Manage SATA PHY" patch:
  * Update function header comments for the changes this makes
  * Drop the Kconfig PHY requires hack, my patch for the phy-core to always be
    built-in has been queued in Greg KH's tree, so this is no longer necessary.
4) Dropped Roger's "ata: ahci_platform: Add 'struct device' argument to ahci_platform_put_resources()"
  patch, ahci_platform_put_resources already has a device argument as result
  of it being changed into a devres release function

Tejun, can you please add patches 1-12 to your ata tree for 3.15 ?

Maxime, can you please add patch 13-15 to your dts tree for 3.15 ?

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-04-21  2:59 Amber Thrall
  0 siblings, 0 replies; 409+ messages in thread
From: Amber Thrall @ 2014-04-21  2:59 UTC (permalink / raw)
  To: kernelnewbies

I recently built and installed kernel version 3.15.0-rc1 following the
KernelBuild article on kernelnewbies.org.  Everything went smooth and my
system is running fine.  However when performing an update via (sudo yum
update) the dependencies failed requiring
"kernel-devel-uname-r=3.13.10".  uname-r returns "3.15.0-rc1" as
expected.

Is there a way to get yum to recognize the latest kernel I built?  Or
does that require updating the kernel's source RPM?

I'm running Fedora 20 and am new to kernel building.  Yum's error
message is included below:

Error: Package:
10:buildsys-build-rpmfusion-kerneldevpkgs-current-20-19.x86_64
(rpmfusion-free-updates)
           Requires: kernel-devel-uname-r = 3.13.10-200.fc20.x86_64
           Installed: kernel-devel-3.11.10-301.fc20.x86_64 (@anaconda)
               kernel-devel-uname-r = 3.11.10-301.fc20.x86_64
           Installed: kernel-devel-3.13.9-200.fc20.x86_64 (@updates)
               kernel-devel-uname-r = 3.13.9-200.fc20.x86_64
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-05-12  4:37 Sivakumar V
  0 siblings, 0 replies; 409+ messages in thread
From: Sivakumar V @ 2014-05-12  4:37 UTC (permalink / raw)
  To: kernelnewbies

Hi All,

    I am tried to compile and install (network file system)nfs module to
kernel i.e. modified nfs code(inserted printk's in kernel nfs code) without
compiling entire kernel .
It is inserted but when configuring nfs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140512/d8b76c77/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-05-12 16:38 Santosh Shilimkar
  0 siblings, 0 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2014-05-12 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

>From 14f3791439b5a6cf12127fb80204265533d92664 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Mon, 12 May 2014 12:28:23 -0400
Subject: [GIT PULL 1/2] ARM: Keystone SOC updates for 3.16

Hi Arm-soc folks,

Please pull below keystone SOC updates for 3.16. It merges cleanly with
arm-soc 'next/soc' head. As already discussed, the $subject pull request
has a depedency with DT dma-properties pull request [1] I sent last week
to be pulled into arm-soc.

The following changes since commit c9eaa447e77efe77b7fa4c953bd62de8297fd6c5:

  Linux 3.15-rc1 (2014-04-13 14:18:35 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-soc

for you to fetch changes up to 14f3791439b5a6cf12127fb80204265533d92664:

  ARM: keystone: Update the dma offset for non-dt platform devices (2014-05-08 15:43:33 -0400)

----------------------------------------------------------------
Keystone SOC updates for 3.16

- Drop unused COMMON_CLK_DEBUG option
- Enable MTD_SPI_NOR config needed for M25P80
- Enable coherent higher address memory space

----------------------------------------------------------------
Brian Norris (1):
      ARM: configs: keystone: add MTD_SPI_NOR (new dependency for M25P80)

Lad Prabhakar (1):
      ARM: configs: keystone: drop CONFIG_COMMON_CLK_DEBUG

Santosh Shilimkar (2):
      ARM: keystone: Switch over to coherent memory address space
      ARM: keystone: Update the dma offset for non-dt platform devices

 arch/arm/configs/integrator_defconfig   |    1 -
 arch/arm/configs/keystone_defconfig     |    2 +-
 arch/arm/configs/sunxi_defconfig        |    1 -
 arch/arm/configs/vt8500_v6_v7_defconfig |    1 -
 arch/arm/mach-keystone/keystone.c       |   74 +++++++++++++++++++++++++++++++
 arch/arm/mach-keystone/memory.h         |   24 ++++++++++
 arch/arm/mach-keystone/platsmp.c        |   18 +++++++-
 7 files changed, 116 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-keystone/memory.h

Regards,
Santosh

[1] https://lkml.org/lkml/2014/5/7/368

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-05-12 16:40 Santosh Shilimkar
  0 siblings, 0 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2014-05-12 16:40 UTC (permalink / raw)
  To: linux-arm-kernel

>From 14f3791439b5a6cf12127fb80204265533d92664 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Mon, 12 May 2014 12:28:23 -0400
Subject: [GIT PULL 1/2] ARM: Keystone SOC updates for 3.16

Hi Arm-soc folks,

Please pull below keystone SOC updates for 3.16. It merges cleanly with
arm-soc 'next/soc' head. As already discussed, the $subject pull request
has a depedency with DT dma-properties pull request [1] I sent last week
to be pulled into arm-soc.

The following changes since commit c9eaa447e77efe77b7fa4c953bd62de8297fd6c5:

  Linux 3.15-rc1 (2014-04-13 14:18:35 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-soc

for you to fetch changes up to 14f3791439b5a6cf12127fb80204265533d92664:

  ARM: keystone: Update the dma offset for non-dt platform devices (2014-05-08 15:43:33 -0400)

----------------------------------------------------------------
Keystone SOC updates for 3.16

- Drop unused COMMON_CLK_DEBUG option
- Enable MTD_SPI_NOR config needed for M25P80
- Enable coherent higher address memory space

----------------------------------------------------------------
Brian Norris (1):
      ARM: configs: keystone: add MTD_SPI_NOR (new dependency for M25P80)

Lad Prabhakar (1):
      ARM: configs: keystone: drop CONFIG_COMMON_CLK_DEBUG

Santosh Shilimkar (2):
      ARM: keystone: Switch over to coherent memory address space
      ARM: keystone: Update the dma offset for non-dt platform devices

 arch/arm/configs/integrator_defconfig   |    1 -
 arch/arm/configs/keystone_defconfig     |    2 +-
 arch/arm/configs/sunxi_defconfig        |    1 -
 arch/arm/configs/vt8500_v6_v7_defconfig |    1 -
 arch/arm/mach-keystone/keystone.c       |   74 +++++++++++++++++++++++++++++++
 arch/arm/mach-keystone/memory.h         |   24 ++++++++++
 arch/arm/mach-keystone/platsmp.c        |   18 +++++++-
 7 files changed, 116 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-keystone/memory.h

Regards,
Santosh

[1] https://lkml.org/lkml/2014/5/7/368

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-05-24  1:21 Loc Ho
  0 siblings, 0 replies; 409+ messages in thread
From: Loc Ho @ 2014-05-24  1:21 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for the APM X-Gene SoC EDAC driver.

v2:
* Add EDAC entry in MAINTAINERS for APM EDAC driver
* Remove the MC scrub patch
* Remove the word 'Caches' from Kconfig
* Change all MASK defines to use BIT(x)
* Update comment or remove them
* Wrap error injection code around CONFIG_EDAC_DEBUG
* Change function name xgene_edac_mc_hw_init to xgene_edac_mc_irq_ctl
* Change all function XXX_hw_init to XXX_hw_ctl
* Fix typo 'activie'
* Move calling function edac_mc_alloc after resource retrieval
* Check for NULL on platform_get_resource return if reference directly
* Add documentation for struct xgene_edac_pmd_ctx
* Move L1 and L2 check out of function xgene_edac_pmd_check to its own
  functions
* Use for loop for configure each CPU of an PMD
* Replace /2 by >> 1
* Remove unnecessary comment on edac_device_add_device failure
* Make mem_err_ip static const
* Unwind EDAC register correctly if failed
---
Loc Ho (4):
  MAINTAINERS: Add entry for APM X-Gene SoC EDAC driver
  Documentation: Add documentation for the APM X-Gene SoC EDAC DTS
    binding
  edac: Add APM X-Gene SoC EDAC driver
  arm64: Add APM X-Gene SoC EDAC DTS entries

 .../devicetree/bindings/edac/apm-xgene-edac.txt    |   70 +
 MAINTAINERS                                        |    8 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |   89 +
 drivers/edac/Kconfig                               |    9 +-
 drivers/edac/Makefile                              |    3 +
 drivers/edac/xgene_edac.c                          | 1993 ++++++++++++++++++++
 6 files changed, 2171 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
 create mode 100644 drivers/edac/xgene_edac.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-07-09 17:49 Sebastian Andrzej Siewior
  0 siblings, 0 replies; 409+ messages in thread
From: Sebastian Andrzej Siewior @ 2014-07-09 17:49 UTC (permalink / raw)
  To: linux-arm-kernel

This is version three of the patch set. Unless something serious comes up
I would drop the RFC on the next post.

So far I should have everything covered up comparing to the omap-serial
driver except for the throttle callbacks. And now I would slowly start
looking into DMA support?

Sebastian

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-08-29 14:22 Ravi Raj
  2014-08-29 14:47 ` Valdis.Kletnieks at vt.edu
  0 siblings, 1 reply; 409+ messages in thread
From: Ravi Raj @ 2014-08-29 14:22 UTC (permalink / raw)
  To: kernelnewbies

Hii Guys,
               I am an Embedded firmware Developer,I am looking for a
Development board to port the linux kernal from scratch, could you guys
please recommend me a good development board were i can port linux from
scratch.











Cheers,
Ravi.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140829/37cc0503/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2014-08-29 14:58   ` Ravi Raj
@ 2014-08-29 15:32     ` Valdis.Kletnieks at vt.edu
  2014-08-29 15:34     ` Valdis.Kletnieks at vt.edu
  1 sibling, 0 replies; 409+ messages in thread
From: Valdis.Kletnieks at vt.edu @ 2014-08-29 15:32 UTC (permalink / raw)
  To: kernelnewbies

On Fri, 29 Aug 2014 16:58:26 +0200, Ravi Raj said:
> so first step is to find an imx6 Arm a9 board and port linux to it

Why not get an imx6 board that already *HAS* Linux for it?

Heck, Freescale will even give you a one day CLASS on it:

http://cache.freescale.com/files/training/doc/dwf/DWF_LINUX_LABWORKBOOK.pdf

(Did you bother trying to google 'imx6 arm a9 linux'? Lots of hits, lots
of providers. ;)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 848 bytes
Desc: not available
Url : http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140829/d797759c/attachment.bin 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2014-08-29 14:58   ` Ravi Raj
  2014-08-29 15:32     ` No subject Valdis.Kletnieks at vt.edu
@ 2014-08-29 15:34     ` Valdis.Kletnieks at vt.edu
  1 sibling, 0 replies; 409+ messages in thread
From: Valdis.Kletnieks at vt.edu @ 2014-08-29 15:34 UTC (permalink / raw)
  To: kernelnewbies

On Fri, 29 Aug 2014 16:58:26 +0200, Ravi Raj said:
>                   Thank you for the response ,So the project is a
> communication between fpga and a imx6 Arm A9 processor using SPI protocol
> and we are making a custom board for this, so first step is to find an imx6
> Arm a9 board and port linux to it and then establish SPI.

Heck, these guys already have ANdroid Kitkat up and running:

http://www.wandboard.org/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 848 bytes
Desc: not available
Url : http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140829/3da056d6/attachment.bin 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-13 19:40 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2014-09-13 19:40 UTC (permalink / raw)
  To: ath9k-devel

apply patches to the ath.git tree as before and handle the patches from
there.

For ath9k and wil6210 the change is that I will be commiting the patches
instead of John and I will apply them to my wireless-drivers trees:

https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers.git/

https://git.kernel.org/cgit/linux/kernel/git/kvalo/wireless-drivers-next.git/

For ath10k and ath6kl related work I will continue to use my QCA email
address but for wireless-drivers maintainer duties I will use CAF
address.

Please let me know if there any questions. Me and John try to make this
transition as smooth as possible.

Kalle

"John W. Linville" <linville@tuxdriver.com> writes:

> Greetings,
>
> Almost 9 years ago, Jeff Garzik wrote a message on LKML detailing
> the sad state of wireless LANs in the Linux world.  The point of his
> message was "So... there it is.  We suck.  There's hope.  No Luke
> Skywalker in sight.":
>
> 	https://lkml.org/lkml/2006/1/5/671
>
> Shortly thereafter, I became the maintainer for wireless LANs in the
> Linux kernel:
>
> 	https://lkml.org/lkml/2006/1/18/377
>
> Since then, we have had a number of wireless summit meetings all around
> the world.  Items were discussed, patches were merged, and friendships
> were made.  Over time, we garnered support from a large range of
> wireless networking vendors.  Eventually even other technologies
> were sending their patches through my trees, and I was consistently
> ranked amongst the top 10 "gate keepers" for getting changes into the
> Linux kernel.  In fact, a couple of years ago I even gave a talk on
> how Linux wireless got better.	It has been quite a ride!
>
> 	https://events.linuxfoundation.org/images/stories/pdf/lfcs2012_linville.pdf
>
> Nevertheless, I think it is time for some changes.  I have been
> the wireless maintainer for a long time, and I personally would
> like to develop in a different direction.  Plus, I think that Linux
> will benefit from having some fresh blood involved in more of the
> maintenance duties.  I will be stepping aside to let that happen.
>
> The mac80211, bluetooth, and nfc trees have fed through me for some
> time.  I am now asking these trees to send pull request directly to
> David Miller.  Since these trees are managed through git, my hope is
> that they will not place any significant burden on Dave.
>
> As for the wireless driver patches, I have asked Kalle Valo
> to handle patch review and merge duties for everything under the
> drivers/net/wireless directory.  This will now include not only the ath
> patches he already manages, but other drivers that don't have trees
> such as mwifiex, rt2x00, rtlwifi, and others.  For consistency, the
> iwlwifi tree will also be merged through Kalle's new tree.  I expect
> that Kalle will announce any relevant details in a follow-up message.
>
> The wireless-testing tree is a resource that some people value.
> I will continue to provide a wireless-testing tree.  Now that tree
> will feed from the various wireless trees managed by others, probably
> with some sort of regularly scheduled pulls.  Details are still to be
> determined, but the tree will still exist and will be substantially
> similar to how it has been so far.
>
> I also receive notices of new bug reports for wireless LANs on
> bugzilla.kernel.org.  For now I will continue to triage those reports,
> so don't ignore me!! :-)
>
> Some may ask what I will do now -- I wish I had a specific answer.
> Immediate plans are to enjoy the coming holidays and my traditional
> year-end time away from work.  After that...well, I'm sure I will
> find something to do.  If you have any suggestions for good uses of
> my talents, feel free to contact me -- I'm not hard to find!
>
> In closing, I hope everyone will support Kalle and the other wireless
> maintainers at least as much as you have supported me for the past
> several years.	These are good, hard working folks.  You are in
> good hands!
>
> Regards,
>
> John
>
> P.S.  Bonus points for anyone that finds a way for me to become a
> professional retro-computing hobbyist... :-)

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-13 19:40 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2014-09-13 19:40 UTC (permalink / raw)
  To: ath9k-devel

phyXtpt to blink like what it does.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
Hong<br>
</font></span></blockquote></div><br><br clear=3D"all"><br>-- <br><div clas=
s=3D"gmail_signature">Met vriendelijk groeten,<br>Melroy van den Berg</div>
</div>

--001a113801d2d4fad5050c853d75--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-13 19:40 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2014-09-13 19:40 UTC (permalink / raw)
  To: ath9k-devel

It doesn't appear to be present in the kernel and I don't think
ath3k would be loaded.

I have a patch to add this ID to ath3k, can you apply it in
backports-20141221 and check ?

http://msujith.org/dir/patches/wl/Jan-14-2015/0013-ath3k-Add-new-AR3012-device.patch

Inside backports:

patch -p1 < 0013-ath3k-Add-new-AR3012-device.patch

And then, do a "make menuconfig" to select ath9k/ath3k
and install.

Sujith

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-13 19:40 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2014-09-13 19:40 UTC (permalink / raw)
  To: ath9k-devel

I think WOW-enabled cards require hardware changes from the
base reference design (in your case WB222/AR9462), to receive
power when suspended.

Sujith

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-13 19:40 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2014-09-13 19:40 UTC (permalink / raw)
  To: ath9k-devel

but how does the device decide to wake up?  Is it based on local TSF and
beacon interval being programmed in somewhere?  Or do you give it an arbitrary
TSF wake-up time somehow as in the previous devices?  I noticed that in ath9k
the various generic timer aliases (e.g. TIM_TIMER) aren't even supported in
ar9003_mac.c.

-- 
Bob Copeland %% http://bobcopeland.com/

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-22  7:45 Jingchang Lu
  0 siblings, 0 replies; 409+ messages in thread
From: Jingchang Lu @ 2014-09-22  7:45 UTC (permalink / raw)
  To: linux-arm-kernel

This series contain the support for Freescale LS1021A CPU and LS1021A-QDS
and LS1021A-TWR board.

The LS1021A SoC combines two ARM Cortex-A7 cores that have been optimized
for high reliability and pack the highest level of integration available
for sub-3W embedded communications processors and with a comprehensive
enablement model focused on ease of programmability.

The LS1021A SoC shares IPs with i.MX family, Vybrid family and Freescale
PowerPC platform. 

For the detail information about LS1021A SoC, please refer to the RM doc.

---
changes in v4:
add "syscon" compatible to device tree scfg and dcfg node, and 
remove uncompleted dcsr related node.
remove mxc_restart reference in DT_MACHINE_START.
remove dma_zone_size defination in DT_MACHINE_START.

changes in v3:
rewrite scfg and dcfg binding doc description.
remove sai related node leaving to the driver support.

changes in v2:
remove unused nodes.
wakeup the secondary core by IPI call to u-boot standby procedure. 
add dt-bindings for LS1021A SoC and platform gerenal configuration nodes.

----------------------------------------------------------------
Jingchang Lu (6):
	ARM: dts: Add SoC level device tree support for LS1021A
	ARM: dts: Add initial LS1021A QDS board dts support
	ARM: dts: Add initial LS1021A TWR board dts support
	dt-bindings: arm: add Freescale LS1021A SoC device tree binding
	ARM: imx: Add initial support for Freescale LS1021A
	ARM: imx: Add Freescale LS1021A SMP support

 Documentation/devicetree/bindings/arm/fsl.txt |  38 ++++
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/ls1021a-qds.dts             | 285 ++++++++++++++++++++++++++
 arch/arm/boot/dts/ls1021a-twr.dts             | 117 +++++++++++
 arch/arm/boot/dts/ls1021a.dtsi                | 539 ++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/Kconfig                     |  14 ++
 arch/arm/mach-imx/Makefile                    |   4 +-
 arch/arm/mach-imx/common.h                    |   1 +
 arch/arm/mach-imx/mach-ls1021a.c              |  22 +++
 arch/arm/mach-imx/platsmp.c                   |  32 +++
 10 files changed, 1053 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/ls1021a-qds.dts
 create mode 100755 arch/arm/boot/dts/ls1021a-twr.dts
 create mode 100644 arch/arm/boot/dts/ls1021a.dtsi
 create mode 100644 arch/arm/mach-imx/mach-ls1021a.c

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-09-22 19:41 Santosh Shilimkar
  0 siblings, 0 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2014-09-22 19:41 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [GIT PULL] ARM: dts: Keystone DTS updates for 3.18

Hi Arm-soc folks,

The following changes since commit 7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9:

  Linux 3.17-rc1 (2014-08-16 10:40:26 -0600)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-dts

for you to fetch changes up to b2ed7d98e1c7098f452cf95ab69211a2f8e02ac8:

  ARM: dts: keystone: fix bindings for pcie and usb clock nodes (2014-09-22 15:19:36 -0400)

----------------------------------------------------------------
Keystone DTS updates for v3.18

- Add IRQ and GPIO nodes
- Fix SPI chip select
- Fix usb and pcie clock nodes

----------------------------------------------------------------
Grygorii Strashko (2):
      ARM: dts: keystone: add keystone irq controller node
      ARM: dts: keystone: add dsp gpio controllers nodes

Karicheri Muralidharan (1):
      ARM: dts: keystone: k2l: Fix chip selects for SPI devices

Karicheri, Muralidharan (1):
      ARM: dts: keystone: fix bindings for pcie and usb clock nodes

 arch/arm/boot/dts/k2e-clocks.dtsi |    6 ++--
 arch/arm/boot/dts/k2e.dtsi        |    7 +++++
 arch/arm/boot/dts/k2hk.dtsi       |   56 +++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/k2l.dtsi        |   42 ++++++++++++++++++++++++++++
 arch/arm/boot/dts/keystone.dtsi   |    8 ++++++
 5 files changed, 116 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-10-28 14:13 Mark Rutland
  0 siblings, 0 replies; 409+ messages in thread
From: Mark Rutland @ 2014-10-28 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

Bcc:
Subject: Re: [PATCHv4 7/7] arm64: add better page protections to arm64
Reply-To:
In-Reply-To: <1414440752-9411-8-git-send-email-lauraa@codeaurora.org>

Hi Laura,

On Mon, Oct 27, 2014 at 08:12:32PM +0000, Laura Abbott wrote:
> Add page protections for arm64 similar to those in arm.
> This is for security reasons to prevent certain classes
> of exploits. The current method:
>
> - Map all memory as either RWX or RW. We round to the nearest
>   section to avoid creating page tables before everything is mapped
> - Once everything is mapped, if either end of the RWX section should
>   not be X, we split the PMD and remap as necessary
> - When initmem is to be freed, we change the permissions back to
>   RW (using stop machine if necessary to flush the TLB)
> - If CONFIG_DEBUG_RODATA is set, the read only sections are set
>   read only.
>
> Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
> ---
> v4: Combined the Kconfig options
> ---
>  arch/arm64/Kconfig.debug            |  23 +++
>  arch/arm64/include/asm/cacheflush.h |   4 +
>  arch/arm64/kernel/vmlinux.lds.S     |  17 ++
>  arch/arm64/mm/init.c                |   1 +
>  arch/arm64/mm/mm.h                  |   2 +
>  arch/arm64/mm/mmu.c                 | 303 +++++++++++++++++++++++++++++++-----
>  6 files changed, 314 insertions(+), 36 deletions(-)

With this patch applied to v3.18-rc2, my board to blows up at boot when
using UEFI (without DEBUG_RODATA selected):

---->8----
EFI stub: Booting Linux Kernel...
Initializing cgroup subsys cpu
Linux version 3.18.0-rc2+ (mark at leverpostej) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #112 SMP PREEMPT Tue Oct 28 13:58:41 GMT 2014
CPU: AArch64 Processor [410fd030] revision 0
Detected VIPT I-cache on CPU0
bootconsole [uart0] enabled
efi: Getting EFI parameters from FDT:
EFI v2.40 by ARM Juno EFI Oct  7 2014 15:05:42
efi:  ACPI=0xfebdc000  ACPI 2.0=0xfebdc014
cma: Reserved 16 MiB at fd800000
BUG: failure at arch/arm64/mm/mmu.c:234/alloc_init_pmd()!
Kernel panic - not syncing: BUG!
CPU: 0 PID: 0 Comm: swapper Not tainted 3.18.0-rc2+ #112
Call trace:
[<ffffffc000087ec8>] dump_backtrace+0x0/0x124
[<ffffffc000087ffc>] show_stack+0x10/0x1c
[<ffffffc0004ebd58>] dump_stack+0x74/0xb8
[<ffffffc0004eb018>] panic+0xe0/0x220
[<ffffffc0004e8e08>] alloc_init_pmd+0x1cc/0x1dc
[<ffffffc0004e8e3c>] alloc_init_pud+0x24/0x6c
[<ffffffc0004e8f54>] __create_mapping+0xd0/0xf0
[<ffffffc00069a0a0>] create_id_mapping+0x5c/0x68
[<ffffffc00069964c>] efi_idmap_init+0x54/0xd8
[<ffffffc0006978a8>] setup_arch+0x408/0x5c0
[<ffffffc00069566c>] start_kernel+0x94/0x3a0
---[ end Kernel panic - not syncing: BUG!
---->8----

I've not yet figured out precisely why. I haven't tried a !EFI boot
because of the way my board is set up at the moment.

Mark.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-11-10  3:11 Libo Chen
  0 siblings, 0 replies; 409+ messages in thread
From: Libo Chen @ 2014-11-10  3:11 UTC (permalink / raw)




^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2014-11-10  6:39 Libo Chen
  0 siblings, 0 replies; 409+ messages in thread
From: Libo Chen @ 2014-11-10  6:39 UTC (permalink / raw)




^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-01-27 16:49 Grzegorz Dwornicki
  0 siblings, 0 replies; 409+ messages in thread
From: Grzegorz Dwornicki @ 2015-01-27 16:49 UTC (permalink / raw)
  To: kernelnewbies

Keepalive question

Hello

I am bothered with very simple situaction. Lets say we have a TCP connection:

S1 <----> S2

Lets assume that this connection is using blocking sockets. and that
both hosts: s1 and s2 are using SO_KEEPALIVE. If they both are not
using this connection then the kernel? is sending packets with no data
to keep connection alive.

I have marked "the kernel?" because I am not sure who does this. I
think its the kernel but I am not sure.

What would happen if only one of them would use keepalive? Could that
empty packet break the loop inside of sk_busy_loop function and return
empty data to the application layer? Or would that while loop body
just re-run?

Hehe is the code (the while loop starts on 128 line)
http://lxr.oss.org.cn/source/include/net/busy_poll.h?a=arm#L95

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-02-18 16:14 Lee Jones
  0 siblings, 0 replies; 409+ messages in thread
From: Lee Jones @ 2015-02-18 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH v2 0/4] clk: st: New clock domain

v1 => v2:
  - Turned the ST specific driver into a generic one 

Hardware can have a bunch of clocks which must not be turned off.
If drivers a) fail to obtain a reference to any of these or b) give
up a previously obtained reference during suspend, the common clk
framework will attempt to turn them off and the hardware will
subsequently die.  The only way to recover from this failure is to
restart.
 
To avoid either of these two scenarios from catastrophically
disabling the running system we have implemented a clock domain
where clocks are consumed and references are taken, thus preventing
them from being shut down by the framework.

Lee Jones (4):
  ARM: sti: stih407-family: Supply defines for CLOCKGEN A0
  ARM: sti: stih407-family: Provide Clock Domain information
  clk: Provide an always-on clock domain framework
  clk: dt: Introduce always-on clock domain documentation

 .../devicetree/bindings/clock/clk-domain.txt       | 35 ++++++++++++
 arch/arm/boot/dts/stih407-family.dtsi              | 13 +++++
 drivers/clk/Makefile                               |  1 +
 drivers/clk/clkdomain.c                            | 63 ++++++++++++++++++++++
 include/dt-bindings/clock/stih407-clks.h           |  4 ++
 5 files changed, 116 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/clk-domain.txt
 create mode 100644 drivers/clk/clkdomain.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-02-26 16:56 Jorge Ramirez-Ortiz
  0 siblings, 0 replies; 409+ messages in thread
From: Jorge Ramirez-Ortiz @ 2015-02-26 16:56 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Subject: [PATCH v5] drivers/tty: amba: defer probing DMA availability until hw_init
In-Reply-To: [PATCH v4] drivers/tty: amba: defer probing DMA availability until hw_init

checkpatch.pl didn't catch 'struct device * const uap_dev' 
resending 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-03-30  4:56 Woody Wu
  0 siblings, 0 replies; 409+ messages in thread
From: Woody Wu @ 2015-03-30  4:56 UTC (permalink / raw)
  To: kernelnewbies

Hi,

I have a kernel already run on production, but I then realized that I need
to add one or two driver to it.  But I hope I can avoid to upgrade the
kernel image for those already running products, I hope I can only extend
the kernel by add the driver modules to the root file system. Is that
possible? The current kernel has already compiled with the loadable modules
options, but for the drivers that I want now the old config is 'no'.

Thanks in advance.
-woody


-- 
Sent from Gmail Mobile
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150330/28819756/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-04-21 10:18 Ard Biesheuvel
  0 siblings, 0 replies; 409+ messages in thread
From: Ard Biesheuvel @ 2015-04-21 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 April 2015 at 12:13, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Apr 21, 2015 at 12:08:51PM +0200, Ard Biesheuvel wrote:
>> This updates the PROCINFO offset-to-setup-function fields of the
>> Thumb2 capable CPU definitions to include the Thumb bit when building
>> a Thumb2 kernel. This ensures that these function are always called
>> in the correct mode.
>
> I don't think this is necessary, in fact, I think this is positively
> regression causing.
>
> The symbol 'initfunc' is known to the assembler to be a thumb symbol.
> As we have seen already from the kernel dumps from the V7M kernel, when
> it calculates initfunc - name in a T2 kernel, the resulting value is an
> _odd_ number.
>

OK, so BSYM() uses '+ 1' rather than ' | 1'? I wasn't expecting that, sorry.

But looking at proc-v7.S again, the problem may just be the missing
ENDPROC() declarations for a couple of the setup() functions, which
explains why they are lacking the Thumb annotations.

> Using BSYM() here will increment it to be the next _even_ number, which
> is wrong as this will potentially point at either half way through a
> 32-bit T2 instruction, or the second 16-bit T2 instruction.
>

Agreed.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-05-18 20:00 raghu MG
  0 siblings, 0 replies; 409+ messages in thread
From: raghu MG @ 2015-05-18 20:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,
This mail is regarding Linux smp boot on ARMADA-XP MV2860
.

CPU-1 doesnt boot/go through the boot sequence & it fails to come
online & dumps this message

CPU1:failed to come online .

The CPU-1 boot register is programmed with physical address of
-->armada_xp_secondary_startup function & then cpu-0 deasserts the CPU-1.

I am using armada-xp-gp.dts with armada-xp-mv78260.dts included in it.

Any help would be appreciated.
Regards

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-07-15  9:32 Yuan Yao
  0 siblings, 0 replies; 409+ messages in thread
From: Yuan Yao @ 2015-07-15  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch has been tested on Fresscale LS-1 SOCs.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-07-22 14:05 Chunfeng Yun
  0 siblings, 0 replies; 409+ messages in thread
From: Chunfeng Yun @ 2015-07-22 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

>From ac1e8724bfa47494223bad0af450c1a63cd2fe0c Mon Sep 17 00:00:00 2001
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
Date: Wed, 22 Jul 2015 21:15:15 +0800
Subject: [PATCH 0/5] *** SUBJECT HERE ***

The patch supports MediaTek's xHCI controller.

There are some differences from xHCI spec:
1. The interval is specified in 250 * 8ns increments for Interrupt Moderation
Interval(IMODI) of the Interrupter Moderation(IMOD) register, it is 8 times as
much as that defined in xHCI spec.

2. For the value of TD Size in Normal TRB, MTK's xHCI controller defines a
number of packets that remain to be transferred for a TD after processing all
Max packets in all previous TRBs,that means don't include the current TRB's,
but in xHCI spec it includes the current ones.

3. To minimize the scheduling effort for synchronous endpoints in xHC, the MTK
architecture defines some extra SW scheduling parameters for HW. According to
these parameters provided by SW, the xHC can easily decide whether a
synchronous endpoint should be scheduled in a specific uFrame. The extra SW
scheduling parameters are put into reserved DWs in Slot and Endpoint Context.
And a bandwidth scheduler algorithm is added to support such feature.

A usb3.0 phy driver is also added which used by mt65xx SoCs platform, it
supports two usb2.0 ports and one usb3.0 port.

Change in v3:
1. implement generic phy
2. move opperations for IPPC and wakeup from phy driver to xHCI driver
3. seperate quirk functions into a single C file to fix up dependence issue

Chunfeng Yun (5):
  dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
  dt-bindings: Add a binding for Mediatek xHCI host controller
  usb: phy: add usb3.0 phy driver for mt65xx SoCs
  xhci: mediatek: support MTK xHCI host controller
  arm64: dts: mediatek: add xHCI & usb phy for mt8173

 .../devicetree/bindings/phy/phy-mt65xx-u3.txt      |  21 +
 .../devicetree/bindings/usb/mt8173-xhci.txt        |  50 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |  15 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  31 +
 drivers/phy/Kconfig                                |   9 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-mt65xx-usb3.c                      | 426 +++++++++++
 drivers/usb/host/Kconfig                           |   9 +
 drivers/usb/host/Makefile                          |   4 +
 drivers/usb/host/xhci-mtk-sch.c                    | 436 +++++++++++
 drivers/usb/host/xhci-mtk.c                        | 836 +++++++++++++++++++++
 drivers/usb/host/xhci-mtk.h                        | 135 ++++
 drivers/usb/host/xhci-ring.c                       |  35 +-
 drivers/usb/host/xhci.c                            |  19 +-
 drivers/usb/host/xhci.h                            |   1 +
 15 files changed, 2021 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-mt65xx-u3.txt
 create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
 create mode 100644 drivers/phy/phy-mt65xx-usb3.c
 create mode 100644 drivers/usb/host/xhci-mtk-sch.c
 create mode 100644 drivers/usb/host/xhci-mtk.c
 create mode 100644 drivers/usb/host/xhci-mtk.h

--
1.8.1.1.dirty

In-Reply-To: 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-09-01 14:14 Mika Penttilä
  2015-09-01 15:22 ` Fabio Estevam
  0 siblings, 1 reply; 409+ messages in thread
From: Mika Penttilä @ 2015-09-01 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

This one causes imx6q with debug uart connected to "schedule while
atomic" endlessly :


9e7b399d6528eac33a6fbfceb2b92af209c3454d is the first bad commit
commit 9e7b399d6528eac33a6fbfceb2b92af209c3454d
Author: Eduardo Valentin <edubezval@gmail.com>
Date:   Tue Aug 11 10:21:20 2015 -0700

    serial: imx: remove unbalanced clk_prepare

    The current code attempts to prepare clk_per and clk_ipg
    before using the device. However, the result is an extra
    prepare call on each clock. Here is the output of uart
    clocks (only uart enabled and used as console):

    $  grep uart /sys/kernel/debug/clk/clk_summary
     uart_serial           1            2    80000000          0 0
           uart           1            2    66000000          0 0

    This patch balances the calls of prepares. The result is:

    $  grep uart /sys/kernel/debug/clk/clk_summary
     uart_serial           1            1    80000000          0 0
           uart           1            1    66000000          0 0

    Cc: Fabio Estevam <festevam@gmail.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Jiri Slaby <jslaby@suse.com>
    Cc: linux-serial at vger.kernel.org
    Cc: linux-pm at vger.kernel.org
    Cc: linux-kernel at vger.kernel.org
    Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2015-09-01 14:14 Mika Penttilä
@ 2015-09-01 15:22 ` Fabio Estevam
  0 siblings, 0 replies; 409+ messages in thread
From: Fabio Estevam @ 2015-09-01 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 1, 2015 at 11:14 AM, Mika Penttil?
<mika.j.penttila@gmail.com> wrote:
> This one causes imx6q with debug uart connected to "schedule while
> atomic" endlessly :

Yes, I have sent a revert patch for it:
http://www.spinics.net/lists/arm-kernel/msg439995.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-09-18  4:49 Shraddha Barke
  0 siblings, 0 replies; 409+ messages in thread
From: Shraddha Barke @ 2015-09-18  4:49 UTC (permalink / raw)
  To: kernelnewbies

I updated my local kernel repository with all recent commits using the
following commands-
git checkout staging-next
git pull

After that when I try to compile, I'm getting an error

scripts/sign-file.c:20:25: fatal error: openssl/bio.h: No such file or
directory
 #include <openssl/bio.h>
                         ^
compilation terminated.
scripts/Makefile.host:91: recipe for target 'scripts/sign-file' failed
make[1]: *** [scripts/sign-file] Error 1
Makefile:545: recipe for target 'scripts' failed
make: *** [scripts] Error 2


What should I do to fix it?

Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150918/0617fe64/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-09-18 17:23 Shraddha Barke
  0 siblings, 0 replies; 409+ messages in thread
From: Shraddha Barke @ 2015-09-18 17:23 UTC (permalink / raw)
  To: kernelnewbies

By mistake I made some changes to staging-next branch
Now I've reverted those changes but I'm getting this message when I
checkout to staging-next

Your branch is ahead of 'origin/staging-next' by 4 commits.
  (use "git push" to publish your local commits)

How do I fix this?

Thanks in advance
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150918/82c325ad/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-10-12 17:26 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2015-10-12 17:26 UTC (permalink / raw)
  To: ath9k-devel

div>Let me know if something is not clear.<br><br></div></div></blockquote>=
<div>I am interested if you reintroduce bug that Sujith already fix in comm=
it:</div><div>ath9k: Enable HW queue control only for MCC<br></div><div><br=
></div><div>While as I understand correctly this patch disable hw queues fo=
r non-mcc (also clear IEEE80211_HW_QUEUE_CONTROL) and your</div><div><span =
style=3D"font-size:12.8px"><br></span></div><div><span style=3D"font-size:1=
2.8px">+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ath9k_is_chanctx_enabled())</span><b=
r></div><div><span style=3D"font-size:12.8px">+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D fi-&gt;txq;</span><br style=3D"font-size:1=
2.8px"><span style=3D"font-size:12.8px">+=C2=A0 =C2=A0 =C2=A0 =C2=A0else</s=
pan><br style=3D"font-size:12.8px"><span style=3D"font-size:12.8px">+=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D info-&gt;hw_queue;</=
span><br></div><div><span style=3D"font-size:12.8px"><br></span></div><div>=
<span style=3D"font-size:12.8px">Use again hw_queue for standard non-mcc op=
eration.</span></div><div><span style=3D"font-size:12.8px"><br></span></div=
><div><span style=3D"font-size:12.8px">Please check this, I am sure while d=
id only simple check :)</span></div><div><span style=3D"font-size:12.8px"><=
br></span></div><div><span style=3D"font-size:12.8px">BR<br>Janusz</span></=
div><div><span style=3D"font-size:12.8px"><br></span></div><div>=C2=A0</div=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;=
padding-left:1ex"><div dir=3D"ltr"><div></div>Regards,<br></div><div class=
=3D"gmail_extra"><br clear=3D"all"><div><div><div dir=3D"ltr"><table cellsp=
acing=3D"0" cellpadding=3D"0" border=3D"0" style=3D"font-family:&#39;Times =
New Roman&#39;"><tbody><tr><td style=3D"width:60px;height:37px"><a href=3D"=
http://www.fon.com/" target=3D"_blank"><img src=3D"http://corp.fon.com/site=
s/default/files/filelibrary/firmafon.png" width=3D"60" height=3D"37" title=
=3D"Fon" alt=3D"Fon" border=3D"0" style=3D"border: 0px none;"></a></td></tr=
><tr><td style=3D"border-bottom-width:1px;border-bottom-style:dotted;min-wi=
dth:100px;font-family:Arial;font-size:10pt;color:rgb(51,51,51);font-weight:=
bold;padding:15px 0px 3px">Borja Salazar</td></tr><tr><td style=3D"padding:=
5px 0px 1px;font-family:Arial;font-size:7.5pt;color:rgb(102,102,102)">Firmw=
are team</td></tr><tr><td style=3D"padding:1px 0px;font-family:Arial;font-s=
ize:7.5pt;color:rgb(102,102,102)"></td></tr><tr><td style=3D"padding:1px 0p=
x;font-family:Arial;font-size:7.5pt;color:rgb(102,102,102)"></td></tr><tr><=
td style=3D"padding:1px 0px;font-family:Arial;font-size:7.5pt;color:rgb(102=
,102,102)">All information in this email is=C2=A0<a href=3D"http://corp.fon=
.com/legal/email-disclaimer" style=3D"color:rgb(102,102,102)" target=3D"_bl=
ank">confidential</a></td></tr></tbody></table></div></div></div><div><div =
class=3D"h5">
<br><div class=3D"gmail_quote">On Fri, Nov 13, 2015 at 11:33 AM, Borja Sala=
zar <span dir=3D"ltr">&lt;<a href=3D"mailto:borja.salazar@fon.com" target=
=3D"_blank">borja.salazar at fon.com</a>&gt;</span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
><span>When channel context is enabled, we could be<br>
stopping/awakening an incorrect queue.<br>
<br>
</span>Signed-off-by: Borja Salazar &lt;<a href=3D"mailto:borja.salazar@fon=
.com" target=3D"_blank">borja.salazar at fon.com</a>&gt;<br>
<div><div>---<br>
=C2=A0drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------<br>
=C2=A01 file changed, 12 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/a=
th/ath9k/xmit.c<br>
index 3e3dac3..9b17a59 100644<br>
--- a/drivers/net/wireless/ath/ath9k/xmit.c<br>
+++ b/drivers/net/wireless/ath/ath9k/xmit.c<br>
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, str=
uct ath_txq *txq,<br>
=C2=A0{<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct ieee80211_tx_info *info =3D IEEE80211_SK=
B_CB(skb);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct ath_frame_info *fi =3D get_frame_info(sk=
b);<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0int q =3D fi-&gt;txq;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0int q;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ath9k_is_chanctx_enabled())<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D fi-&gt;txq;<b=
r>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0else<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D info-&gt;hw_q=
ueue;<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (q &lt; 0)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return;<br>
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, str=
uct ath_txq *txq,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (txq-&gt;stopped &amp;&amp;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 txq-&gt;pending_frames &lt; sc-&g=
t;tx.txq_max_pending[q]) {<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ath9k_is_chanct=
x_enabled())<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0ieee80211_wake_queue(sc-&gt;hw, info-&gt;hw_queue);<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0ieee80211_wake_queue(sc-&gt;hw, q);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ieee80211_wake_queu=
e(sc-&gt;hw, q);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 txq-&gt;stopped =3D=
 false;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0}<br>
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk=
_buff *skb,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* info are no longer valid (overwritten b=
y the ath_frame_info data.<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/<br>
<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D skb_get_queue_mapping(skb);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ath9k_is_chanctx_enabled())<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D skb_get_queue=
_mapping(skb);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0else<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0q =3D info-&gt;hw_q=
ueue;<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ath_txq_lock(sc, txq);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (txq =3D=3D sc-&gt;tx.txq_map[q]) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fi-&gt;txq =3D q;<b=
r>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (++txq-&gt;pendi=
ng_frames &gt; sc-&gt;tx.txq_max_pending[q] &amp;&amp;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 !txq-=
&gt;stopped) {<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0if (ath9k_is_chanctx_enabled())<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ieee80211_stop_queue(sc-&gt;hw, info-=
&gt;hw_queue);<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0else<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ieee80211_stop_queue(sc-&gt;hw, q);<b=
r>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0ieee80211_stop_queue(sc-&gt;hw, q);<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 txq-&gt;stopped =3D true;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
--<br>
2.3.6<br>
<br>
</div></div></blockquote></div><br></div></div></div>
</blockquote></div><br></div></div>

--001a11444ce011feae05246a36f0--

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2015-10-21  6:17 Rock Lee
  0 siblings, 0 replies; 409+ messages in thread
From: Rock Lee @ 2015-10-21  6:17 UTC (permalink / raw)
  To: kernelnewbies

unsubscribe kernelnewbies

Regards
----
Rock Lee 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20151021/6fa4734a/attachment.html 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <E1ZqY3A-0004Mt-KH@feisty.vs19.net>
@ 2015-10-26  3:21 ` Jiada Wang
  0 siblings, 0 replies; 409+ messages in thread
From: Jiada Wang @ 2015-10-26  3:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hello

 > Subject: [PATCH v2 4/8] spi: imx: add selection for iMX53 and iMX6 
controller type
>
> ECSPI contorller for iMX53 and iMX6 has few hardware issues in slave
> mode and (32*n+1) SPI word size handling comparing to iMX51.
> The change add possibility to detect the SPI controller is use and apply
> workarounds/limitations.
> Documentation for device tree bindings updated
>
> Signed-off-by: Anton Bondarenko <anton_bondarenko@mentor.com>
> ---
>   .../devicetree/bindings/spi/fsl-imx-cspi.txt       |  2 ++
>   drivers/spi/spi-imx.c                              | 36 ++++++++++++++++++++--
>   2 files changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
> index 523341a..425485f 100644
> --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
> +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
> @@ -9,6 +9,8 @@ Required properties:
>     - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31
>     - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35
>     - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51
> +  - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53
> +  - "fsl,imx6q-ecspi" for SPI compatible with the one integrated on i.MX6 family
>   - reg : Offset and length of the register set for the device
>   - interrupts : Should contain CSPI/eCSPI interrupt
>   - fsl,spi-num-chipselects : Contains the number of the chipselect
> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
> index d9b730d..41c9cef 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -72,7 +72,8 @@ enum spi_imx_devtype {
>   	IMX27_CSPI,
>   	IMX31_CSPI,
>   	IMX35_CSPI,	/* CSPI on all i.mx except above */
> -	IMX51_ECSPI,	/* ECSPI on i.mx51 and later */
> +	IMX51_ECSPI,	/* ECSPI on i.mx51 */
> +	IMX53_ECSPI,	/* ECSPI on i.mx53 and later */
>   };
>
>   struct spi_imx_data;
> @@ -129,9 +130,20 @@ static inline int is_imx35_cspi(struct spi_imx_data *d)
>   	return d->devtype_data->devtype == IMX35_CSPI;
>   }
>
> +static inline int is_imx53_ecspi(struct spi_imx_data *d)
> +{
> +	return d->devtype_data->devtype == IMX53_ECSPI;
> +}
> +
> +static inline int is_imx5x_ecspi(struct spi_imx_data *d)
> +{
> +	return d->devtype_data->devtype == IMX51_ECSPI ||
> +	       d->devtype_data->devtype == IMX53_ECSPI;
> +}
> +
>   static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d)
>   {
> -	return (d->devtype_data->devtype == IMX51_ECSPI) ? 64 : 8;
> +	return is_imx5x_ecspi(d) ? 64 : 8;
>   }
>
>   #define MXC_SPI_BUF_RX(type)						\
> @@ -680,6 +692,16 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = {
>   	.devtype = IMX51_ECSPI,
>   };
>
> +static struct spi_imx_devtype_data imx53_ecspi_devtype_data = {
> +	/* i.mx53 and later ecspi shares the functions with i.mx51 one */
> +	.intctrl = mx51_ecspi_intctrl,
> +	.config = mx51_ecspi_config,
> +	.trigger = mx51_ecspi_trigger,
> +	.rx_available = mx51_ecspi_rx_available,
> +	.reset = mx51_ecspi_reset,
> +	.devtype = IMX53_ECSPI,
> +};
> +
>   static const struct platform_device_id spi_imx_devtype[] = {
>   	{
>   		.name = "imx1-cspi",
> @@ -697,6 +719,12 @@ static const struct platform_device_id spi_imx_devtype[] = {
>   		.name = "imx35-cspi",
>   		.driver_data = (kernel_ulong_t) &imx35_cspi_devtype_data,
>   	}, {
> +		.name = "imx53-ecspi",
> +		.driver_data = (kernel_ulong_t)&imx53_ecspi_devtype_data,
> +	}, {
> +		.name = "imx6q-ecspi",
> +		.driver_data = (kernel_ulong_t)&imx53_ecspi_devtype_data,
> +	}, {
>   		.name = "imx51-ecspi",
>   		.driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data,
>   	}, {
> @@ -710,6 +738,8 @@ static const struct of_device_id spi_imx_dt_ids[] = {
>   	{ .compatible = "fsl,imx27-cspi", .data = &imx27_cspi_devtype_data, },
>   	{ .compatible = "fsl,imx31-cspi", .data = &imx31_cspi_devtype_data, },
>   	{ .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, },
> +	{ .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, },
> +	{ .compatible = "fsl,imx6q-ecspi", .data = &imx53_ecspi_devtype_data, },
>   	{ .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, },
>   	{ /* sentinel */ }
>   };
> @@ -1299,7 +1329,7 @@ static int spi_imx_probe(struct platform_device *pdev)
>   	 * Only validated on i.mx6 now, can remove the constrain if validated on
>   	 * other chips.
>   	 */
> -	if (spi_imx->devtype_data == &imx51_ecspi_devtype_data &&
> +	if (is_imx5x_ecspi(spi_imx) &&
>   	    spi_imx_sdma_init(&pdev->dev, spi_imx, master))
>   		dev_err(&pdev->dev, "dma setup error,use pio instead\n");
>
>

With this patch, there will still be issues with SPI controller on imx6 
soc other than imx6q,
for example SPI controller on imx6sl has compatibility
"compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";"

So I would suggest to update device-tree file,
for example
imx53.dtsi
"fsl,imx53-ecspi", "fsl,imx51-ecspi"; -> "fsl,imx53-ecspi";
imx6qdl.dtsi
compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi"; -> compatible = 
"fsl,imx6q-ecspi", "fsl,imx53-ecspi";
imx6sl.dtsi
compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi"; -> compatible = 
"fsl,imx6sl-ecspi", "fsl,imx53-ecspi";
etc...
by doing this, then only compatible string "fsl,imx53-ecspi" need to be
added in driver code.

Thanks,
Jiada

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-10-27  0:44 xuyiping
  0 siblings, 0 replies; 409+ messages in thread
From: xuyiping @ 2015-10-27  0:44 UTC (permalink / raw)
  To: linux-arm-kernel



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-11-16 16:13 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2015-11-16 16:13 UTC (permalink / raw)
  To: ath9k-devel

anything over that is cause for great concern.

Is there any other metric that you would suggest we track that would
show some issues due to wifi interference?

Is there anyway to get AR9341 datasheet?

Cheers,
Valent.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2015-12-13 21:57 何旦洁
  0 siblings, 0 replies; 409+ messages in thread
From: 何旦洁 @ 2015-12-13 21:57 UTC (permalink / raw)
  To: linux-arm-kernel



???? iPhone

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-02-09  7:29 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-02-09  7:29 UTC (permalink / raw)
  To: ath9k-devel

CSI Tool->
-  Gives 56 complex numbers which represent the mag and phase
 of the ofdm subcarriers. 
- The CSI tool is listening for HT20/HT40 packets with channel sounding
 bit (or bits) set so is per packet and needs a transmitter node also
- CSI is also available on some intel (sorry to mention the dirty word) chips 
but you need to have specialised firmware which the kernel 
and userland CSI code accesses.

SpectralScan->
- Is easier to use 
- give you the phase and mag (summed) in one figure.
- don't need specialised transmitters.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-03-07 17:52 nunojsa
  0 siblings, 0 replies; 409+ messages in thread
From: nunojsa @ 2016-03-07 17:52 UTC (permalink / raw)
  To: kernelnewbies



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-04-11  7:51 Paul Walmsley
  0 siblings, 0 replies; 409+ messages in thread
From: Paul Walmsley @ 2016-04-11  7:51 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP baseline test results for v4.6-rc3

Here are some basic OMAP test results for Linux v4.6-rc3.
Logs and other details at:

    http://www.pwsan.com/omap/testlogs/test_v4.6-rc3/20160411005353/


Test summary
------------

Build: uImage:
    Pass ( 3/ 3): omap1_defconfig, omap1_defconfig_1510innovator_only,
		  omap1_defconfig_5912osk_only

Build: uImage+dtb:
    Pass (13/13): omap2plus_defconfig_am33xx_only/am335x-bone,
		  omap2plus_defconfig/omap4-panda,
		  omap2plus_defconfig/omap4-panda-es,
		  omap2plus_defconfig/omap4-var-stk-om44,
		  omap2plus_defconfig/omap3-evm-37xx,
		  omap2plus_defconfig_n800_only_a/omap2420-n800,
		  omap2plus_defconfig/omap2430-sdp,
		  omap2plus_defconfig/am3517-evm,
		  omap2plus_defconfig/omap3-beagle,
		  omap2plus_defconfig/omap3-beagle-xm,
		  omap2plus_defconfig/omap3-sbc-t3517,
		  omap2plus_defconfig/omap5-uevm,
		  omap2plus_defconfig/omap5-sbc-t54

Build: zImage:
    Pass (18/18): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_n800_only_a,
		  omap2plus_defconfig_n800_multi_omap2xxx,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only,
		  omap2plus_defconfig_ti81xx_only,
		  rmk_omap3430_ldp_oldconfig,
		  rmk_omap3430_ldp_allnoconfig,
		  rmk_omap4430_sdp_oldconfig,
		  rmk_omap4430_sdp_allnoconfig, multi_v7_defconfig

Build warnings from toolchain: uImage:
    (none)

Build warnings from toolchain: uImage+dtb:
    (none)

Build warnings from toolchain: zImage:
    FAIL (16/18): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_n800_only_a,
		  omap2plus_defconfig_n800_multi_omap2xxx,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only,
		  omap2plus_defconfig_ti81xx_only,
		  rmk_omap3430_ldp_oldconfig,
		  rmk_omap4430_sdp_oldconfig, multi_v7_defconfig

Boot to userspace:
    FAIL ( 1/18): 2430sdp
    skip ( 3/18): 5912osk, 3517evm, 5430es2sbct54
    Pass (14/18): am335xbonelt, am437xsk, am335xbone, 4430es2panda,
		  4460pandaes, 4460varsomom, 37xxevm, 3530es3beagle,
		  3530es31beagle, 3730beaglexm, 3730es12beaglexm,
		  cmt3517, 5430es2uevm, 2420n800

Kernel warnings during boot to userspace:
    FAIL ( 2/18): 4430es2panda, cmt3517

PM: chip retention via suspend:
    FAIL ( 6/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  2430sdp, 5430es2uevm
    Pass ( 5/11): 4460pandaes, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm

PM: chip retention via dynamic idle:
    FAIL ( 8/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  3530es3beagle, 3530es31beagle, 2430sdp, 5430es2uevm
    Pass ( 3/11): 4460pandaes, 3730beaglexm, 3730es12beaglexm

PM: chip off (except CORE, due to errata) via suspend:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off (except CORE, due to errata) via dynamic idle:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off via suspend:
    FAIL ( 2/ 4): 37xxevm, 3530es3beagle
    Pass ( 2/ 4): 3530es31beagle, 3730es12beaglexm

PM: chip off via dynamic idle:
    FAIL ( 3/ 4): 37xxevm, 3530es3beagle, 3530es31beagle
    Pass ( 1/ 4): 3730es12beaglexm

Kernel warnings during PM test:
    FAIL ( 1/18): 4430es2panda

Obsolete Kconfig symbols:
    FAIL ( 3/21): omap1_defconfig, omap2plus_defconfig,
		  multi_v7_defconfig


vmlinux object size
(delta in bytes from test_v4.6-rc2 (9735a22799b9214d17d3c231fe377fc852f042e9)):
   text     data      bss    total  kernel
   +772     -896        0     -124  omap1_defconfig
   +772     -920        0     -148  omap1_defconfig_1510innovator_only
   +596     -928        0     -332  omap1_defconfig_5912osk_only
   -108      +64        0      -44  multi_v7_defconfig
   +236        0        0     +236  omap2plus_defconfig
   +976        0        0     +976  omap2plus_defconfig_2430sdp_only
   +300        0        0     +300  omap2plus_defconfig_am33xx_only
   +300        0        0     +300  omap2plus_defconfig_am43xx_only
   +236        0        0     +236  omap2plus_defconfig_cpupm
   +236        0        0     +236  omap2plus_defconfig_dra7xx_only
   +388       -8        0     +380  omap2plus_defconfig_n800_multi_omap2xxx
   +420        0        0     +420  omap2plus_defconfig_n800_only_a
   +164        0        0     +164  omap2plus_defconfig_no_pm
   +172        0        0     +172  omap2plus_defconfig_omap2_4_only
   +236        0        0     +236  omap2plus_defconfig_omap3_4_only
   +300        0        0     +300  omap2plus_defconfig_omap5_only
  +1004        0        0    +1004  omap2plus_defconfig_ti81xx_only
   +244        0      -48     +196  rmk_omap3430_ldp_allnoconfig
  +3896        0        0    +3896  rmk_omap3430_ldp_oldconfig
   +228        0      -48     +180  rmk_omap4430_sdp_allnoconfig
   +200        0        0     +200  rmk_omap4430_sdp_oldconfig

Boot-time memory difference
(delta in bytes from test_v4.6-rc2 (9735a22799b9214d17d3c231fe377fc852f042e9))
  avail  rsrvd   high  freed  board          kconfig
  (no differences)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-04-22  8:25 Daniel Lezcano
  2016-04-22  8:27 ` Daniel Lezcano
  0 siblings, 1 reply; 409+ messages in thread
From: Daniel Lezcano @ 2016-04-22  8:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Rafael,

please pull the following changes for 4.7.

 * Constify the cpuidle_ops structure and the types returned by the 
 * functions using it (Jisheng Zhang)


Thanks !

  -- Daniel

The following changes since commit c3b46c73264b03000d1e18b22f5caf63332547c9:

  Linux 4.6-rc4 (2016-04-17 19:13:32 -0700)

are available in the git repository at:

  http://git.linaro.org/people/daniel.lezcano/linux.git cpuidle/4.7

for you to fetch changes up to 5e7c17df795e462c70a43f1b3b670e08efefe8fd:

  drivers: firmware: psci: use const and __initconst for psci_cpuidle_ops 
(2016-04-20 10:44:32 +0200)

----------------------------------------------------------------
Jisheng Zhang (4):
      ARM: cpuidle: add const qualifier to cpuidle_ops member in structures
      ARM: cpuidle: constify return value of arm_cpuidle_get_ops()
      soc: qcom: spm: Use const and __initconst for qcom_cpuidle_ops
      drivers: firmware: psci: use const and __initconst for 
psci_cpuidle_ops

 arch/arm/include/asm/cpuidle.h | 2 +-
 arch/arm/kernel/cpuidle.c      | 6 +++---
 drivers/firmware/psci.c        | 2 +-
 drivers/soc/qcom/spm.c         | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2016-04-22  8:25 Daniel Lezcano
@ 2016-04-22  8:27 ` Daniel Lezcano
  0 siblings, 0 replies; 409+ messages in thread
From: Daniel Lezcano @ 2016-04-22  8:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/22/2016 10:25 AM, Daniel Lezcano wrote:
> Hi Rafael,
>
> please pull the following changes for 4.7.
>
>   * Constify the cpuidle_ops structure and the types returned by the
>   * functions using it (Jisheng Zhang)

Please ignore this email. I did a wrong manipulation with mutt.

Sorry for the noise.

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-06-13  6:24 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-06-13  6:24 UTC (permalink / raw)
  To: ath9k-devel

seems to be effective. But I'm not sure.
And sometimes, some phase measurement show large dispalcement along y-axis
even they are captured within very short duration.

Hence the question is,
Is ath9k reports CSI with those unwanted linear phase offset removed?
If it is not, should I look into Atheros CSI tool? As I look into it, it
just captures CSI from the kernel and does not modify it.
Or, Is CSI of Atheros different form that of Intel? I don't think so...

The final goal of extracting true phase from CSI of ath9k is to determine
angle of arrival (AoA) of signal.

Regards,
Jeon.

[1]: http://pdcc.ntu.edu.sg/wands/Atheros/ "Atheros CSI Extraction Tool"
[2] K. Qian, C. Wu, Z. Yang, Y. Liu, and Z. Zhou, =E2=80=9CPADS: Passive de=
tection
of moving targets with dynamic speed using PHY layer information,=E2=80=9D =
in 2014
20th IEEE International Conference on Parallel and Distributed Systems
(ICPADS), 2014, pp. 1=E2=80=938.
[3] M. Kotaru, K. Joshi, D. Bharadia, and S. Katti, =E2=80=9CSpotFi: Decime=
ter
Level Localization Using WiFi,=E2=80=9D SIGCOMM Comput. Commun. Rev., vol. =
45, no.
4, pp. 269=E2=80=93282, Aug. 2015.
[4] http://dhalperi.github.io/linux-80211n-csitool/ "Linux 802.11n CSI
Tool"

--001a113ff17008949005352bd33e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Dear ath9k developers,<br><br>I am currently working with =
Atheros CSI Extraction Tool [1] to get a true phase of each subcarrier.<br>=
<br>- Background<br><br>[2], [3] and many other papers claim that phase inf=
ormation from extracted CSI contains two components: true phase and unwante=
d phase offset due to subcarrier and time delay.<br>i.e., measured_phase =
=3D true_phase + time_delay * subcarrier_index + phase_offset_due_to_txrx_m=
ismatch<br>This equation can be visualized as below:<br><br><a href=3D"http=
://i.imgur.com/rk9Hh1M.png">http://i.imgur.com/rk9Hh1M.png</a><br><br>(Plea=
se note that this figure is based on CSI tool for Intel 5300 NIC.)<br><br>I=
t contains unwanted linear phase offset and constant phase offset. Since th=
e true phase is relatively small, it seems that phase is monotonically incr=
easing or decreasing in macro view due to the unwanted phase offsets. We ca=
nnot see a tiny true phase currently.<div><div><br>To remove phase offset d=
ue to subcarrier, the mentioned papers are attempting to remove it with lin=
ear fitting ax + b,<br>where a =3D slope of the figure, b =3D average of me=
asured phase, and x =3D subcarrier index.<br><br>After removing unwanted ph=
ase offset components, the true phase is estimated.<br>This estimated true =
phase seems steady and consistent across a time duration shorter than &lt; =
100 - 1000 ms:<br><br><a href=3D"http://i.imgur.com/AO89vYV.png">http://i.i=
mgur.com/AO89vYV.png</a><br><br>Note that Y-axis scale is reduece from [-50=
, 10] to [5, -3]<br><br>- My question<br><br>I want to extract and manipula=
te CSI phase WITH ATH9K NIC.<br><br>After extracting CSI from my ath9k NIC =
(AR9580 @ 2.4 GHz) with Atheros CSI extraction tool,<br>I&#39;ve tried vari=
ous fitting methods to eliminate unwanted components and stacked results fr=
om nearly 100 packets:<br><br><a href=3D"http://i.imgur.com/5r9eYwO.png">ht=
tp://i.imgur.com/5r9eYwO.png</a><br><br>From the result, in short, removing=
 only constant offset across subcarrier seems to be effective. But I&#39;m =
not sure.</div><div>And sometimes, some phase measurement show large dispal=
cement along y-axis even they are captured within very short duration.<br><=
br>Hence the question is,</div><div>Is ath9k reports CSI with those unwante=
d linear phase offset removed?</div><div>If it is not, should I look into A=
theros CSI tool? As I look into it, it just captures CSI from the kernel an=
d does not modify it.</div><div>Or, Is CSI of Atheros different form that o=
f Intel? I don&#39;t think so...</div><div><br></div><div>The final goal of=
 extracting true phase from CSI of ath9k is to determine angle of arrival (=
AoA) of signal.<br><br>Regards,<br>Jeon.<br><br>[1]: <a href=3D"http://pdcc=
.ntu.edu.sg/wands/Atheros/">http://pdcc.ntu.edu.sg/wands/Atheros/</a> &quot=
;Atheros CSI Extraction Tool&quot;<br>[2] K. Qian, C. Wu, Z. Yang, Y. Liu, =
and Z. Zhou, =E2=80=9CPADS: Passive detection of moving targets with dynami=
c speed using PHY layer information,=E2=80=9D in 2014 20th IEEE Internation=
al Conference on Parallel and Distributed Systems (ICPADS), 2014, pp. 1=E2=
=80=938.<br>[3] M. Kotaru, K. Joshi, D. Bharadia, and S. Katti, =E2=80=9CSp=
otFi: Decimeter Level Localization Using WiFi,=E2=80=9D SIGCOMM Comput. Com=
mun. Rev., vol. 45, no. 4, pp. 269=E2=80=93282, Aug. 2015.<br>[4] <a href=
=3D"http://dhalperi.github.io/linux-80211n-csitool/">http://dhalperi.github=
.io/linux-80211n-csitool/</a> &quot;Linux 802.11n CSI Tool&quot;
</div></div></div>

--001a113ff17008949005352bd33e--

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-06-13  6:24 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-06-13  6:24 UTC (permalink / raw)
  To: ath9k-devel

assumed the frequencies and numbers were correct, which is why I
picked it up.

> Is this trying to add 4.9 GHz channels in general for multiple different
> use cases? And if so, what are those use cases? Or is this only for some
> public safety cases? And if so, for which regulatory domains?

I believe he has a client that requires this support in a Linux kernel.

> To be frank, I really don't see how this would be even close to a state
> that should be accepted into the upstream tree.

Fair enough I'm dropping this.

Kalle, I've marked this as rejected and archived on Patchwork.

Thanks,

-- 
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-07-10  9:24 ` Neil Armstrong
  0 siblings, 0 replies; 409+ messages in thread
From: Neil Armstrong @ 2016-07-10  9:24 UTC (permalink / raw)
  To: linus-amlogic

Subject: [PATCH v2 0/4] pwm: Add Amlogic Meson SoC PWM Controller

Add support for the PWM controller found in Amlogic Meson SoCs.
This controller provides a dual PWM output with 4 selectable clock source
and a two level divider to achieve a better PWM range.

Currently Meson8b and GXBB SoCs are supported.

Changes since v1 at http://lkml.kernel.org/r/1466173784-15625-1-git-send-email-narmstrong at baylibre.com :
- fix meson8b dtsi

Neil Armstrong (4):
  pwm: Add support for Meson PWM Controller
  dt-bindings: pwm: Add bindings for Meson PWM Controller
  ARM64: dts: meson-gxbb: Add Meson GXBB PWM Controller nodes
  ARM: dts: meson8b: Add Meson8b PWM Controller nodes

 .../devicetree/bindings/pwm/pwm-meson.txt          |  21 +
 arch/arm/boot/dts/meson8b.dtsi                     |  21 +
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        |  28 ++
 drivers/pwm/Kconfig                                |   9 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-meson.c                            | 491 +++++++++++++++++++++
 6 files changed, 571 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-meson.txt
 create mode 100644 drivers/pwm/pwm-meson.c

-- 
2.7.0

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-07-10  9:24 ` Neil Armstrong
  0 siblings, 0 replies; 409+ messages in thread
From: Neil Armstrong @ 2016-07-10  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH v2 0/4] pwm: Add Amlogic Meson SoC PWM Controller

Add support for the PWM controller found in Amlogic Meson SoCs.
This controller provides a dual PWM output with 4 selectable clock source
and a two level divider to achieve a better PWM range.

Currently Meson8b and GXBB SoCs are supported.

Changes since v1 at http://lkml.kernel.org/r/1466173784-15625-1-git-send-email-narmstrong at baylibre.com :
- fix meson8b dtsi

Neil Armstrong (4):
  pwm: Add support for Meson PWM Controller
  dt-bindings: pwm: Add bindings for Meson PWM Controller
  ARM64: dts: meson-gxbb: Add Meson GXBB PWM Controller nodes
  ARM: dts: meson8b: Add Meson8b PWM Controller nodes

 .../devicetree/bindings/pwm/pwm-meson.txt          |  21 +
 arch/arm/boot/dts/meson8b.dtsi                     |  21 +
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi        |  28 ++
 drivers/pwm/Kconfig                                |   9 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-meson.c                            | 491 +++++++++++++++++++++
 6 files changed, 571 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-meson.txt
 create mode 100644 drivers/pwm/pwm-meson.c

-- 
2.7.0

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-09-30 14:37 Maxime Ripard
  0 siblings, 0 replies; 409+ messages in thread
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH v5 0/5] drm: Add Support for Passive RGB to VGA bridges

Hi,

This serie is about adding support for the RGB to VGA bridge found in
the A13-Olinuxino and the CHIP VGA adapter.

Both these boards rely on an entirely passive bridge made out of
resitor ladders that do not require any initialisation. The only thing
needed is to get the timings from the screen if available (and if not,
fall back on XGA standards), set up the display pipeline to output on
the RGB bus with the proper timings, and you're done.

This serie also fixes a bunch of bugs uncovered when trying to
increase the resolution, and hence the pixel clock, of our
pipeline. It also fixes a few bugs in the DRM driver itself that went
unnoticed before.

Let me know what you think,
Maxime

Changes from v4:
  - Removed unused functions

Changes from v3:
  - Depends on OF in Kconfig
  - Fixed typos in the driver comments
  - Removed the mention of a "passive" bridge in the bindings doc
  - Made the strcuture const
  - Removed the nops and best_encoders implementations
  - Removed the call to drm_bridge_enable in the sun4i driver

Changes from v2:
  - Changed the compatible as suggested
  - Rebased on top 4.8

Changes from v1:
  - Switch to using a vga-connector
  - Use drm_encoder bridge pointer instead of doing our own
  - Report the connector status as unknown instead of connected by
    default, and as connected only if we can retrieve the EDID.
  - Switch to of_i2c_get_adapter by node, and put the reference when done
  - Rebased on linux-next	      

Maxime Ripard (5):
  drm/sun4i: rgb: Remove the bridge enable/disable functions
  drm/bridge: Add RGB to VGA bridge support
  ARM: sun5i: a13-olinuxino: Enable VGA bridge
  ARM: multi_v7: enable VGA bridge
  ARM: sunxi: Enable VGA bridge

 .../bindings/display/bridge/rgb-to-vga-bridge.txt  |  48 +++++
 arch/arm/boot/dts/sun5i-a13-olinuxino.dts          |  54 +++++
 arch/arm/configs/multi_v7_defconfig                |   1 +
 arch/arm/configs/sunxi_defconfig                   |   1 +
 drivers/gpu/drm/bridge/Kconfig                     |   7 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 drivers/gpu/drm/bridge/rgb-to-vga.c                | 229 +++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun4i_rgb.c                  |   6 -
 8 files changed, 341 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
 create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-11-11  3:38 Chunyan Zhang
  0 siblings, 0 replies; 409+ messages in thread
From: Chunyan Zhang @ 2016-11-11  3:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Steven,

On 21 October 2016 at 20:13, Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> On 18 October 2016 at 23:44, Steven Rostedt <rostedt@goodmis.org> wrote:
>> On Tue, 18 Oct 2016 16:08:58 +0800
>> Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
>>
>>> Currently Function traces can be only exported to ring buffer, this
>>> patch added trace_export concept which can process traces and export
>>> them to a registered destination as an addition to the current only
>>> one output of Ftrace - i.e. ring buffer.
>>>
>>> In this way, if we want Function traces to be sent to other destination
>>> rather than ring buffer only, we just need to register a new trace_export
>>> and implement its own .write() function for writing traces to storage.
>>>
>>> With this patch, only Function trace (trace type is TRACE_FN)
>>> is supported.
>>
>> This is getting better, but I still have some nits.
>>
>
> Thanks.
>
>>>
>>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>>> ---
>>>  include/linux/trace.h |  28 +++++++++++
>>>  kernel/trace/trace.c  | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
>>>  2 files changed, 159 insertions(+), 1 deletion(-)
>>>  create mode 100644 include/linux/trace.h
>>>
>>> diff --git a/include/linux/trace.h b/include/linux/trace.h
>>> new file mode 100644
>>> index 0000000..eb1c5b8
>>> --- /dev/null
>>> +++ b/include/linux/trace.h
>>> @@ -0,0 +1,28 @@
>>> +#ifndef _LINUX_TRACE_H
>>> +#define _LINUX_TRACE_H
>>> +
>>> +#ifdef CONFIG_TRACING
>>> +/*
>>> + * The trace export - an export of Ftrace output. The trace_export
>>> + * can process traces and export them to a registered destination as
>>> + * an addition to the current only output of Ftrace - i.e. ring buffer.
>>> + *
>>> + * If you want traces to be sent to some other place rather than ring
>>> + * buffer only, just need to register a new trace_export and implement
>>> + * its own .write() function for writing traces to the storage.
>>> + *
>>> + * next              - pointer to the next trace_export
>>> + * write     - copy traces which have been delt with ->commit() to
>>> + *             the destination
>>> + */
>>> +struct trace_export {
>>> +     struct trace_export __rcu       *next;
>>> +     void (*write)(const char *, unsigned int);
>>
>> Why const char*? Why not const void *? This will never be a string.
>>
>
> Will revise this.
>
>>
>>> +};
>>> +
>>> +int register_ftrace_export(struct trace_export *export);
>>> +int unregister_ftrace_export(struct trace_export *export);
>>> +
>>> +#endif       /* CONFIG_TRACING */
>>> +
>>> +#endif       /* _LINUX_TRACE_H */
>>> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
>>> index 8696ce6..db94ec1 100644
>>> --- a/kernel/trace/trace.c
>>> +++ b/kernel/trace/trace.c
>>> @@ -40,6 +40,7 @@
>>>  #include <linux/poll.h>
>>>  #include <linux/nmi.h>
>>>  #include <linux/fs.h>
>>> +#include <linux/trace.h>
>>>  #include <linux/sched/rt.h>
>>>
>>>  #include "trace.h"
>>> @@ -2128,6 +2129,132 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
>>>       ftrace_trace_userstack(buffer, flags, pc);
>>>  }
>>>
>>> +static void
>>> +trace_process_export(struct trace_export *export,
>>> +            struct ring_buffer_event *event)
>>> +{
>>> +     struct trace_entry *entry;
>>> +     unsigned int size = 0;
>>> +
>>> +     entry = ring_buffer_event_data(event);
>>> +
>>> +     size = ring_buffer_event_length(event);
>>> +
>>> +     if (export->write)
>>> +             export->write((char *)entry, size);
>>
>> Is there ever going to be a time where export->write wont be set?
>
> There hasn't been since only one trace_export (i.e. stm_ftrace) was
> added in this patch-set , I just wanted to make sure the write() has
> been set before registering trace_export like what I added in 2/3 of
> this series.
>
>>
>> And if there is, this can be racy. As in
>>
>>
>>         CPU 0:                  CPU 1:
>>         ------                  ------
>>         if (export->write)
>>
>>                                 export->write = NULL;
>
> Is there going to be this kind of use case? Why some one needs to
> change export->write() rather than register a new trace_export?
>
> I probably haven't understood your point thoroughly, please correct me
> if my guess was wrong.
>

Any further comments? :)

Thanks,
Chunyan

>
> Thanks for the review,
> Chunyan
>
>>
>>         export->write(entry, size);
>>
>>         BOOM!
>>
>>
>> -- Steve
>>
>>> +}
>>> +
>>> +static DEFINE_MUTEX(ftrace_export_lock);
>>> +
>>> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
>>> +
>>> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
>>> +
>>> +static inline void ftrace_exports_enable(void)
>>> +{
>>> +     static_branch_enable(&ftrace_exports_enabled);
>>> +}
>>> +
>>> +static inline void ftrace_exports_disable(void)
>>> +{
>>> +     static_branch_disable(&ftrace_exports_enabled);
>>> +}
>>> +
>>> +void ftrace_exports(struct ring_buffer_event *event)
>>> +{
>>> +     struct trace_export *export;
>>> +
>>> +     preempt_disable_notrace();
>>> +
>>> +     export = rcu_dereference_raw_notrace(ftrace_exports_list);
>>> +     while (export) {
>>> +             trace_process_export(export, event);
>>> +             export = rcu_dereference_raw_notrace(export->next);
>>> +     }
>>> +
>>> +     preempt_enable_notrace();
>>> +}
>>> +
>>> +static inline void
>>> +add_trace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> +     rcu_assign_pointer(export->next, *list);
>>> +     /*
>>> +      * We are entering export into the list but another
>>> +      * CPU might be walking that list. We need to make sure
>>> +      * the export->next pointer is valid before another CPU sees
>>> +      * the export pointer included into the list.
>>> +      */
>>> +     rcu_assign_pointer(*list, export);
>>> +}
>>> +
>>> +static inline int
>>> +rm_trace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> +     struct trace_export **p;
>>> +
>>> +     for (p = list; *p != NULL; p = &(*p)->next)
>>> +             if (*p == export)
>>> +                     break;
>>> +
>>> +     if (*p != export)
>>> +             return -1;
>>> +
>>> +     rcu_assign_pointer(*p, (*p)->next);
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static inline void
>>> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> +     if (*list == NULL)
>>> +             ftrace_exports_enable();
>>> +
>>> +     add_trace_export(list, export);
>>> +}
>>> +
>>> +static inline int
>>> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
>>> +{
>>> +     int ret;
>>> +
>>> +     ret = rm_trace_export(list, export);
>>> +     if (*list == NULL)
>>> +             ftrace_exports_disable();
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +int register_ftrace_export(struct trace_export *export)
>>> +{
>>> +     if (WARN_ON_ONCE(!export->write))
>>> +             return -1;
>>> +
>>> +     mutex_lock(&ftrace_export_lock);
>>> +
>>> +     add_ftrace_export(&ftrace_exports_list, export);
>>> +
>>> +     mutex_unlock(&ftrace_export_lock);
>>> +
>>> +     return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(register_ftrace_export);
>>> +
>>> +int unregister_ftrace_export(struct trace_export *export)
>>> +{
>>> +     int ret;
>>> +
>>> +     mutex_lock(&ftrace_export_lock);
>>> +
>>> +     ret = rm_ftrace_export(&ftrace_exports_list, export);
>>> +
>>> +     mutex_unlock(&ftrace_export_lock);
>>> +
>>> +     return ret;
>>> +}
>>> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
>>> +
>>>  void
>>>  trace_function(struct trace_array *tr,
>>>              unsigned long ip, unsigned long parent_ip, unsigned long flags,
>>> @@ -2146,8 +2273,11 @@ trace_function(struct trace_array *tr,
>>>       entry->ip                       = ip;
>>>       entry->parent_ip                = parent_ip;
>>>
>>> -     if (!call_filter_check_discard(call, entry, buffer, event))
>>> +     if (!call_filter_check_discard(call, entry, buffer, event)) {
>>> +             if (static_branch_unlikely(&ftrace_exports_enabled))
>>> +                     ftrace_exports(event);
>>>               __buffer_unlock_commit(buffer, event);
>>> +     }
>>>  }
>>>
>>>  #ifdef CONFIG_STACKTRACE
>>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-11-19 18:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-11-19 18:31 UTC (permalink / raw)
  To: ath9k-devel

80         /* Enable radar pulse detection if on a DFS channel. Spectral
81          * scanning and radar detection can not be used concurrently.
82          */
83         if (hw->conf.radar_enabled) {
84                 u32 rxfilter;
85
86                 rxfilter = ath9k_hw_getrxfilter(ah);
87                 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
88                                 ATH9K_RX_FILTER_PHYERR;
89                 ath9k_hw_setrxfilter(ah, rxfilter);
90                 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
91                         chan->center_freq);
92         } else {
93                 /* perform spectral scan if requested. */
94                 if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
95                         sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN)
96                         ath9k_cmn_spectral_scan_trigger(common, &sc->spec_priv);
97         }

it seems that spectral can't ever be activated while operating on a DFS channel.

If you need to catch the opposite case, i.e. prevent feeding pseudo-radar pulses
into the pattern detector, you just need to ensure that they depend on
hw->conf.radar_enabled. A patch like the attached one should be enough.


Cheers,
Zefir

--------------81DB7B8680E9662AC7B071A0
Content-Type: text/x-patch;
 name="0001-ath9k-feed-DFS-detector-only-if-operating-on-radar-c.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0001-ath9k-feed-DFS-detector-only-if-operating-on-radar-c.pa";
 filename*1="tch"

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-11-19 18:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-11-19 18:31 UTC (permalink / raw)
  To: ath9k-devel

behaviour. The biggest problem seems to be that the
ath9k_hw_set_sta_beacon_timers function is never called, so once the
hardware enters the PS mode there is no hardware trigger to wake up
the hardware. However, there is a mac80211 beacon loss software timer
is the one that wakes up the hardware after 7 lost beacon.

Could you provide me more details about the link between Power Save
Mode and the hardware triggers/sleep registers from
ath9k_hw_set_sta_beacon_timers?
The ath9k_hw_set_sta_beacon_timers should be called every time a
beacon is received, right?

[1] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/hw.c?v=4.3#L2269
[2] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/main.c#L486
[3] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c?v=2.6.35#L639


> BR
> Janusz
>
>> Thanks,
>> Doru
>> _______________________________________________
>> ath9k-devel mailing list
>> ath9k-devel at lists.ath9k.org
>> https://lists.ath9k.org/mailman/listinfo/ath9k-devel

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-11-19 18:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-11-19 18:31 UTC (permalink / raw)
  To: ath9k-devel

"""
Since ADC was not designed to be a dedicated HW RNG, we do not want to
bind it to /dev/hwrng framework directly.
"""

> Where is the description of the RNG, where is the test implementation? 
> > 
> > Otherwise, your patch will cause high CPU load,  as continuously read ADC
> > data if entropy bits under write_wakeup_threshold.
> 
> The issue is that although you may have analyzed it, others are unable to 
> measure the quality of the RNG and assess the design as well as the 
> implementation of the RNG. This RNG is the only implementation of a hardware 
> RNG that per default and without being able to change it at runtime injects 
> data into the input_pool where the noise source cannot be audited. Note, even 
> other respected RNG noise sources like the Intel RDRAND will not feed into /
> dev/random per default in a way that dominates all other noise sources.
> 
> I would like to be able to deactivate that noise source to the extent that it 
> does not cause /dev/random to unblock. The reason is that your noise source 
> starts to dominate all other noise sources.

I think the short-term problem here is the config logic:

config ATH9K_HWRNG
       bool "Random number generator support"
       depends on ATH9K && (HW_RANDOM = y || HW_RANDOM = ATH9K)
       default y

If you have *any* hwrngs you want to use and you have an ath9k card
(HW_RANDOM = y and ATH9K != n), you get the behavior Stephan is pointing
out.

Short term, we should just default no here.

> If you think that this patch is a challenge because your driver starts to 
> spin, please help and offer another solution.

Well, I don't buy the reasoning listed above for not using the hwrng
framework.  Interrupt timings were never designed to be a source of entropy
either.  We need to grab it where ever we can find it, especially on
embedded systems.  Documentation/hw_random.txt even says:

"""
This data is NOT CHECKED by any fitness tests, and could potentially be
bogus (if the hardware is faulty or has been tampered with).
"""

I really don't think there's a problem with adding these sorts of
sources under char/hw_random/.  I think the only thing we would be
concerned about, other than the already addressed entropy estimation,
would be constraining the data rate.

Is ath9k the only wireless card that exposes ADC registers?  What about
sound cards?

thx,

Jason.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-11-19 18:31 bogus
  0 siblings, 0 replies; 409+ messages in thread
From: bogus @ 2016-11-19 18:31 UTC (permalink / raw)
  To: ath9k-devel

"""
Since ADC was not designed to be a dedicated HW RNG, we do not want to bind=
 it to /dev/hwrng framework directly.
"""

> Where is the description of the RNG, where is the test implementation?=20
> >=20
> > Otherwise, your patch will cause high CPU load,  as continuously=20
> > read ADC data if entropy bits under write_wakeup_threshold.
>=20
> The issue is that although you may have analyzed it, others are unable=20
> to measure the quality of the RNG and assess the design as well as the=20
> implementation of the RNG. This RNG is the only implementation of a=20
> hardware RNG that per default and without being able to change it at=20
> runtime injects data into the input_pool where the noise source cannot=20
> be audited. Note, even other respected RNG noise sources like the=20
> Intel RDRAND will not feed into / dev/random per default in a way that do=
minates all other noise sources.
>=20
> I would like to be able to deactivate that noise source to the extent=20
> that it does not cause /dev/random to unblock. The reason is that your=20
> noise source starts to dominate all other noise sources.

I think the short-term problem here is the config logic:

config ATH9K_HWRNG
       bool "Random number generator support"
       depends on ATH9K && (HW_RANDOM =3D y || HW_RANDOM =3D ATH9K)
       default y

If you have *any* hwrngs you want to use and you have an ath9k card (HW_RAN=
DOM =3D y and ATH9K !=3D n), you get the behavior Stephan is pointing out.

Short term, we should just default no here.

> If you think that this patch is a challenge because your driver starts=20
> to spin, please help and offer another solution.

Well, I don't buy the reasoning listed above for not using the hwrng framew=
ork.  Interrupt timings were never designed to be a source of entropy eithe=
r.  We need to grab it where ever we can find it, especially on embedded sy=
stems.  Documentation/hw_random.txt even says:

"""
This data is NOT CHECKED by any fitness tests, and could potentially be bog=
us (if the hardware is faulty or has been tampered with).
"""

I really don't think there's a problem with adding these sorts of sources u=
nder char/hw_random/.  I think the only thing we would be concerned about, =
other than the already addressed entropy estimation, would be constraining =
the data rate.

Is ath9k the only wireless card that exposes ADC registers?  What about sou=
nd cards?

thx,

Jason.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2016-12-01 10:00 Ramana Radhakrishnan
  0 siblings, 0 replies; 409+ messages in thread
From: Ramana Radhakrishnan @ 2016-12-01 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

>
> By the way, how is this implemented?  Some of them overlap existing
> callee-saved registers.


The AArch64 PCS requires that only the bottom 64 bits of SIMD
registers (v8-v15) are callee-saved. The top 64 bits of the current
Advanced SIMD registers are the responsibility of the caller. This
naturally extends to SVE.


Ramana

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2017-01-13 10:46   ` [PATCH v3 1/8] arm: put types.h in uapi Nicolas Dichtel
@ 2017-01-13 15:36     ` David Howells
  0 siblings, 0 replies; 409+ messages in thread
From: David Howells @ 2017-01-13 15:36 UTC (permalink / raw)
  To: linux-snps-arc

Nicolas Dichtel <nicolas.dichtel@6wind.com> wrote:

> This header file is exported, thus move it to uapi.

Exported how?

> +#ifdef __INT32_TYPE__
> +#undef __INT32_TYPE__
> +#define __INT32_TYPE__		int
> +#endif
> +
> +#ifdef __UINT32_TYPE__
> +#undef __UINT32_TYPE__
> +#define __UINT32_TYPE__	unsigned int
> +#endif
> +
> +#ifdef __UINTPTR_TYPE__
> +#undef __UINTPTR_TYPE__
> +#define __UINTPTR_TYPE__	unsigned long
> +#endif

These weren't defined by the kernel before, so why do we need to define them
now?

Will defining __UINTPTR_TYPE__ cause problems in compiling libboost by
changing the signature on C++ functions that use uintptr_t?

David

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2017-01-13 10:46   ` [PATCH v3 4/8] x86: stop exporting msr-index.h to userland Nicolas Dichtel
@ 2017-01-13 15:43     ` David Howells
  0 siblings, 0 replies; 409+ messages in thread
From: David Howells @ 2017-01-13 15:43 UTC (permalink / raw)
  To: linux-snps-arc

> -header-y += msr-index.h

I see it on my desktop as /usr/include/asm/msr-index.h and it's been there at
least four years - and as such it's part of the UAPI.  I don't think you can
remove it unless you can guarantee there are no userspace users.

David

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-01-31  7:58 Andy Gross
  0 siblings, 0 replies; 409+ messages in thread
From: Andy Gross @ 2017-01-31  7:58 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [Patch v5 0/2] Support ARM SMCC SoC vendor quirks

At least one SoC vendor (Qualcomm) requires additional processing done
during ARM SMCCC calls.  As such, an additional parameter to the
arm_smccc_smc is required to be able to handle SoC specific quirks.

The Qualcomm quirk is necessary due to the fact that the scm call can
be interrupted on Qualcomm ARM64 platforms.  When this occurs, the
call must be restarted using information that was passed back during
the original smc call.

The first patch in this series adds a quirk structure and also adds a
quirk parameter to arm_smccc_smc calls.  I added macros to allow users
to choose the API they need.  This keeps all of the current users who
do not need quirks from having to change anything.

The second patch adds the Qualcomm quirk and also implements the
Qualcomm firmware changes required to handle the restarting of the
interrupted SMC call.

The original patch set for the SMCCC session ID is located at:
https://lkml.org/lkml/2016/8/20/7

Changes from v4:
  - Fix issue with hvc calls.

Changes from v3:
  - Fix documentation

Changes from v2:
  - Use variadic macros

Changes from v1:
  - Add macros to handle both use cases per review comments

Andy Gross (2):
  arm: kernel: Add SMC structure parameter
  firmware: qcom: scm: Fix interrupted SCM calls

 arch/arm/kernel/armksyms.c      |  2 +-
 arch/arm/kernel/smccc-call.S    |  7 ++++---
 arch/arm64/kernel/arm64ksyms.c  |  2 +-
 arch/arm64/kernel/asm-offsets.c |  7 +++++--
 arch/arm64/kernel/smccc-call.S  | 22 ++++++++++++++++------
 drivers/firmware/qcom_scm-64.c  | 13 ++++++++++---
 include/linux/arm-smccc.h       | 38 +++++++++++++++++++++++++++++++-------
 7 files changed, 68 insertions(+), 23 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-02-07  0:22 Scott Bauer
  2017-02-07  0:46 ` Jens Axboe
  0 siblings, 1 reply; 409+ messages in thread
From: Scott Bauer @ 2017-02-07  0:22 UTC (permalink / raw)


I screwed up and had size_t's in the uapi structures which of course
differ in size on 32 and 64 bit platforms. This caused issues running
32 bit userland on a 64 bit kernel. We're hoping to sneak this
patch in so we don't have to maintain a compat layer.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2017-02-07  0:22 Scott Bauer
@ 2017-02-07  0:46 ` Jens Axboe
  0 siblings, 0 replies; 409+ messages in thread
From: Jens Axboe @ 2017-02-07  0:46 UTC (permalink / raw)


On 02/06/2017 05:22 PM, Scott Bauer wrote:
> I screwed up and had size_t's in the uapi structures which of course
> differ in size on 32 and 64 bit platforms. This caused issues running
> 32 bit userland on a 64 bit kernel. We're hoping to sneak this
> patch in so we don't have to maintain a compat layer.

I'll apply it - you forgot to add a Fixes, always do that when a patch
fixes something that a specific commit introduced.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-04-09 10:46 76564 at max.arc.nasa.gov
  0 siblings, 0 replies; 409+ messages in thread
From: 76564 at max.arc.nasa.gov @ 2017-04-09 10:46 UTC (permalink / raw)
  To: linux-security-module

A non-text attachment was scrubbed...
Name: REPORT_876578354678929_linux-security-module.zip
Type: application/zip
Size: 67873 bytes
Desc: not available
URL: <http://kernsec.org/pipermail/linux-security-module-archive/attachments/20170409/8f34a4d7/attachment.zip>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-04-16 15:11 wendyqzx at gmail.com
  0 siblings, 0 replies; 409+ messages in thread
From: wendyqzx at gmail.com @ 2017-04-16 15:11 UTC (permalink / raw)
  To: linux-security-module

A non-text attachment was scrubbed...
Name: EMAIL_8910011500_linux-security-module.zip
Type: application/zip
Size: 2039 bytes
Desc: not available
URL: <http://kernsec.org/pipermail/linux-security-module-archive/attachments/20170416/2cb101ce/attachment.zip>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-04-21  4:59 wendyqzx at gmail.com
  0 siblings, 0 replies; 409+ messages in thread
From: wendyqzx at gmail.com @ 2017-04-21  4:59 UTC (permalink / raw)
  To: linux-security-module

A non-text attachment was scrubbed...
Name: EMAIL_2700592_linux-security-module.zip
Type: application/zip
Size: 2164 bytes
Desc: not available
URL: <http://kernsec.org/pipermail/linux-security-module-archive/attachments/20170421/b9d2e23c/attachment.zip>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-04-21 23:23 Sandeep Mann
  0 siblings, 0 replies; 409+ messages in thread
From: Sandeep Mann @ 2017-04-21 23:23 UTC (permalink / raw)




Adding linux-nvme at lists.infradead.org

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
       [not found] <CAMj-D2DO_CfvD77izsGfggoKP45HSC9aD6auUPAYC9Yeq_aX7w@mail.gmail.com>
@ 2017-05-04 16:44 ` gengdongjiu
  0 siblings, 0 replies; 409+ messages in thread
From: gengdongjiu @ 2017-05-04 16:44 UTC (permalink / raw)
  To: linux-arm-kernel

Dear James,
   Thanks a lot for your review and comments. I am very sorry for the
late response.


2017-05-04 23:42 GMT+08:00 gengdongjiu <gengdj.1984@gmail.com>:
>  Hi Dongjiu Geng,
>
> On 30/04/17 06:37, Dongjiu Geng wrote:
>> when happen SEA, deliver signal bus and handle the ioctl that
>> inject SEA abort to guest, so that guest can handle the SEA error.
>
>> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
>> index 105b6ab..a96594f 100644
>> --- a/arch/arm/kvm/mmu.c
>> +++ b/arch/arm/kvm/mmu.c
>> @@ -20,8 +20,10 @@
>> @@ -1238,6 +1240,36 @@ static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, kvm_pfn_t pfn,
>>   __coherent_cache_guest_page(vcpu, pfn, size);
>>  }
>>
>> +static void kvm_send_signal(unsigned long address, bool hugetlb, bool hwpoison)
>> +{
>> + siginfo_t info;
>> +
>> + info.si_signo   = SIGBUS;
>> + info.si_errno   = 0;
>> + if (hwpoison)
>> + info.si_code    = BUS_MCEERR_AR;
>> + else
>> + info.si_code    = 0;
>> +
>> + info.si_addr    = (void __user *)address;
>> + if (hugetlb)
>> + info.si_addr_lsb = PMD_SHIFT;
>> + else
>> + info.si_addr_lsb = PAGE_SHIFT;
>> +
>> + send_sig_info(SIGBUS, &info, current);
>> +}
>> +
> ?  [hide part of quote]
>
> Punit reviewed the other version of this patch, this PMD_SHIFT is not the right
> thing to do, it needs a more accurate set of calls and shifts as there may be
> hugetlbfs pages other than PMD_SIZE.
>
> https://www.spinics.net/lists/arm-kernel/msg568919.html
>
> I haven't posted a new version of that patch because I was still hunting a bug
> in the hugepage/hwpoison code, even with Punit's fixes series I see -EFAULT
> returned to userspace instead of this hwpoison code being invoked.

  Ok, got it, thanks for your information.
>
> Please avoid duplicating functionality between patches, it wastes reviewers
> time, especially when we know there are problems with this approach.
>
>
>> +static void kvm_handle_bad_page(unsigned long address,
>> + bool hugetlb, bool hwpoison)
>> +{
>> + /* handle both hwpoison and other synchronous external Abort */
>> + if (hwpoison)
>> + kvm_send_signal(address, hugetlb, true);
>> + else
>> + kvm_send_signal(address, hugetlb, false);
>> +}
>
> Why the extra level of indirection? We only want to signal userspace like this
> from KVM for hwpoison. Signals for RAS related reasons should come from the bits
> of the kernel that decoded the error.

For the SEA, the are maily two types:
0b010000 Synchronous External Abort on memory access.
0b0101xx Synchronous External Abort on page table walk. DFSC[1:0]
encode the level.

hwpoison should belong to the  "Synchronous External Abort on memory access"
if the SEA type is not hwpoison, such as page table walk, do you mean
KVM do not deliver the SIGBUS?
If so, how the KVM handle the SEA type other than hwpoison?

>
> (hwpoison for KVM is a corner case as Qemu's memory effectively has two users,
> Qemu and KVM. This isn't the example of how user-space gets signalled.)
>
>
>> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
>> index b37446a..780e3c4 100644
>> --- a/arch/arm64/kvm/guest.c
>> +++ b/arch/arm64/kvm/guest.c
>> @@ -277,6 +277,13 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
>>   return -EINVAL;
>>  }
>>
>> +int kvm_vcpu_ioctl_sea(struct kvm_vcpu *vcpu)
>> +{
>> + kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
>> +
>> + return 0;
>> +}
>
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index bb02909..1d2e2e7 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -1306,6 +1306,7 @@ struct kvm_s390_ucas_mapping {
>>  #define KVM_S390_GET_IRQ_STATE  _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
>>  /* Available with KVM_CAP_X86_SMM */
>>  #define KVM_SMI                   _IO(KVMIO,   0xb7)
>> +#define KVM_ARM_SEA               _IO(KVMIO,   0xb8)
>>
>>  #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
>>  #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
>>
>
> Why do we need a userspace API for SEA? It can also be done by using
> KVM_{G,S}ET_ONE_REG to change the vcpu registers. The advantage of doing it this
> way is you can choose which ESR value to use.
>
> Adding a new API call to do something you could do with an old one doesn't look
> right.

James, I considered your suggestion before that use the
KVM_{G,S}ET_ONE_REG to change the vcpu registers. but I found it does
not have difference to use the alread existed KVM API.  so may be
changing the vcpu registers in qemu will duplicate with the KVM APIs.

injection a SEA is no more than setting some registers: elr_el1, PC,
PSTATE, SPSR_el1, far_el1, esr_el1
I seen this KVM API do the same thing as Qemu.  do you found call this
API will have issue and necessary to choose another ESR value?

I pasted the alread existed KVM API code:

static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned
long addr)
{
 unsigned long cpsr = *vcpu_cpsr(vcpu);
 bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
 u32 esr = 0;
 *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
 *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
 *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
 *vcpu_spsr(vcpu) = cpsr;
 vcpu_sys_reg(vcpu, FAR_EL1) = addr;
 /*
  * Build an {i,d}abort, depending on the level and the
  * instruction set. Report an external synchronous abort.
  */
 if (kvm_vcpu_trap_il_is32bit(vcpu))
  esr |= ESR_ELx_IL;
 /*
  * Here, the guest runs in AArch64 mode when in EL1. If we get
  * an AArch32 fault, it means we managed to trap an EL0 fault.
  */
 if (is_aarch32 || (cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
  esr |= (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT);
 else
  esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
 if (!is_iabt)
  esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
 vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_ELx_FSC_EXTABT;
}

static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
    unsigned long addr)
{
 u32 vect_offset;
 u32 *far, *fsr;
 bool is_lpae;
 if (is_pabt) {
  vect_offset = 12;
  far = &vcpu_cp15(vcpu, c6_IFAR);
  fsr = &vcpu_cp15(vcpu, c5_IFSR);
 } else { /* !iabt */
  vect_offset = 16;
  far = &vcpu_cp15(vcpu, c6_DFAR);
  fsr = &vcpu_cp15(vcpu, c5_DFSR);
 }
 prepare_fault32(vcpu, COMPAT_PSR_MODE_ABT | COMPAT_PSR_A_BIT, vect_offset);
 *far = addr;
 /* Give the guest an IMPLEMENTATION DEFINED exception */
 is_lpae = (vcpu_cp15(vcpu, c2_TTBCR) >> 31);
 if (is_lpae)
  *fsr = 1 << 9 | 0x34;
 else
  *fsr = 0x14;
}


/**
 * kvm_inject_dabt - inject a data abort into the guest
 * @vcpu: The VCPU to receive the undefined exception
 * @addr: The address to report in the DFAR
 *
 * It is assumed that this code is called from the VCPU thread and that the
 * VCPU therefore is not currently executing guest code.
 */
void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
{
 if (!(vcpu->arch.hcr_el2 & HCR_RW))
  inject_abt32(vcpu, false, addr);
 else
  inject_abt64(vcpu, false, addr);
}


>
>
> Thanks,
>
> James

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-06-04 11:59 Yury Norov
  0 siblings, 0 replies; 409+ messages in thread
From: Yury Norov @ 2017-06-04 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [PATCH v7 resend 2 00/20] ILP32 for ARM64

Hi Catalin,
 
Here is a rebase of latest kernel patchset against next-20170602. There's almost
no changes, but there are some conflicts that are not trivial, and I'd like to
refresh the submission therefore.

How are your experiments with testing and benchmarking of ILP32 are going? In
my current tests I see 0 failures on LTP. Benchmarking on SPEC CPU2006 and
LMBench shows no difference for LP64 and expected performance boost for ILP32
(compared to LP64 results).

Steve Ellcey is handling upstream submission of Glibc patches. The patches are
ready and have been reviewed and reworked per community?s comments. There are
no outstanding userspace ABI issues from Glibc. Glibc submission is now waiting
on ILP32 kernel submission.

Catalin, regarding rootfs, is OpenSuSe?s build sufficient for your experiments?
I?ve also seen Wookey merging patches for ILP32 triplet to binutils and pushing
them to Debian.

One last thing I wanted to check with you about is ILP32 PCS - does, in your
view, ARM Ltd. needs to publish any additional docs for ABI to become official?

Below is the regular description.

Thanks.
Yury

--------

This series enables aarch64 with ilp32 mode.

As supporting work, it introduces ARCH_32BIT_OFF_T configuration
option that is enabled for existing 32-bit architectures but disabled
for new arches (so 64-bit off_t is is used by new userspace). Also it
deprecates getrlimit and setrlimit syscalls prior to prlimit64.

This version is based on linux-next from 2017-03-01. It works with
glibc-2.25, and tested with LTP, glibc testsuite, trinity, lmbench,
CPUSpec.

Patches 1, 2, 3 and 8 are general, and may be applied separately.

This is the rebase of v7 - still no major changes has been made.

Kernel and GLIBC trees:
https://github.com/norov/linux/tree/ilp32-20170602
https://github.com/norov/glibc/tree/dev9

(GLIBC patches are managed by Steve Ellcey, so my tree is only for
reference.)

Changes:
v3: https://lkml.org/lkml/2014/9/3/704
v4: https://lkml.org/lkml/2015/4/13/691
v5: https://lkml.org/lkml/2015/9/29/911
v6: https://lkml.org/lkml/2016/5/23/661
v7: RFC nowrap:  https://lkml.org/lkml/2016/6/17/990
v7: RFC2 nowrap: https://lkml.org/lkml/2016/8/17/245
v7: RFC3 nowrap: https://lkml.org/lkml/2016/10/21/883
v7: https://lkml.org/lkml/2017/1/9/213
v7: Resend: http://lists.infradead.org/pipermail/linux-arm-kernel/2017-March/490801.html
v7: Resend 2:
    - vdso-ilp32 Makefile synced with lp64 Makefile (patch 19);
    - rebased on next-20170602.

Andrew Pinski (6):
  arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  arm64: ensure the kernel is compiled for LP64
  arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
  arm64: ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
    it
  arm64: ilp32: introduce ilp32-specific handlers for sigframe and
    ucontext
  arm64:ilp32: add ARM64_ILP32 to Kconfig

Philipp Tomsich (1):
  arm64:ilp32: add vdso-ilp32 and use for signal return

Yury Norov (13):
  compat ABI: use non-compat openat and open_by_handle_at variants
  32-bit ABI: introduce ARCH_32BIT_OFF_T config option
  asm-generic: Drop getrlimit and setrlimit syscalls from default list
  arm64: ilp32: add documentation on the ILP32 ABI for ARM64
  thread: move thread bits accessors to separated file
  arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
  arm64: introduce binfmt_elf32.c
  arm64: ilp32: introduce binfmt_ilp32.c
  arm64: ilp32: share aarch32 syscall handlers
  arm64: signal: share lp64 signal routines to ilp32
  arm64: signal32: move ilp32 and aarch32 common code to separated file
  arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32

 Documentation/arm64/ilp32.txt                 |  45 +++++++
 arch/Kconfig                                  |   4 +
 arch/arc/Kconfig                              |   1 +
 arch/arc/include/uapi/asm/unistd.h            |   1 +
 arch/arm/Kconfig                              |   1 +
 arch/arm64/Kconfig                            |  19 ++-
 arch/arm64/Makefile                           |   8 ++
 arch/arm64/include/asm/compat.h               |  19 +--
 arch/arm64/include/asm/elf.h                  |  37 ++----
 arch/arm64/include/asm/fpsimd.h               |   2 +-
 arch/arm64/include/asm/ftrace.h               |   2 +-
 arch/arm64/include/asm/hwcap.h                |   6 +-
 arch/arm64/include/asm/is_compat.h            |  90 ++++++++++++++
 arch/arm64/include/asm/memory.h               |   5 +-
 arch/arm64/include/asm/processor.h            |  11 +-
 arch/arm64/include/asm/ptrace.h               |   2 +-
 arch/arm64/include/asm/seccomp.h              |   2 +-
 arch/arm64/include/asm/signal32.h             |   9 +-
 arch/arm64/include/asm/signal32_common.h      |  27 ++++
 arch/arm64/include/asm/signal_common.h        |  33 +++++
 arch/arm64/include/asm/signal_ilp32.h         |  38 ++++++
 arch/arm64/include/asm/syscall.h              |   2 +-
 arch/arm64/include/asm/thread_info.h          |   4 +-
 arch/arm64/include/asm/unistd.h               |   6 +-
 arch/arm64/include/asm/vdso.h                 |   6 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |   9 +-
 arch/arm64/include/uapi/asm/unistd.h          |  13 ++
 arch/arm64/kernel/Makefile                    |   8 +-
 arch/arm64/kernel/asm-offsets.c               |   9 +-
 arch/arm64/kernel/binfmt_elf32.c              |  38 ++++++
 arch/arm64/kernel/binfmt_ilp32.c              |  85 +++++++++++++
 arch/arm64/kernel/cpufeature.c                |   8 +-
 arch/arm64/kernel/cpuinfo.c                   |  20 +--
 arch/arm64/kernel/entry.S                     |  34 +++++-
 arch/arm64/kernel/entry32.S                   |  80 ------------
 arch/arm64/kernel/entry32_common.S            | 107 ++++++++++++++++
 arch/arm64/kernel/entry_ilp32.S               |  22 ++++
 arch/arm64/kernel/head.S                      |   2 +-
 arch/arm64/kernel/hw_breakpoint.c             |   8 +-
 arch/arm64/kernel/perf_regs.c                 |   2 +-
 arch/arm64/kernel/process.c                   |   7 +-
 arch/arm64/kernel/ptrace.c                    |  80 ++++++++++--
 arch/arm64/kernel/signal.c                    | 102 ++++++++++------
 arch/arm64/kernel/signal32.c                  | 107 ----------------
 arch/arm64/kernel/signal32_common.c           | 135 ++++++++++++++++++++
 arch/arm64/kernel/signal_ilp32.c              | 170 ++++++++++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c                 | 100 +++++++++++++++
 arch/arm64/kernel/traps.c                     |   5 +-
 arch/arm64/kernel/vdso-ilp32/.gitignore       |   2 +
 arch/arm64/kernel/vdso-ilp32/Makefile         |  80 ++++++++++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     |  33 +++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S |  95 ++++++++++++++
 arch/arm64/kernel/vdso.c                      |  69 +++++++++--
 arch/arm64/kernel/vdso/gettimeofday.S         |  20 ++-
 arch/arm64/kernel/vdso/vdso.S                 |   6 +-
 arch/blackfin/Kconfig                         |   1 +
 arch/c6x/include/uapi/asm/unistd.h            |   1 +
 arch/cris/Kconfig                             |   1 +
 arch/frv/Kconfig                              |   1 +
 arch/h8300/Kconfig                            |   1 +
 arch/h8300/include/uapi/asm/unistd.h          |   1 +
 arch/hexagon/Kconfig                          |   1 +
 arch/hexagon/include/uapi/asm/unistd.h        |   1 +
 arch/m32r/Kconfig                             |   1 +
 arch/m68k/Kconfig                             |   1 +
 arch/metag/Kconfig                            |   1 +
 arch/metag/include/uapi/asm/unistd.h          |   1 +
 arch/microblaze/Kconfig                       |   1 +
 arch/mips/Kconfig                             |   1 +
 arch/mn10300/Kconfig                          |   1 +
 arch/nios2/Kconfig                            |   1 +
 arch/nios2/include/uapi/asm/unistd.h          |   1 +
 arch/openrisc/Kconfig                         |   1 +
 arch/openrisc/include/uapi/asm/unistd.h       |   1 +
 arch/parisc/Kconfig                           |   1 +
 arch/powerpc/Kconfig                          |   1 +
 arch/score/Kconfig                            |   1 +
 arch/score/include/uapi/asm/unistd.h          |   1 +
 arch/sh/Kconfig                               |   1 +
 arch/sparc/Kconfig                            |   1 +
 arch/tile/Kconfig                             |   1 +
 arch/tile/include/uapi/asm/unistd.h           |   1 +
 arch/tile/kernel/compat.c                     |   3 +
 arch/unicore32/Kconfig                        |   1 +
 arch/unicore32/include/uapi/asm/unistd.h      |   1 +
 arch/x86/Kconfig                              |   1 +
 arch/x86/um/Kconfig                           |   1 +
 arch/xtensa/Kconfig                           |   1 +
 drivers/clocksource/arm_arch_timer.c          |   2 +-
 include/linux/fcntl.h                         |   2 +-
 include/linux/thread_bits.h                   |  63 ++++++++++
 include/linux/thread_info.h                   |  66 ++--------
 include/uapi/asm-generic/unistd.h             |  10 +-
 93 files changed, 1601 insertions(+), 413 deletions(-)
 create mode 100644 Documentation/arm64/ilp32.txt
 create mode 100644 arch/arm64/include/asm/is_compat.h
 create mode 100644 arch/arm64/include/asm/signal32_common.h
 create mode 100644 arch/arm64/include/asm/signal_common.h
 create mode 100644 arch/arm64/include/asm/signal_ilp32.h
 create mode 100644 arch/arm64/kernel/binfmt_elf32.c
 create mode 100644 arch/arm64/kernel/binfmt_ilp32.c
 create mode 100644 arch/arm64/kernel/entry32_common.S
 create mode 100644 arch/arm64/kernel/entry_ilp32.S
 create mode 100644 arch/arm64/kernel/signal32_common.c
 create mode 100644 arch/arm64/kernel/signal_ilp32.c
 create mode 100644 arch/arm64/kernel/sys_ilp32.c
 create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
 create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
 create mode 100644 include/linux/thread_bits.h

-- 
2.11.0

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-06-06  7:19 From Lori J. Robinson
  0 siblings, 0 replies; 409+ messages in thread
From: From Lori J. Robinson @ 2017-06-06  7:19 UTC (permalink / raw)
  To: linux-security-module

Hello,

I am General Lori J. Robinson, I am presently in Afghanistan serving
the UN/NATO military assignment here,i have an important discussion
with you  kindly respond to me through my private  box
lori_robinson.usa at hotmail.com  so that we can know ourselves better. I
hope to read from you if your are also interested. Thanks and hoping
to hear from you soonest.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2017-06-26 13:16 [PATCH] arm64: use readq() instead of readl() to read 64bit entry_point Luc Van Oostenryck
@ 2017-07-03 23:46 ` Khuong Dinh
  0 siblings, 0 replies; 409+ messages in thread
From: Khuong Dinh @ 2017-07-03 23:46 UTC (permalink / raw)
  To: linux-arm-kernel

It is good with X-Gene 1/2.

Tested-by: Khuong Dinh <kdinh@apm.com>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-08-22  1:38 Nicholas Piggin
  0 siblings, 0 replies; 409+ messages in thread
From: Nicholas Piggin @ 2017-08-22  1:38 UTC (permalink / raw)
  To: linux-arm-kernel

Date: Sun, 20 Aug 2017 13:16:16 +1000
Subject: [PATCH] timers: Fix excessive granularity of new timers after a nohz
 idle

When a timer base is idle, it is forwarded when a new timer is added
to ensure that granularity does not become excessive. When not idle,
the timer tick is expected to increment the base.

However there are several problems:

- If an existing timer is modified, the base is forwarded only after
  the index is calculated.

- The base is not forwarded by add_timer_on.

- There is a window after a timer is restarted from a nohz ide, after
  it is marked not-idle and before the timer tick on this CPU, where a
  timer may be added but the ancient base does not get forwarded.

These result in excessive granularity (a 1 jiffy timeout can blow out
to 100s of jiffies), which cause the rcu lockup detector to trigger,
among other things.

Fix this by keeping track of whether the timer base has been idle
since it was last run or forwarded, and if so then forward it before
adding a new timer.

There is still a problem where the mod_timer optimization where it's
modified with the same expiry time can result in excessive granularity
relative to the new shorter interval. That is not addressed by this
patch because checking base->was_idle would increase overhead and it's
a rather special case (you could reason that the caller should not
expect change in absolute expiry time due to such an operation). So
that is noted as a comment.

As well as fixing the visible RCU softlockup failures, I tested an
idle system (with no lockup watchdogs running) and traced all
non-deferrable timer expiries for 1000s, and analysed wakeup latency
relative to requested latency.  1.0 means we slept for as many jiffies
as requested, 2.0 means we slept 2x the time (this suffers jiffies
round-up skew at low absolute times):

             max     avg      std
upstream   506.0    1.20     4.68
patched      2.0    1.08     0.15

This was noticed due to the lockup detector Kconfig changes dropping it
out of people's .configs. When the lockup detectors are enabled, no CPU
can go idle for longer than 4 seconds, which limits the granularity
errors. Sub-optimal timer behaviour is observable on a smaller scale:

             max     avg      std
upstream     9.0    1.05     0.19
patched      2.0    1.04     0.11

Tested-by: David Miller <davem@davemloft.net>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---

Hi Andrew,

I would have preferred to get comments from the timer maintainers, but
they've been busy or away for the past copule of weeks. Perhaps you
would consider carrying it until then?

Thanks,
Nick

 kernel/time/timer.c | 44 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 8f5d1bf18854..dd7be9fe6839 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -203,6 +203,7 @@ struct timer_base {
 	bool			migration_enabled;
 	bool			nohz_active;
 	bool			is_idle;
+	bool			was_idle; /* was it idle since last run/fwded */
 	DECLARE_BITMAP(pending_map, WHEEL_SIZE);
 	struct hlist_head	vectors[WHEEL_SIZE];
 } ____cacheline_aligned;
@@ -856,13 +857,19 @@ get_target_base(struct timer_base *base, unsigned tflags)
 
 static inline void forward_timer_base(struct timer_base *base)
 {
-	unsigned long jnow = READ_ONCE(jiffies);
+	unsigned long jnow;
 
 	/*
-	 * We only forward the base when it's idle and we have a delta between
-	 * base clock and jiffies.
+	 * We only forward the base when we are idle or have just come out
+	 * of idle (was_idle logic), and have a delta between base clock
+	 * and jiffies. In the common case, run_timers will take care of it.
 	 */
-	if (!base->is_idle || (long) (jnow - base->clk) < 2)
+	if (likely(!base->was_idle))
+		return;
+
+	jnow = READ_ONCE(jiffies);
+	base->was_idle = base->is_idle;
+	if ((long)(jnow - base->clk) < 2)
 		return;
 
 	/*
@@ -938,6 +945,13 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
 	 * same array bucket then just return:
 	 */
 	if (timer_pending(timer)) {
+		/*
+		 * The downside of this optimization is that it can result in
+		 * larger granularity than you would get from adding a new
+		 * timer with this expiry. Would a timer flag for networking
+		 * be appropriate, then we can try to keep expiry of general
+		 * timers within ~1/8th of their interval?
+		 */
 		if (timer->expires == expires)
 			return 1;
 
@@ -948,6 +962,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
 		 * dequeue/enqueue dance.
 		 */
 		base = lock_timer_base(timer, &flags);
+		forward_timer_base(base);
 
 		clk = base->clk;
 		idx = calc_wheel_index(expires, clk);
@@ -964,6 +979,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
 		}
 	} else {
 		base = lock_timer_base(timer, &flags);
+		forward_timer_base(base);
 	}
 
 	ret = detach_if_pending(timer, base, false);
@@ -991,12 +1007,10 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
 			raw_spin_lock(&base->lock);
 			WRITE_ONCE(timer->flags,
 				   (timer->flags & ~TIMER_BASEMASK) | base->cpu);
+			forward_timer_base(base);
 		}
 	}
 
-	/* Try to forward a stale timer base clock */
-	forward_timer_base(base);
-
 	timer->expires = expires;
 	/*
 	 * If 'idx' was calculated above and the base time did not advance
@@ -1112,6 +1126,7 @@ void add_timer_on(struct timer_list *timer, int cpu)
 		WRITE_ONCE(timer->flags,
 			   (timer->flags & ~TIMER_BASEMASK) | cpu);
 	}
+	forward_timer_base(base);
 
 	debug_activate(timer, timer->expires);
 	internal_add_timer(base, timer);
@@ -1499,8 +1514,10 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
 		/*
 		 * If we expect to sleep more than a tick, mark the base idle:
 		 */
-		if ((expires - basem) > TICK_NSEC)
+		if ((expires - basem) > TICK_NSEC) {
+			base->was_idle = true;
 			base->is_idle = true;
+		}
 	}
 	raw_spin_unlock(&base->lock);
 
@@ -1611,6 +1628,17 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h)
 {
 	struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
 
+	/*
+	 * was_idle must be cleared before running timers so that any timer
+	 * functions that call mod_timer will not try to forward the base.
+	 *
+	 * The deferrable base does not do idle tracking at all, so we do
+	 * not forward it. This can result in very large variations in
+	 * granularity for deferrable timers, but they can be deferred for
+	 * long periods due to idle.
+	 */
+	base->was_idle = false;
+
 	__run_timers(base);
 	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active)
 		__run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]));
-- 
2.13.3

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2017-09-13 18:15 unmesh rathi
  0 siblings, 0 replies; 409+ messages in thread
From: unmesh rathi @ 2017-09-13 18:15 UTC (permalink / raw)




^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2017-11-30 10:25 Mary Cuevas
  0 siblings, 0 replies; 409+ messages in thread
From: Mary Cuevas @ 2017-11-30 10:25 UTC (permalink / raw)
  To: linux-arm-kernel


Open
Sent from my iPhone

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-02-02  6:54 Jianchao Wang
  0 siblings, 0 replies; 409+ messages in thread
From: Jianchao Wang @ 2018-02-02  6:54 UTC (permalink / raw)


Hi Christoph, Keith and Sagi

Please consider and comment on the following patchset.
That's really appreciated.

There is a complicated relationship between nvme_timeout and nvme_dev_disable.
 - nvme_timeout has to invoke nvme_dev_disable to stop the
   controller doing DMA access before free the request.
 - nvme_dev_disable has to depend on nvme_timeout to complete
   adminq requests to set HMB or delete sq/cq when the controller
   has no response.
 - nvme_dev_disable will race with nvme_timeout when cancels the
   outstanding requests.
We have found some issues introduced by them, please refer the following link

http://lists.infradead.org/pipermail/linux-nvme/2018-January/015053.html 
http://lists.infradead.org/pipermail/linux-nvme/2018-January/015276.html
http://lists.infradead.org/pipermail/linux-nvme/2018-January/015328.html
Even we cannot ensure there is no other issue.

The best way to fix them is to break up the relationship between them.
With this patch, we could avoid nvme_dev_disable to be invoked
by nvme_timeout and eliminate the race between nvme_timeout and
nvme_dev_disable on outstanding requests.


There are 6 patches:

1st ~ 3th patches does some preparation for the 4th one.
4th is to avoid nvme_dev_disable to be invoked by nvme_timeout, and implement
the synchronization between them. More details, please refer to the comment of
this patch.
5th fixes a bug after 4th patch is introduced. It let nvme_delete_io_queues can
only be wakeup by completion path.
6th fixes a bug found when test, it is not related with 4th patch.

This patchset was tested under debug patch for some days.
And some bugfix have been done.
The debug patch and other patches are available in following it branch:
https://github.com/jianchwa/linux-blcok.git nvme_fixes_test

Jianchao Wang (6)
0001-nvme-pci-move-clearing-host-mem-behind-stopping-queu.patch
0002-nvme-pci-fix-the-freeze-and-quiesce-for-shutdown-and.patch
0003-blk-mq-make-blk_mq_rq_update_aborted_gstate-a-extern.patch
0004-nvme-pci-break-up-nvme_timeout-and-nvme_dev_disable.patch
0005-nvme-pci-discard-wait-timeout-when-delete-cq-sq.patch
0006-nvme-pci-suspend-queues-based-on-online_queues.patch

diff stat following:
 block/blk-mq.c          |   3 +-
 drivers/nvme/host/pci.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
 include/linux/blk-mq.h  |   1 +
 3 files changed, 169 insertions(+), 60 deletions(-)

Thanks
Jianchao

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-02-25  0:39 J Freyensee
  0 siblings, 0 replies; 409+ messages in thread
From: J Freyensee @ 2018-02-25  0:39 UTC (permalink / raw)
  To: linux-security-module

        auth fc300131 subscribe linux-security-module \
         why2jjj.linux at gmail.com

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-04-16  1:22 Andrew Worsley
  0 siblings, 0 replies; 409+ messages in thread
From: Andrew Worsley @ 2018-04-16  1:22 UTC (permalink / raw)
  To: linux-arm-kernel


  This patch clears the remaining i2c buffer overrun problems that I see in my
hardware.  When run at 200kHz over 2 days and 17 hours there were *NO* faults seen
despite continously accessing the all the i2c devices. I feel the remaining issues
are related to the TPM not behaving properly at clock speeds of 285kHz or higher.
The other i2c hardware is fine up to maximum 400khz.  At these higher clock speeds
the TPM appears to fall behind and I see SDA held low after the TPM read and the
driver report bus arbitration lost errors.  Eventually the TPM completely stops
responding and SDA is held low. But accessing the other i2c hardware causes more
i2c clock pulses which lets the SDA go high again then the other i2c devices work
with out problems which further confirms our thinking that the TPM is source of the
remaining i2c problems.

  With the additional i2c fixes in the attached patch the Xilinx i2c driver
is working with out problems on our hardware. I recommend you consider adding these
changes which apply on top of the previous fixes that I sent.

  Thanks

        Andrew Worsley

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-04-20  8:02 ` Christoph Hellwig
  0 siblings, 0 replies; 409+ messages in thread
From: Christoph Hellwig @ 2018-04-20  8:02 UTC (permalink / raw)
  To: linux-snps-arc

To: iommu at lists.linux-foundation.org
Cc: linux-arch at vger.kernel.org
Cc: Michal Simek <monstr at monstr.eu>
Cc: Greentime Hu <green.hu at gmail.com>
Cc: Vincent Chen <deanbo422 at gmail.com>
Cc: linux-alpha at vger.kernel.org
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-c6x-dev at linux-c6x.org
Cc: linux-hexagon at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: nios2-dev at lists.rocketboards.org
Cc: openrisc at lists.librecores.org
Cc: linux-parisc at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-xtensa at linux-xtensa.org
Cc: linux-kernel at vger.kernel.org
Subject: [RFC] common non-cache coherent direct dma mapping ops

Hi all,

this series continues consolidating the dma-mapping code, with a focus
on architectures that do not (always) provide cache coherence for DMA.
Three architectures (arm, mips and powerpc) are still left to be
converted later due to complexity of their dma ops selection.

The dma-noncoherent ops calls the dma-direct ops for the actual
translation of streaming mappins and allow the architecture to provide
any cache flushing required for cpu to device and/or device to cpu
ownership transfers.  The dma coherent allocator is for now still left
entirely to architecture supplied implementations due the amount of
variations.  Hopefully we can do some consolidation for them later on
as well.

A lot of architectures are currently doing very questionable things
in their dma mapping routines, which are documented in the changelogs
for each patch.  Please review them very careful and correct me on
incorrect assumptions.

Because this series sits on top of two previously submitted series
a git tree might be useful to actually test it.  It is provided here:

    git://git.infradead.org/users/hch/misc.git generic-dma-noncoherent

Gitweb:

    http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/generic-dma-noncoherent

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-04-20  8:02 ` Christoph Hellwig
  0 siblings, 0 replies; 409+ messages in thread
From: Christoph Hellwig @ 2018-04-20  8:02 UTC (permalink / raw)
  To: linux-arm-kernel

To: iommu at lists.linux-foundation.org
Cc: linux-arch at vger.kernel.org
Cc: Michal Simek <monstr@monstr.eu>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Cc: linux-alpha at vger.kernel.org
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-c6x-dev at linux-c6x.org
Cc: linux-hexagon at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: nios2-dev at lists.rocketboards.org
Cc: openrisc at lists.librecores.org
Cc: linux-parisc at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-xtensa at linux-xtensa.org
Cc: linux-kernel at vger.kernel.org
Subject: [RFC] common non-cache coherent direct dma mapping ops

Hi all,

this series continues consolidating the dma-mapping code, with a focus
on architectures that do not (always) provide cache coherence for DMA.
Three architectures (arm, mips and powerpc) are still left to be
converted later due to complexity of their dma ops selection.

The dma-noncoherent ops calls the dma-direct ops for the actual
translation of streaming mappins and allow the architecture to provide
any cache flushing required for cpu to device and/or device to cpu
ownership transfers.  The dma coherent allocator is for now still left
entirely to architecture supplied implementations due the amount of
variations.  Hopefully we can do some consolidation for them later on
as well.

A lot of architectures are currently doing very questionable things
in their dma mapping routines, which are documented in the changelogs
for each patch.  Please review them very careful and correct me on
incorrect assumptions.

Because this series sits on top of two previously submitted series
a git tree might be useful to actually test it.  It is provided here:

    git://git.infradead.org/users/hch/misc.git generic-dma-noncoherent

Gitweb:

    http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/generic-dma-noncoherent

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-05-04 20:06 Bjorn Helgaas
  0 siblings, 0 replies; 409+ messages in thread
From: Bjorn Helgaas @ 2018-05-04 20:06 UTC (permalink / raw)
  To: linux-arm-kernel

Bcc: 
Subject: Re: [PATCH] PCI: Check whether bridges allow access to extended
 config space
Reply-To: 
In-Reply-To: <5AEC8002.5000309@kontron.com>

[+cc Fred, Sinan]

On Fri, May 04, 2018 at 03:45:07PM +0000, Gilles Buloz wrote:
> Le 04/05/2018 00:31, Bjorn Helgaas a ?crit :
> > [+cc LKML]
> >
> > On Thu, May 03, 2018 at 12:40:27PM +0000, Gilles Buloz wrote:
> >> Subject:    [PATCH] For exception at PCI probe due to bridge reporting UR
> >>
> >> Even if a device supports extended config access, no such access must be
> >> done to this device If there's a bridge not supporting that in the path
> >> to this device. Doing such access with UR reporting enabled on the root
> >> bridge leads to an exception.
> >>
> >> This is the case on a LS1043A CPU (NXP QorIQ Layerscape) platform with
> >> the following bus topology :
> >>    LS1043 PCIe root
> >>      -> PEX8112 PCIe-to-PCI bridge (not supporting ext cfg on PCI side)
> >>        -> PMC slot connector (for legacy PMC modules)
> >> With a PMC module topology as follows :
> >>    PMC connector
> >>      -> PCI-to-PCIe bridge
> >>        -> PCIe switch (4 ports)
> >>          -> 4 PCIe devices (one on each port)
> >> In this case all devices behind the PEX8112 are supporting extended config
> >> access but this is prohibited by the PEX8112. Without this patch, an
> >> exception (synchronous abort) occurs in pci_cfg_space_size_ext().
> >>
> >> This patch checks the parent bridge of each allocated child bus to know if
> >> extended config access is supported on the child bus, and sets a flag in
> >> child->bus_flags if not supported. This  flag is inherited by all children
> >> buses of this child bus and then is checked to avoid this unsupported
> >> accesses to every device on these buses.
> > Hi Gilles,
> >
> > Thanks for the patch!  I reworked it a little bit to simplify the code
> > in pci_alloc_child_bus().  Can you test it and make sure I didn't
> > break anything?
> >
> Hi Bjorn,
> 
> Your rework works as expected. Tested on LS1043A platform with kernel 4.17-rc1, and with some backport on kernel 4.1.35
> 
> Suggestion : maybe change the pci_info() string to have :
>      pci_bus 0000:xx: extended config space not accessible
> instead of
>      pci_bus 0000:xx: extended config space not accessible on secondary bus
> as xx is already the number of the secondary bus

Oops, when I wrote that I was thinking it would be printed for the
bridge device (not the bus).  I changed it as you suggest.

Interesting, I didn't think about the fact that pci_info() would work
on a struct pci_bus * as well as on a struct pci_dev *, since it's a
macro and they both have a "dev" member.

> Info : with kernel 4.17-rc1, it turns out I need pcie_aspm=off to
> have the PMC devices behind the PCI-to-PCIe bridge of the PMC safely
> detected/configured. But this is not caused by the patch.

> Without pcie_aspm=off I saw this at one boot :
>     "pci 0000:02:0e.0: ASPM: Could not configure common clock" for this bridge, but devices
>     correctly detected/configured
> but at most boots I get :
>     no ASPM message but "pci 0000:04:02.0: bridge configuration invalid ([bus ff-ff]), reconfiguring "
>     instead, and some devices are missing. Also lspci show "rev ff" for some devices.
> I don't see this problem on 4.1.35 with the same backported patch.

This is interesting, especially since you have this unusual topology
of a path to the device that is PCIe, then conventional PCI, then PCIe
again.  We *should* be able to use ASPM on the PCIe links, but it's
definitely not a well-tested scenario.

Can you tell if something is actually broken?  Sinan's recent change,
04875177dbe0 ("PCI/ASPM: Don't warn if already in common clock mode"),
which appeared in v4.17-rc1, turns off the message in some cases.

The "bridge configuration invalid" message just means the firmware
didn't configure the bridge.  We *should* still set it up correctly,
but please report a bug if we don't.

lspci showing "ff" for some devices might be a symptom of the devices
being powered off.  In that case config reads normally return ~0 data
(though on your platform maybe it would cause exceptions).  I've seen
this in other situations and wondered if it would be worth adding a
hint to lspci so it could say "device may be powered off".

Anyway, if you are seeing something broken (more than just the
messages), please start a new thread about each one.  If you do, could
you please:

  - open a report at https://bugzilla.kernel.org/, in the Drivers/PCI
    component (open a separate bug for each issue you see)

  - use kernel version 4.17-rc1 and mark it as a regression if
    appropriate

  - attach (don't paste inline) the complete dmesg log and "lspci -vv"
    output (as root) to the bug

  - post a note to linux-pci at vger.kernel.org, cc Fred, Sinan, and me,
    and include the link to the bugzilla

Bjorn

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-05-08  6:10 Vishnu Gopinath
  0 siblings, 0 replies; 409+ messages in thread
From: Vishnu Gopinath @ 2018-05-08  6:10 UTC (permalink / raw)
  To: kernelnewbies

new in the field of linux kernal... how to start..from where to start
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180508/10f1e928/attachment.html>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-06-23 21:08 David Lechner
  0 siblings, 0 replies; 409+ messages in thread
From: David Lechner @ 2018-06-23 21:08 UTC (permalink / raw)
  To: linux-arm-kernel


Date: Sat, 23 Jun 2018 15:43:59 -0500
Subject: [PATCH 0/8] New remoteproc driver for TI PRU

This series adds a new remoteproc driver for the TI Programmable Runtime Unit
(PRU) that is present in some TI Sitara processors. This code has been tested
working on AM1808 (LEGO MINDSTORMS EV3) and AM3358 (BeagleBone Green).

There are a couple of quirks that had to be worked around in order to get this
working. The PRU units have multiple memory maps. Notably, both the instruction
RAM and data RAM are at address 0x0. This caused the da_to_va callback to not
work because the same address could refer to two different locations. To work
around this, the first two patches add a "map" parameter to the da_to_va
callbacks so that we have an extra bit of information to make this distinction.

Also, on AM38xx we have to use pdata for accessing a reset since there is not
a reset controller. There are several other devices doing this, so the seems
the best way for now.

For anyone else who would like to test, I used the rpmsg-client-sample driver.
Just enable it in your kernel config. Then grab the appropriate firmware[1]
and put in in /lib/firmware/. Use sysfs to start and stop the PRU:

        echo start > /sys/class/remoteproc<n>/state
        echo stop > /sys/class/remoteproc<n>/state

[1]: firmware downloads:

AM18XX: https://github.com/ev3dev/ev3dev-pru-firmware/releases/download/mainline-kernel-testing/AM18xx-PRU-rpmsg-client-sample.zip
AM335X: https://github.com/ev3dev/ev3dev-pru-firmware/releases/download/mainline-kernel-testing/AM335x-PRU-rpmsg-client-sample.zip

David Lechner (8):
  remoteproc: add map parameter to da_to_va
  remoteproc: add page lookup for TI PRU to ELF loader
  ARM: OMAP2+: add pdata quirks for PRUSS reset
  dt-bindings: add bindings for TI PRU as remoteproc
  remoteproc: new driver for TI PRU
  ARM: davinci_all_defconfig: enable PRU remoteproc module
  ARM: dts: da850: add node for PRUSS
  ARM: dts: am33xx: add node for PRU remoteproc

 .../bindings/remoteproc/ti_pru_rproc.txt      |  51 ++
 MAINTAINERS                                   |   5 +
 arch/arm/boot/dts/am33xx.dtsi                 |   9 +
 arch/arm/boot/dts/da850.dtsi                  |   8 +
 arch/arm/configs/davinci_all_defconfig        |   2 +
 arch/arm/mach-omap2/pdata-quirks.c            |   9 +
 drivers/remoteproc/Kconfig                    |   7 +
 drivers/remoteproc/Makefile                   |   1 +
 drivers/remoteproc/imx_rproc.c                |   2 +-
 drivers/remoteproc/keystone_remoteproc.c      |   3 +-
 drivers/remoteproc/qcom_adsp_pil.c            |   2 +-
 drivers/remoteproc/qcom_q6v5_pil.c            |   2 +-
 drivers/remoteproc/qcom_wcnss.c               |   2 +-
 drivers/remoteproc/remoteproc_core.c          |  10 +-
 drivers/remoteproc/remoteproc_elf_loader.c    | 117 +++-
 drivers/remoteproc/remoteproc_internal.h      |   2 +-
 drivers/remoteproc/st_slim_rproc.c            |   2 +-
 drivers/remoteproc/ti_pru_rproc.c             | 660 ++++++++++++++++++
 drivers/remoteproc/wkup_m3_rproc.c            |   3 +-
 include/linux/platform_data/ti-pruss.h        |  18 +
 include/linux/remoteproc.h                    |   2 +-
 include/uapi/linux/elf-em.h                   |   1 +
 22 files changed, 899 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/ti_pru_rproc.txt
 create mode 100644 drivers/remoteproc/ti_pru_rproc.c
 create mode 100644 include/linux/platform_data/ti-pruss.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-07-06  5:52 inventsekar
  0 siblings, 0 replies; 409+ messages in thread
From: inventsekar @ 2018-07-06  5:52 UTC (permalink / raw)
  To: kernelnewbies

Dear All,....

so I was reading on Quora....
https://www.quora.com/What-are-some-features-that-Linus-Torvalds-dismissed-from-the-Linux-kernel

Signing Linux kernel with Microsoft secure boot keys for UEFI. That was
suggested by RedHat developers and Linus flipped them off in his
character...
I went to that link and read two three times, but I could not understand.


Could you explain this above issue, on a newbies perspective.


Best regards, sekar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180706/6727e55a/attachment-0001.html>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-07-06 21:16 Santosh Shilimkar
  2018-07-06 21:16 ` Santosh Shilimkar
  2018-07-06 21:16 ` Santosh Shilimkar
  0 siblings, 2 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2018-07-06 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [GIT PULL 1/3] ARM: Keystone DTS update for v4.19

The following changes since commit ce397d215ccd07b8ae3f71db689aedb85d56ab40:

  Linux 4.18-rc1 (2018-06-17 08:04:49 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone_dts_for_4.19

for you to fetch changes up to f7e8a182a41e791cca3d7a9e25adddf2908bddde:

  ARM: dts: keystone-k2g-evm: Use sdhci-omap programming model (2018-06-29 15:57:27 -0700)

----------------------------------------------------------------
ARM: Keystone DTS updates for 4.19

 - K2G NIC drriver support
 - Enbale network support for K2G ICE and EVM boards
 - Hardware Ring driver support for k2hk, k2l and k2e socs
 - Add MMC supply for k2g EVM

----------------------------------------------------------------
Kishon Vijay Abraham I (2):
      ARM: dts: keystone-k2g-evm: Add "vqmmc-supply" property for mmc0/mmc1
      ARM: dts: keystone-k2g-evm: Use sdhci-omap programming model

Murali Karicheri (3):
      ARM: dts: k2g: add dt bindings to support network driver
      ARM: dts: keystone-k2g-evm: Enable netcp network driver
      ARM: dts: keystone-k2g-ice: Enable netcp network driver

Vitaly Andrianov (3):
      ARM: dts: k2hk: add dts node for k2hk hw_rng driver
      ARM: dts: k2l: add dts node for k2l hw_rng driver
      ARM: dts: k2e: add dts node for k2e hw_rng driver

 arch/arm/boot/dts/keystone-k2e-netcp.dtsi  |  20 ++++
 arch/arm/boot/dts/keystone-k2g-evm.dts     |  63 +++++++++++++
 arch/arm/boot/dts/keystone-k2g-ice.dts     |  59 ++++++++++++
 arch/arm/boot/dts/keystone-k2g-netcp.dtsi  | 147 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/keystone-k2g.dtsi        |  25 +++--
 arch/arm/boot/dts/keystone-k2hk-netcp.dtsi |  20 ++++
 arch/arm/boot/dts/keystone-k2l-netcp.dtsi  |  20 ++++
 7 files changed, 346 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/boot/dts/keystone-k2g-netcp.dtsi

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2018-07-06 21:16 Santosh Shilimkar
@ 2018-07-06 21:16 ` Santosh Shilimkar
  2018-07-06 21:16 ` Santosh Shilimkar
  1 sibling, 0 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2018-07-06 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [GIT PULL 2/3] ARM: Keystone config update for v4.19

The following changes since commit ce397d215ccd07b8ae3f71db689aedb85d56ab40:

  Linux 4.18-rc1 (2018-06-17 08:04:49 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone_config_for_4.19

for you to fetch changes up to 60e9343b355118e903a155135f0511918d69e3ac:

  ARM: configs: keystone: Enable CONFIG_MMC_SDHCI_OMAP (2018-06-29 15:57:53 -0700)

----------------------------------------------------------------
ARM: Keystone config updates for 4.19

 - Enable MMC support
 - Enable Micrel and DP83867 phys

----------------------------------------------------------------
Kishon Vijay Abraham I (1):
      ARM: configs: keystone: Enable CONFIG_MMC_SDHCI_OMAP

Murali Karicheri (1):
      ARM: keystone: k2g: enable micrel and dp83867 phys

 arch/arm/configs/keystone_defconfig | 5 +++++
 1 file changed, 5 insertions(+)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2018-07-06 21:16 Santosh Shilimkar
  2018-07-06 21:16 ` Santosh Shilimkar
@ 2018-07-06 21:16 ` Santosh Shilimkar
  2018-07-06 21:18   ` Santosh Shilimkar
  1 sibling, 1 reply; 409+ messages in thread
From: Santosh Shilimkar @ 2018-07-06 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

Subject: [GIT PULL 3/3] SOC: Driver updates for v4.19

The following changes since commit ce397d215ccd07b8ae3f71db689aedb85d56ab40:

  Linux 4.18-rc1 (2018-06-17 08:04:49 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/soc_drivers_for_4.19

for you to fetch changes up to 990c10091db318c7eb7e8935c86b6f7c01585015:

  soc: ti: wkup_m3_ipc: mark PM functions as __maybe_unused (2018-07-06 09:47:51 -0700)

----------------------------------------------------------------
Keystone SOC driver update for 4.19

 -  Add suspend/resume functionality to TI EMIF SRAM driver
 -  Add wakeup M3 RTC self refresh support
 -  Fix for the PM runtime ifdefs

----------------------------------------------------------------
Arnd Bergmann (1):
      soc: ti: wkup_m3_ipc: mark PM functions as __maybe_unused

Dave Gerlach (2):
      memory: ti-emif-sram: Add resume function to recopy sram code
      soc: ti: wkup_m3_ipc: Add wkup_m3_request_wake_src

Keerthy (1):
      soc: ti: wkup_m3_ipc: Add rtc_only with ddr in self refresh mode support

 drivers/memory/ti-emif-pm.c  | 33 +++++++++++++++++++
 drivers/soc/ti/wkup_m3_ipc.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/wkup_m3_ipc.h  |  9 ++++++
 3 files changed, 118 insertions(+)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2018-07-06 21:16 ` Santosh Shilimkar
@ 2018-07-06 21:18   ` Santosh Shilimkar
  0 siblings, 0 replies; 409+ messages in thread
From: Santosh Shilimkar @ 2018-07-06 21:18 UTC (permalink / raw)
  To: linux-arm-kernel

Ignore this.. Will send again with subjects fixed

On 7/6/2018 2:16 PM, Santosh Shilimkar wrote:
> Subject: [GIT PULL 3/3] SOC: Driver updates for v4.19
> 
> The following changes since commit ce397d215ccd07b8ae3f71db689aedb85d56ab40:
> 
>    Linux 4.18-rc1 (2018-06-17 08:04:49 +0900)
> 
> are available in the git repository at:
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/soc_drivers_for_4.19
> 
> for you to fetch changes up to 990c10091db318c7eb7e8935c86b6f7c01585015:
> 
>    soc: ti: wkup_m3_ipc: mark PM functions as __maybe_unused (2018-07-06 09:47:51 -0700)
> 
> ----------------------------------------------------------------
> Keystone SOC driver update for 4.19
> 
>   -  Add suspend/resume functionality to TI EMIF SRAM driver
>   -  Add wakeup M3 RTC self refresh support
>   -  Fix for the PM runtime ifdefs
> 
> ----------------------------------------------------------------
> Arnd Bergmann (1):
>        soc: ti: wkup_m3_ipc: mark PM functions as __maybe_unused
> 
> Dave Gerlach (2):
>        memory: ti-emif-sram: Add resume function to recopy sram code
>        soc: ti: wkup_m3_ipc: Add wkup_m3_request_wake_src
> 
> Keerthy (1):
>        soc: ti: wkup_m3_ipc: Add rtc_only with ddr in self refresh mode support
> 
>   drivers/memory/ti-emif-pm.c  | 33 +++++++++++++++++++
>   drivers/soc/ti/wkup_m3_ipc.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
>   include/linux/wkup_m3_ipc.h  |  9 ++++++
>   3 files changed, 118 insertions(+)
> 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-08-02 10:48 TU PHUNG VAN
  0 siblings, 0 replies; 409+ messages in thread
From: TU PHUNG VAN @ 2018-08-02 10:48 UTC (permalink / raw)
  To: kernelnewbies

S.?
www
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20180802/20565816/attachment.html>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2018-10-05 13:39 Christoph Hellwig
  0 siblings, 0 replies; 409+ messages in thread
From: Christoph Hellwig @ 2018-10-05 13:39 UTC (permalink / raw)


Bcc: 
Subject: [GIT PULL] nvme updates for 4.20
Reply-To: 

A relatively boring merge window:

 - better AEN tracing (Chaitanya)
 - NUMA aware PCIe multipathing (me)
 - RDMA workqueue fixes (Sagi)
 - better bio usage in the target (Sagi)
 - FC rework for target removal (James)
 - better multipath handling of ->queue_rq failures (James)
 - various cleanups (Milan)

The following changes since commit c0aac682fa6590cb660cb083dbc09f55e799d2d2:

  Merge tag 'v4.19-rc6' into for-4.20/block (2018-10-01 08:58:57 -0600)

are available in the Git repository at:

  git://git.infradead.org/nvme.git nvme-4.20

for you to fetch changes up to 2acf70ade79d26b97611a8df52eb22aa33814cd4:

  nvmet-rdma: use a private workqueue for delete (2018-10-05 09:25:18 +0200)

----------------------------------------------------------------
Chaitanya Kulkarni (2):
      nvmet: remove redundant module prefix
      nvme-core: add async event trace helper

Christoph Hellwig (1):
      nvme: take node locality into account when selecting a path

James Smart (3):
      nvmet_fc: support target port removal with nvmet layer
      nvme_fc: add 'nvme_discovery' sysfs attribute to fc transport device
      nvme: call nvme_complete_rq when nvmf_check_ready fails for mpath I/O

Milan P. Gandhi (2):
      nvme: fix typo in nvme_identify_ns_descs
      nvme-fc: fix for a minor typos

Sagi Grimberg (2):
      nvmet: don't split large I/Os unconditionally
      nvmet-rdma: use a private workqueue for delete

 drivers/nvme/host/core.c          |  20 ++++--
 drivers/nvme/host/fabrics.c       |   7 +-
 drivers/nvme/host/fc.c            | 108 +++++++++++++++++++++++++++----
 drivers/nvme/host/multipath.c     |  57 +++++++++++++----
 drivers/nvme/host/nvme.h          |  25 +++-----
 drivers/nvme/host/trace.h         |  28 ++++++++
 drivers/nvme/target/admin-cmd.c   |   2 +-
 drivers/nvme/target/fc.c          | 130 +++++++++++++++++++++++++++++++++++---
 drivers/nvme/target/io-cmd-bdev.c |   9 ++-
 drivers/nvme/target/nvmet.h       |   1 +
 drivers/nvme/target/rdma.c        |  19 ++++--
 include/linux/nvme.h              |   1 +
 12 files changed, 347 insertions(+), 60 deletions(-)

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2019-03-16 11:17 Bharath Vedartham
  0 siblings, 0 replies; 409+ messages in thread
From: Bharath Vedartham @ 2019-03-16 11:17 UTC (permalink / raw)


linux-kernel at vger.kernel.org 
Bcc: 
Subject: [PATCH] staging: erofs: Add whitespace after declaration
Reply-To: 

Fix the checkpatch.pl warning to add a whitespace after declaration
statements.

Signed-off-by: Bharath Vedartham <linux.bhar at gmail.com>
---
 drivers/staging/erofs/inode.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c
index 924b8df..9a36a1f 100644
--- a/drivers/staging/erofs/inode.c
+++ b/drivers/staging/erofs/inode.c
@@ -270,8 +270,8 @@ struct inode *erofs_iget(struct super_block *sb,
 	if (inode->i_state & I_NEW) {
 		int err;
 		struct erofs_vnode *vi = EROFS_V(inode);
-		vi->nid = nid;
 
+		vi->nid = nid;
 		err = fill_inode(inode, isdir);
 		if (likely(!err))
 			unlock_new_inode(inode);
@@ -305,4 +305,3 @@ const struct inode_operations erofs_fast_symlink_iops = {
 #endif
 	.get_acl = erofs_get_acl,
 };
-
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* No subject
@ 2019-03-19 14:41 ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


Date: Tue, 19 Mar 2019 14:45:45 +0200
Subject: [PATCH 0/9] RFC: NVME VFIO mediated device

Hi everyone!

In this patch series, I would like to introduce my take on the problem of doing 
as fast as possible virtualization of storage with emphasis on low latency.

In this patch series I implemented a kernel vfio based, mediated device that 
allows the user to pass through a partition and/or whole namespace to a guest.

The idea behind this driver is based on paper you can find at
https://www.usenix.org/conference/atc18/presentation/peng,

Although note that I stared the development prior to reading this paper, 
independently.

In addition to that implementation is not based on code used in the paper as 
I wasn't being able at that time to make the source available to me.

***Key points about the implementation:***

* Polling kernel thread is used. The polling is stopped after a 
predefined timeout (1/2 sec by default).
Support for all interrupt driven mode is planned, and it shows promising results.

* Guest sees a standard NVME device - this allows to run guest with 
unmodified drivers, for example windows guests.

* The NVMe device is shared between host and guest.
That means that even a single namespace can be split between host 
and guest based on different partitions.

* Simple configuration

*** Performance ***

Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
and both latency and throughput is very similar to SPDK.

Soon I will test this on a better server and nvme device and provide
more formal performance numbers.

Latency numbers:
~80ms - spdk with fio plugin on the host.
~84ms - nvme driver on the host
~87ms - mdev-nvme + nvme driver in the guest

Throughput was following similar pattern as well.

* Configuration example
  $ modprobe nvme mdev_queues=4
  $ modprobe nvme-mdev

  $ UUID=$(uuidgen)
  $ DEVICE='device pci address'
  $ echo $UUID > /sys/bus/pci/devices/$DEVICE/mdev_supported_types/nvme-2Q_V1/create
  $ echo n1p3 > /sys/bus/mdev/devices/$UUID/namespaces/add_namespace #attach host namespace 1 parition 3
  $ echo 11 > /sys/bus/mdev/devices/$UUID/settings/iothread_cpu #pin the io thread to cpu 11

  Afterward boot qemu with
  -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID
  
  Zero configuration on the guest.
  
*** FAQ ***

* Why to make this in the kernel? Why this is better that SPDK

  -> Reuse the existing nvme kernel driver in the host. No new drivers in the guest.
  
  -> Share the NVMe device between host and guest. 
     Even in fully virtualized configurations,
     some partitions of nvme device could be used by guests as block devices 
     while others passed through with nvme-mdev to achieve balance between
     all features of full IO stack emulation and performance.
  
  -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
     can send interrupts to the guest directly without a context 
     switch that can be expensive due to meltdown mitigation.

  -> Is able to utilize interrupts to get reasonable performance. 
     This is only implemented
     as a proof of concept and not included in the patches, 
     but interrupt driven mode shows reasonable performance
     
  -> This is a framework that later can be used to support NVMe devices 
     with more of the IO virtualization built-in 
     (IOMMU with PASID support coupled with device that supports it)

* Why to attach directly to nvme-pci driver and not use block layer IO
  -> The direct attachment allows for better performance, but I will
     check the possibility of using block IO, especially for fabrics drivers.
  
*** Implementation notes ***

*  All guest memory is mapped into the physical nvme device 
   but not 1:1 as vfio-pci would do this.
   This allows very efficient DMA.
   To support this, patch 2 adds ability for a mdev device to listen on 
   guest's memory map events. 
   Any such memory is immediately pinned and then DMA mapped.
   (Support for fabric drivers where this is not possible exits too,
    in which case the fabric driver will do its own DMA mapping)

*  nvme core driver is modified to announce the appearance 
   and disappearance of nvme controllers and namespaces,
   to which the nvme-mdev driver is subscribed.
 
*  nvme-pci driver is modified to expose raw interface of attaching to 
   and sending/polling the IO queues.
   This allows the mdev driver very efficiently to submit/poll for the IO.
   By default one host queue is used per each mediated device.
   (support for other fabric based host drivers is planned)

* The nvme-mdev doesn't assume presence of KVM, thus any VFIO user, including
  SPDK, a qemu running with tccg, ... can use this virtual device.

*** Testing ***

The device was tested with stock QEMU 3.0 on the host,
with host was using 5.0 kernel with nvme-mdev added and the following hardware:
 * QEMU nvme virtual device (with nested guest)
 * Intel DC P3700 on Xeon E5-2620 v2 server
 * Samsung SM981 (in a Thunderbolt enclosure, with my laptop)
 * Lenovo NVME device found in my laptop

The guest was tested with kernel 4.16, 4.18, 4.20 and
the same custom complied kernel 5.0
Windows 10 guest was tested too with both Microsoft's inbox driver and
open source community NVME driver
(https://lists.openfabrics.org/pipermail/nvmewin/2016-December/001420.html)

Testing was mostly done on x86_64, but 32 bit host/guest combination
was lightly tested too.

In addition to that, the virtual device was tested with nested guest,
by passing the virtual device to it,
using pci passthrough, qemu userspace nvme driver, and spdk


PS: I used to contribute to the kernel as a hobby using the
    maximlevitsky at gmail.com address

Maxim Levitsky (9):
  vfio/mdev: add .request callback
  nvme/core: add some more values from the spec
  nvme/core: add NVME_CTRL_SUSPENDED controller state
  nvme/pci: use the NVME_CTRL_SUSPENDED state
  nvme/pci: add known admin effects to augument admin effects log page
  nvme/pci: init shadow doorbell after each reset
  nvme/core: add mdev interfaces
  nvme/core: add nvme-mdev core driver
  nvme/pci: implement the mdev external queue allocation interface

 MAINTAINERS                   |   5 +
 drivers/nvme/Kconfig          |   1 +
 drivers/nvme/Makefile         |   1 +
 drivers/nvme/host/core.c      | 149 +++++-
 drivers/nvme/host/nvme.h      |  55 ++-
 drivers/nvme/host/pci.c       | 385 ++++++++++++++-
 drivers/nvme/mdev/Kconfig     |  16 +
 drivers/nvme/mdev/Makefile    |   5 +
 drivers/nvme/mdev/adm.c       | 873 ++++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/events.c    | 142 ++++++
 drivers/nvme/mdev/host.c      | 491 +++++++++++++++++++
 drivers/nvme/mdev/instance.c  | 802 +++++++++++++++++++++++++++++++
 drivers/nvme/mdev/io.c        | 563 ++++++++++++++++++++++
 drivers/nvme/mdev/irq.c       | 264 ++++++++++
 drivers/nvme/mdev/mdev.h      |  56 +++
 drivers/nvme/mdev/mmio.c      | 591 +++++++++++++++++++++++
 drivers/nvme/mdev/pci.c       | 247 ++++++++++
 drivers/nvme/mdev/priv.h      | 700 +++++++++++++++++++++++++++
 drivers/nvme/mdev/udata.c     | 390 +++++++++++++++
 drivers/nvme/mdev/vcq.c       | 207 ++++++++
 drivers/nvme/mdev/vctrl.c     | 514 ++++++++++++++++++++
 drivers/nvme/mdev/viommu.c    | 322 +++++++++++++
 drivers/nvme/mdev/vns.c       | 356 ++++++++++++++
 drivers/nvme/mdev/vsq.c       | 178 +++++++
 drivers/vfio/mdev/vfio_mdev.c |  11 +
 include/linux/mdev.h          |   4 +
 include/linux/nvme.h          |  88 +++-
 27 files changed, 7375 insertions(+), 41 deletions(-)
 create mode 100644 drivers/nvme/mdev/Kconfig
 create mode 100644 drivers/nvme/mdev/Makefile
 create mode 100644 drivers/nvme/mdev/adm.c
 create mode 100644 drivers/nvme/mdev/events.c
 create mode 100644 drivers/nvme/mdev/host.c
 create mode 100644 drivers/nvme/mdev/instance.c
 create mode 100644 drivers/nvme/mdev/io.c
 create mode 100644 drivers/nvme/mdev/irq.c
 create mode 100644 drivers/nvme/mdev/mdev.h
 create mode 100644 drivers/nvme/mdev/mmio.c
 create mode 100644 drivers/nvme/mdev/pci.c
 create mode 100644 drivers/nvme/mdev/priv.h
 create mode 100644 drivers/nvme/mdev/udata.c
 create mode 100644 drivers/nvme/mdev/vcq.c
 create mode 100644 drivers/nvme/mdev/vctrl.c
 create mode 100644 drivers/nvme/mdev/viommu.c
 create mode 100644 drivers/nvme/mdev/vns.c
 create mode 100644 drivers/nvme/mdev/vsq.c

-- 
2.17.2

^ permalink raw reply	[flat|nested] 409+ messages in thread

* (unknown)
@ 2019-03-19 14:41 ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

Date: Tue, 19 Mar 2019 14:45:45 +0200
Subject: [PATCH 0/9] RFC: NVME VFIO mediated device

Hi everyone!

In this patch series, I would like to introduce my take on the problem of doing 
as fast as possible virtualization of storage with emphasis on low latency.

In this patch series I implemented a kernel vfio based, mediated device that 
allows the user to pass through a partition and/or whole namespace to a guest.

The idea behind this driver is based on paper you can find at
https://www.usenix.org/conference/atc18/presentation/peng,

Although note that I stared the development prior to reading this paper, 
independently.

In addition to that implementation is not based on code used in the paper as 
I wasn't being able at that time to make the source available to me.

***Key points about the implementation:***

* Polling kernel thread is used. The polling is stopped after a 
predefined timeout (1/2 sec by default).
Support for all interrupt driven mode is planned, and it shows promising results.

* Guest sees a standard NVME device - this allows to run guest with 
unmodified drivers, for example windows guests.

* The NVMe device is shared between host and guest.
That means that even a single namespace can be split between host 
and guest based on different partitions.

* Simple configuration

*** Performance ***

Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
and both latency and throughput is very similar to SPDK.

Soon I will test this on a better server and nvme device and provide
more formal performance numbers.

Latency numbers:
~80ms - spdk with fio plugin on the host.
~84ms - nvme driver on the host
~87ms - mdev-nvme + nvme driver in the guest

Throughput was following similar pattern as well.

* Configuration example
  $ modprobe nvme mdev_queues=4
  $ modprobe nvme-mdev

  $ UUID=$(uuidgen)
  $ DEVICE='device pci address'
  $ echo $UUID > /sys/bus/pci/devices/$DEVICE/mdev_supported_types/nvme-2Q_V1/create
  $ echo n1p3 > /sys/bus/mdev/devices/$UUID/namespaces/add_namespace #attach host namespace 1 parition 3
  $ echo 11 > /sys/bus/mdev/devices/$UUID/settings/iothread_cpu #pin the io thread to cpu 11

  Afterward boot qemu with
  -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID
  
  Zero configuration on the guest.
  
*** FAQ ***

* Why to make this in the kernel? Why this is better that SPDK

  -> Reuse the existing nvme kernel driver in the host. No new drivers in the guest.
  
  -> Share the NVMe device between host and guest. 
     Even in fully virtualized configurations,
     some partitions of nvme device could be used by guests as block devices 
     while others passed through with nvme-mdev to achieve balance between
     all features of full IO stack emulation and performance.
  
  -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
     can send interrupts to the guest directly without a context 
     switch that can be expensive due to meltdown mitigation.

  -> Is able to utilize interrupts to get reasonable performance. 
     This is only implemented
     as a proof of concept and not included in the patches, 
     but interrupt driven mode shows reasonable performance
     
  -> This is a framework that later can be used to support NVMe devices 
     with more of the IO virtualization built-in 
     (IOMMU with PASID support coupled with device that supports it)

* Why to attach directly to nvme-pci driver and not use block layer IO
  -> The direct attachment allows for better performance, but I will
     check the possibility of using block IO, especially for fabrics drivers.
  
*** Implementation notes ***

*  All guest memory is mapped into the physical nvme device 
   but not 1:1 as vfio-pci would do this.
   This allows very efficient DMA.
   To support this, patch 2 adds ability for a mdev device to listen on 
   guest's memory map events. 
   Any such memory is immediately pinned and then DMA mapped.
   (Support for fabric drivers where this is not possible exits too,
    in which case the fabric driver will do its own DMA mapping)

*  nvme core driver is modified to announce the appearance 
   and disappearance of nvme controllers and namespaces,
   to which the nvme-mdev driver is subscribed.
 
*  nvme-pci driver is modified to expose raw interface of attaching to 
   and sending/polling the IO queues.
   This allows the mdev driver very efficiently to submit/poll for the IO.
   By default one host queue is used per each mediated device.
   (support for other fabric based host drivers is planned)

* The nvme-mdev doesn't assume presence of KVM, thus any VFIO user, including
  SPDK, a qemu running with tccg, ... can use this virtual device.

*** Testing ***

The device was tested with stock QEMU 3.0 on the host,
with host was using 5.0 kernel with nvme-mdev added and the following hardware:
 * QEMU nvme virtual device (with nested guest)
 * Intel DC P3700 on Xeon E5-2620 v2 server
 * Samsung SM981 (in a Thunderbolt enclosure, with my laptop)
 * Lenovo NVME device found in my laptop

The guest was tested with kernel 4.16, 4.18, 4.20 and
the same custom complied kernel 5.0
Windows 10 guest was tested too with both Microsoft's inbox driver and
open source community NVME driver
(https://lists.openfabrics.org/pipermail/nvmewin/2016-December/001420.html)

Testing was mostly done on x86_64, but 32 bit host/guest combination
was lightly tested too.

In addition to that, the virtual device was tested with nested guest,
by passing the virtual device to it,
using pci passthrough, qemu userspace nvme driver, and spdk


PS: I used to contribute to the kernel as a hobby using the
    maximlevitsky@gmail.com address

Maxim Levitsky (9):
  vfio/mdev: add .request callback
  nvme/core: add some more values from the spec
  nvme/core: add NVME_CTRL_SUSPENDED controller state
  nvme/pci: use the NVME_CTRL_SUSPENDED state
  nvme/pci: add known admin effects to augument admin effects log page
  nvme/pci: init shadow doorbell after each reset
  nvme/core: add mdev interfaces
  nvme/core: add nvme-mdev core driver
  nvme/pci: implement the mdev external queue allocation interface

 MAINTAINERS                   |   5 +
 drivers/nvme/Kconfig          |   1 +
 drivers/nvme/Makefile         |   1 +
 drivers/nvme/host/core.c      | 149 +++++-
 drivers/nvme/host/nvme.h      |  55 ++-
 drivers/nvme/host/pci.c       | 385 ++++++++++++++-
 drivers/nvme/mdev/Kconfig     |  16 +
 drivers/nvme/mdev/Makefile    |   5 +
 drivers/nvme/mdev/adm.c       | 873 ++++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/events.c    | 142 ++++++
 drivers/nvme/mdev/host.c      | 491 +++++++++++++++++++
 drivers/nvme/mdev/instance.c  | 802 +++++++++++++++++++++++++++++++
 drivers/nvme/mdev/io.c        | 563 ++++++++++++++++++++++
 drivers/nvme/mdev/irq.c       | 264 ++++++++++
 drivers/nvme/mdev/mdev.h      |  56 +++
 drivers/nvme/mdev/mmio.c      | 591 +++++++++++++++++++++++
 drivers/nvme/mdev/pci.c       | 247 ++++++++++
 drivers/nvme/mdev/priv.h      | 700 +++++++++++++++++++++++++++
 drivers/nvme/mdev/udata.c     | 390 +++++++++++++++
 drivers/nvme/mdev/vcq.c       | 207 ++++++++
 drivers/nvme/mdev/vctrl.c     | 514 ++++++++++++++++++++
 drivers/nvme/mdev/viommu.c    | 322 +++++++++++++
 drivers/nvme/mdev/vns.c       | 356 ++++++++++++++
 drivers/nvme/mdev/vsq.c       | 178 +++++++
 drivers/vfio/mdev/vfio_mdev.c |  11 +
 include/linux/mdev.h          |   4 +
 include/linux/nvme.h          |  88 +++-
 27 files changed, 7375 insertions(+), 41 deletions(-)
 create mode 100644 drivers/nvme/mdev/Kconfig
 create mode 100644 drivers/nvme/mdev/Makefile
 create mode 100644 drivers/nvme/mdev/adm.c
 create mode 100644 drivers/nvme/mdev/events.c
 create mode 100644 drivers/nvme/mdev/host.c
 create mode 100644 drivers/nvme/mdev/instance.c
 create mode 100644 drivers/nvme/mdev/io.c
 create mode 100644 drivers/nvme/mdev/irq.c
 create mode 100644 drivers/nvme/mdev/mdev.h
 create mode 100644 drivers/nvme/mdev/mmio.c
 create mode 100644 drivers/nvme/mdev/pci.c
 create mode 100644 drivers/nvme/mdev/priv.h
 create mode 100644 drivers/nvme/mdev/udata.c
 create mode 100644 drivers/nvme/mdev/vcq.c
 create mode 100644 drivers/nvme/mdev/vctrl.c
 create mode 100644 drivers/nvme/mdev/viommu.c
 create mode 100644 drivers/nvme/mdev/vns.c
 create mode 100644 drivers/nvme/mdev/vsq.c

-- 
2.17.2

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 1/9] vfio/mdev: add .request callback
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


This will allow the hotplug to be enabled for mediated devices

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/vfio/mdev/vfio_mdev.c | 11 +++++++++++
 include/linux/mdev.h          |  4 ++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index d230620fe02d..17aa76de0764 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -101,6 +101,16 @@ static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
 	return parent->ops->mmap(mdev, vma);
 }
 
+static void vfio_mdev_request(void *device_data, unsigned int count)
+{
+	struct mdev_device *mdev = device_data;
+	struct mdev_parent *parent = mdev->parent;
+
+	if (unlikely(!parent->ops->request))
+		return;
+	parent->ops->request(mdev, count);
+}
+
 static const struct vfio_device_ops vfio_mdev_dev_ops = {
 	.name		= "vfio-mdev",
 	.open		= vfio_mdev_open,
@@ -109,6 +119,7 @@ static const struct vfio_device_ops vfio_mdev_dev_ops = {
 	.read		= vfio_mdev_read,
 	.write		= vfio_mdev_write,
 	.mmap		= vfio_mdev_mmap,
+	.request	= vfio_mdev_request,
 };
 
 static int vfio_mdev_probe(struct device *dev)
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index b6e048e1045f..24887cd56962 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -13,6 +13,9 @@
 #ifndef MDEV_H
 #define MDEV_H
 
+#include <linux/uuid.h>
+#include <linux/device.h>
+
 struct mdev_device;
 
 /**
@@ -81,6 +84,7 @@ struct mdev_parent_ops {
 	long	(*ioctl)(struct mdev_device *mdev, unsigned int cmd,
 			 unsigned long arg);
 	int	(*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
+	void	(*request)(struct mdev_device *mdev, unsigned int count);
 };
 
 /* interface for exporting mdev supported type attributes */
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 1/9] vfio/mdev: add .request callback
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

This will allow the hotplug to be enabled for mediated devices

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/vfio/mdev/vfio_mdev.c | 11 +++++++++++
 include/linux/mdev.h          |  4 ++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index d230620fe02d..17aa76de0764 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -101,6 +101,16 @@ static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
 	return parent->ops->mmap(mdev, vma);
 }
 
+static void vfio_mdev_request(void *device_data, unsigned int count)
+{
+	struct mdev_device *mdev = device_data;
+	struct mdev_parent *parent = mdev->parent;
+
+	if (unlikely(!parent->ops->request))
+		return;
+	parent->ops->request(mdev, count);
+}
+
 static const struct vfio_device_ops vfio_mdev_dev_ops = {
 	.name		= "vfio-mdev",
 	.open		= vfio_mdev_open,
@@ -109,6 +119,7 @@ static const struct vfio_device_ops vfio_mdev_dev_ops = {
 	.read		= vfio_mdev_read,
 	.write		= vfio_mdev_write,
 	.mmap		= vfio_mdev_mmap,
+	.request	= vfio_mdev_request,
 };
 
 static int vfio_mdev_probe(struct device *dev)
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index b6e048e1045f..24887cd56962 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -13,6 +13,9 @@
 #ifndef MDEV_H
 #define MDEV_H
 
+#include <linux/uuid.h>
+#include <linux/device.h>
+
 struct mdev_device;
 
 /**
@@ -81,6 +84,7 @@ struct mdev_parent_ops {
 	long	(*ioctl)(struct mdev_device *mdev, unsigned int cmd,
 			 unsigned long arg);
 	int	(*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
+	void	(*request)(struct mdev_device *mdev, unsigned int count);
 };
 
 /* interface for exporting mdev supported type attributes */
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 2/9] nvme/core: add some more values from the spec
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


This adds few defines from the spec,
that will be used in the nvme-mdev driver

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 include/linux/nvme.h | 88 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index bbcc83886899..029162db31bb 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -152,32 +152,42 @@ enum {
 #define NVME_NVM_IOCQES		4
 
 enum {
-	NVME_CC_ENABLE		= 1 << 0,
-	NVME_CC_CSS_NVM		= 0 << 4,
 	NVME_CC_EN_SHIFT	= 0,
+	NVME_CC_ENABLE		= 1 << NVME_CC_EN_SHIFT,
+
 	NVME_CC_CSS_SHIFT	= 4,
+	NVME_CC_CSS_NVM		= 0 << NVME_CC_CSS_SHIFT,
+
 	NVME_CC_MPS_SHIFT	= 7,
+	NVME_CC_MPS_MASK	= 0xF << NVME_CC_MPS_SHIFT,
+
 	NVME_CC_AMS_SHIFT	= 11,
-	NVME_CC_SHN_SHIFT	= 14,
-	NVME_CC_IOSQES_SHIFT	= 16,
-	NVME_CC_IOCQES_SHIFT	= 20,
 	NVME_CC_AMS_RR		= 0 << NVME_CC_AMS_SHIFT,
 	NVME_CC_AMS_WRRU	= 1 << NVME_CC_AMS_SHIFT,
 	NVME_CC_AMS_VS		= 7 << NVME_CC_AMS_SHIFT,
+	NVME_CC_AMS_MASK	= 0x7 << NVME_CC_AMS_SHIFT,
+
+	NVME_CC_SHN_SHIFT	= 14,
 	NVME_CC_SHN_NONE	= 0 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_NORMAL	= 1 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_ABRUPT	= 2 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_MASK	= 3 << NVME_CC_SHN_SHIFT,
+
+	NVME_CC_IOSQES_SHIFT	= 16,
+	NVME_CC_IOCQES_SHIFT	= 20,
 	NVME_CC_IOSQES		= NVME_NVM_IOSQES << NVME_CC_IOSQES_SHIFT,
 	NVME_CC_IOCQES		= NVME_NVM_IOCQES << NVME_CC_IOCQES_SHIFT,
+
 	NVME_CSTS_RDY		= 1 << 0,
 	NVME_CSTS_CFS		= 1 << 1,
 	NVME_CSTS_NSSRO		= 1 << 4,
 	NVME_CSTS_PP		= 1 << 5,
-	NVME_CSTS_SHST_NORMAL	= 0 << 2,
-	NVME_CSTS_SHST_OCCUR	= 1 << 2,
-	NVME_CSTS_SHST_CMPLT	= 2 << 2,
-	NVME_CSTS_SHST_MASK	= 3 << 2,
+
+	NVME_CSTS_SHST_SHIFT	= 2,
+	NVME_CSTS_SHST_NORMAL	= 0 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_OCCUR	= 1 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_CMPLT	= 2 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_MASK	= 3 << NVME_CSTS_SHST_SHIFT,
 };
 
 struct nvme_id_power_state {
@@ -404,6 +414,20 @@ enum {
 	NVME_NIDT_UUID		= 0x03,
 };
 
+struct nvme_err_log_entry {
+	__u8			err_count[8];
+	__le16			sqid;
+	__le16			cid;
+	__le16			status;
+	__le16			location;
+	__u8			lba[8];
+	__le32			ns;
+	__u8			vnd;
+	__u8			rsvd1[3];
+	__u8			cmd_specific[8];
+	__u8			rsvd2[24];
+};
+
 struct nvme_smart_log {
 	__u8			critical_warning;
 	__u8			temperature[2];
@@ -491,13 +515,30 @@ enum {
 	NVME_AER_VS			= 7,
 };
 
-enum {
-	NVME_AER_NOTICE_NS_CHANGED	= 0x00,
-	NVME_AER_NOTICE_FW_ACT_STARTING = 0x01,
-	NVME_AER_NOTICE_ANA		= 0x03,
-	NVME_AER_NOTICE_DISC_CHANGED	= 0xf0,
+enum nvme_async_event_type {
+	NVME_AER_TYPE_ERROR	= 0,
+	NVME_AER_TYPE_SMART	= 1,
+	NVME_AER_TYPE_NOTICE	= 2,
+	NVME_AER_TYPE_MAX	= 7,
 };
 
+enum nvme_async_event {
+	NVME_AER_ERROR_INVALID_DB_REG = 0,
+	NVME_AER_ERROR_INVALID_DB_VALUE = 1,
+	NVME_AER_ERROR_DIAG_FAILURE = 2,
+	NVME_AER_ERROR_PERSISTENT_INT_ERR = 3,
+	NVME_AER_ERROR_TRANSIENT_INT_ERR = 4,
+	NVME_AER_ERROR_FW_IMAGE_LOAD_ERR = 5,
+
+	NVME_AER_SMART_SUBSYS_RELIABILITY = 0,
+	NVME_AER_SMART_TEMP_THRESH = 1,
+	NVME_AER_SMART_SPARE_BELOW_THRESH = 2,
+
+	NVME_AER_NOTICE_NS_CHANGED	= 0,
+	NVME_AER_NOTICE_FW_ACT_STARTING = 1,
+	NVME_AER_NOTICE_ANA		= 3,
+	NVME_AER_NOTICE_DISC_CHANGED	= 0xf0,
+};
 enum {
 	NVME_AEN_BIT_NS_ATTR		= 8,
 	NVME_AEN_BIT_FW_ACT		= 9,
@@ -548,12 +589,6 @@ struct nvme_reservation_status {
 	} regctl_ds[];
 };
 
-enum nvme_async_event_type {
-	NVME_AER_TYPE_ERROR	= 0,
-	NVME_AER_TYPE_SMART	= 1,
-	NVME_AER_TYPE_NOTICE	= 2,
-};
-
 /* I/O commands */
 
 enum nvme_opcode {
@@ -705,10 +740,19 @@ enum {
 	NVME_RW_DSM_LATENCY_LOW		= 3 << 4,
 	NVME_RW_DSM_SEQ_REQ		= 1 << 6,
 	NVME_RW_DSM_COMPRESSED		= 1 << 7,
+
+	NVME_WZ_DEAC			= 1 << 9,
 	NVME_RW_PRINFO_PRCHK_REF	= 1 << 10,
 	NVME_RW_PRINFO_PRCHK_APP	= 1 << 11,
 	NVME_RW_PRINFO_PRCHK_GUARD	= 1 << 12,
 	NVME_RW_PRINFO_PRACT		= 1 << 13,
+
+	NVME_RW_PRINFO			=
+			NVME_RW_PRINFO_PRCHK_REF |
+			NVME_RW_PRINFO_PRCHK_APP |
+			NVME_RW_PRINFO_PRCHK_GUARD |
+			NVME_RW_PRINFO_PRACT,
+
 	NVME_RW_DTYPE_STREAMS		= 1 << 4,
 };
 
@@ -809,6 +853,7 @@ enum {
 	NVME_SQ_PRIO_HIGH	= (1 << 1),
 	NVME_SQ_PRIO_MEDIUM	= (2 << 1),
 	NVME_SQ_PRIO_LOW	= (3 << 1),
+	NVME_SQ_PRIO_MASK	= (3 << 1),
 	NVME_FEAT_ARBITRATION	= 0x01,
 	NVME_FEAT_POWER_MGMT	= 0x02,
 	NVME_FEAT_LBA_RANGE	= 0x03,
@@ -1146,6 +1191,7 @@ struct streams_directive_params {
 
 struct nvme_command {
 	union {
+		__le32 dwords[16];
 		struct nvme_common_command common;
 		struct nvme_rw_command rw;
 		struct nvme_identify identify;
@@ -1217,6 +1263,8 @@ enum {
 	NVME_SC_SGL_INVALID_METADATA	= 0x10,
 	NVME_SC_SGL_INVALID_TYPE	= 0x11,
 
+	NVME_SC_PRP_OFFSET_INVALID	= 0x13,
+
 	NVME_SC_SGL_INVALID_OFFSET	= 0x16,
 	NVME_SC_SGL_INVALID_SUBTYPE	= 0x17,
 
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 2/9] nvme/core: add some more values from the spec
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

This adds few defines from the spec,
that will be used in the nvme-mdev driver

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 include/linux/nvme.h | 88 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index bbcc83886899..029162db31bb 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -152,32 +152,42 @@ enum {
 #define NVME_NVM_IOCQES		4
 
 enum {
-	NVME_CC_ENABLE		= 1 << 0,
-	NVME_CC_CSS_NVM		= 0 << 4,
 	NVME_CC_EN_SHIFT	= 0,
+	NVME_CC_ENABLE		= 1 << NVME_CC_EN_SHIFT,
+
 	NVME_CC_CSS_SHIFT	= 4,
+	NVME_CC_CSS_NVM		= 0 << NVME_CC_CSS_SHIFT,
+
 	NVME_CC_MPS_SHIFT	= 7,
+	NVME_CC_MPS_MASK	= 0xF << NVME_CC_MPS_SHIFT,
+
 	NVME_CC_AMS_SHIFT	= 11,
-	NVME_CC_SHN_SHIFT	= 14,
-	NVME_CC_IOSQES_SHIFT	= 16,
-	NVME_CC_IOCQES_SHIFT	= 20,
 	NVME_CC_AMS_RR		= 0 << NVME_CC_AMS_SHIFT,
 	NVME_CC_AMS_WRRU	= 1 << NVME_CC_AMS_SHIFT,
 	NVME_CC_AMS_VS		= 7 << NVME_CC_AMS_SHIFT,
+	NVME_CC_AMS_MASK	= 0x7 << NVME_CC_AMS_SHIFT,
+
+	NVME_CC_SHN_SHIFT	= 14,
 	NVME_CC_SHN_NONE	= 0 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_NORMAL	= 1 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_ABRUPT	= 2 << NVME_CC_SHN_SHIFT,
 	NVME_CC_SHN_MASK	= 3 << NVME_CC_SHN_SHIFT,
+
+	NVME_CC_IOSQES_SHIFT	= 16,
+	NVME_CC_IOCQES_SHIFT	= 20,
 	NVME_CC_IOSQES		= NVME_NVM_IOSQES << NVME_CC_IOSQES_SHIFT,
 	NVME_CC_IOCQES		= NVME_NVM_IOCQES << NVME_CC_IOCQES_SHIFT,
+
 	NVME_CSTS_RDY		= 1 << 0,
 	NVME_CSTS_CFS		= 1 << 1,
 	NVME_CSTS_NSSRO		= 1 << 4,
 	NVME_CSTS_PP		= 1 << 5,
-	NVME_CSTS_SHST_NORMAL	= 0 << 2,
-	NVME_CSTS_SHST_OCCUR	= 1 << 2,
-	NVME_CSTS_SHST_CMPLT	= 2 << 2,
-	NVME_CSTS_SHST_MASK	= 3 << 2,
+
+	NVME_CSTS_SHST_SHIFT	= 2,
+	NVME_CSTS_SHST_NORMAL	= 0 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_OCCUR	= 1 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_CMPLT	= 2 << NVME_CSTS_SHST_SHIFT,
+	NVME_CSTS_SHST_MASK	= 3 << NVME_CSTS_SHST_SHIFT,
 };
 
 struct nvme_id_power_state {
@@ -404,6 +414,20 @@ enum {
 	NVME_NIDT_UUID		= 0x03,
 };
 
+struct nvme_err_log_entry {
+	__u8			err_count[8];
+	__le16			sqid;
+	__le16			cid;
+	__le16			status;
+	__le16			location;
+	__u8			lba[8];
+	__le32			ns;
+	__u8			vnd;
+	__u8			rsvd1[3];
+	__u8			cmd_specific[8];
+	__u8			rsvd2[24];
+};
+
 struct nvme_smart_log {
 	__u8			critical_warning;
 	__u8			temperature[2];
@@ -491,13 +515,30 @@ enum {
 	NVME_AER_VS			= 7,
 };
 
-enum {
-	NVME_AER_NOTICE_NS_CHANGED	= 0x00,
-	NVME_AER_NOTICE_FW_ACT_STARTING = 0x01,
-	NVME_AER_NOTICE_ANA		= 0x03,
-	NVME_AER_NOTICE_DISC_CHANGED	= 0xf0,
+enum nvme_async_event_type {
+	NVME_AER_TYPE_ERROR	= 0,
+	NVME_AER_TYPE_SMART	= 1,
+	NVME_AER_TYPE_NOTICE	= 2,
+	NVME_AER_TYPE_MAX	= 7,
 };
 
+enum nvme_async_event {
+	NVME_AER_ERROR_INVALID_DB_REG = 0,
+	NVME_AER_ERROR_INVALID_DB_VALUE = 1,
+	NVME_AER_ERROR_DIAG_FAILURE = 2,
+	NVME_AER_ERROR_PERSISTENT_INT_ERR = 3,
+	NVME_AER_ERROR_TRANSIENT_INT_ERR = 4,
+	NVME_AER_ERROR_FW_IMAGE_LOAD_ERR = 5,
+
+	NVME_AER_SMART_SUBSYS_RELIABILITY = 0,
+	NVME_AER_SMART_TEMP_THRESH = 1,
+	NVME_AER_SMART_SPARE_BELOW_THRESH = 2,
+
+	NVME_AER_NOTICE_NS_CHANGED	= 0,
+	NVME_AER_NOTICE_FW_ACT_STARTING = 1,
+	NVME_AER_NOTICE_ANA		= 3,
+	NVME_AER_NOTICE_DISC_CHANGED	= 0xf0,
+};
 enum {
 	NVME_AEN_BIT_NS_ATTR		= 8,
 	NVME_AEN_BIT_FW_ACT		= 9,
@@ -548,12 +589,6 @@ struct nvme_reservation_status {
 	} regctl_ds[];
 };
 
-enum nvme_async_event_type {
-	NVME_AER_TYPE_ERROR	= 0,
-	NVME_AER_TYPE_SMART	= 1,
-	NVME_AER_TYPE_NOTICE	= 2,
-};
-
 /* I/O commands */
 
 enum nvme_opcode {
@@ -705,10 +740,19 @@ enum {
 	NVME_RW_DSM_LATENCY_LOW		= 3 << 4,
 	NVME_RW_DSM_SEQ_REQ		= 1 << 6,
 	NVME_RW_DSM_COMPRESSED		= 1 << 7,
+
+	NVME_WZ_DEAC			= 1 << 9,
 	NVME_RW_PRINFO_PRCHK_REF	= 1 << 10,
 	NVME_RW_PRINFO_PRCHK_APP	= 1 << 11,
 	NVME_RW_PRINFO_PRCHK_GUARD	= 1 << 12,
 	NVME_RW_PRINFO_PRACT		= 1 << 13,
+
+	NVME_RW_PRINFO			=
+			NVME_RW_PRINFO_PRCHK_REF |
+			NVME_RW_PRINFO_PRCHK_APP |
+			NVME_RW_PRINFO_PRCHK_GUARD |
+			NVME_RW_PRINFO_PRACT,
+
 	NVME_RW_DTYPE_STREAMS		= 1 << 4,
 };
 
@@ -809,6 +853,7 @@ enum {
 	NVME_SQ_PRIO_HIGH	= (1 << 1),
 	NVME_SQ_PRIO_MEDIUM	= (2 << 1),
 	NVME_SQ_PRIO_LOW	= (3 << 1),
+	NVME_SQ_PRIO_MASK	= (3 << 1),
 	NVME_FEAT_ARBITRATION	= 0x01,
 	NVME_FEAT_POWER_MGMT	= 0x02,
 	NVME_FEAT_LBA_RANGE	= 0x03,
@@ -1146,6 +1191,7 @@ struct streams_directive_params {
 
 struct nvme_command {
 	union {
+		__le32 dwords[16];
 		struct nvme_common_command common;
 		struct nvme_rw_command rw;
 		struct nvme_identify identify;
@@ -1217,6 +1263,8 @@ enum {
 	NVME_SC_SGL_INVALID_METADATA	= 0x10,
 	NVME_SC_SGL_INVALID_TYPE	= 0x11,
 
+	NVME_SC_PRP_OFFSET_INVALID	= 0x13,
+
 	NVME_SC_SGL_INVALID_OFFSET	= 0x16,
 	NVME_SC_SGL_INVALID_SUBTYPE	= 0x17,
 
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 3/9] nvme/core: add NVME_CTRL_SUSPENDED controller state
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


This state will be used by a controller that is going to
suspended state, and will later be used by mdev
framework to detect this and flush its queues

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/core.c | 15 +++++++++++++++
 drivers/nvme/host/nvme.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 6a9dd68c0f4f..cf9de026cb93 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -320,6 +320,19 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		switch (old_state) {
 		case NVME_CTRL_NEW:
 		case NVME_CTRL_RESETTING:
+		case NVME_CTRL_CONNECTING:
+		case NVME_CTRL_SUSPENDED:
+			changed = true;
+			/* FALLTHRU */
+		default:
+			break;
+		}
+		break;
+	case NVME_CTRL_SUSPENDED:
+		switch (old_state) {
+		case NVME_CTRL_NEW:
+		case NVME_CTRL_LIVE:
+		case NVME_CTRL_RESETTING:
 		case NVME_CTRL_CONNECTING:
 			changed = true;
 			/* FALLTHRU */
@@ -332,6 +345,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		case NVME_CTRL_NEW:
 		case NVME_CTRL_LIVE:
 		case NVME_CTRL_ADMIN_ONLY:
+		case NVME_CTRL_SUSPENDED:
 			changed = true;
 			/* FALLTHRU */
 		default:
@@ -354,6 +368,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		case NVME_CTRL_ADMIN_ONLY:
 		case NVME_CTRL_RESETTING:
 		case NVME_CTRL_CONNECTING:
+		case NVME_CTRL_SUSPENDED:
 			changed = true;
 			/* FALLTHRU */
 		default:
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index c4a1bb41abf0..9320b0a87d79 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -142,6 +142,7 @@ static inline u16 nvme_req_qid(struct request *req)
 enum nvme_ctrl_state {
 	NVME_CTRL_NEW,
 	NVME_CTRL_LIVE,
+	NVME_CTRL_SUSPENDED,
 	NVME_CTRL_ADMIN_ONLY,    /* Only admin queue live */
 	NVME_CTRL_RESETTING,
 	NVME_CTRL_CONNECTING,
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 3/9] nvme/core: add NVME_CTRL_SUSPENDED controller state
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

This state will be used by a controller that is going to
suspended state, and will later be used by mdev
framework to detect this and flush its queues

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/core.c | 15 +++++++++++++++
 drivers/nvme/host/nvme.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 6a9dd68c0f4f..cf9de026cb93 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -320,6 +320,19 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		switch (old_state) {
 		case NVME_CTRL_NEW:
 		case NVME_CTRL_RESETTING:
+		case NVME_CTRL_CONNECTING:
+		case NVME_CTRL_SUSPENDED:
+			changed = true;
+			/* FALLTHRU */
+		default:
+			break;
+		}
+		break;
+	case NVME_CTRL_SUSPENDED:
+		switch (old_state) {
+		case NVME_CTRL_NEW:
+		case NVME_CTRL_LIVE:
+		case NVME_CTRL_RESETTING:
 		case NVME_CTRL_CONNECTING:
 			changed = true;
 			/* FALLTHRU */
@@ -332,6 +345,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		case NVME_CTRL_NEW:
 		case NVME_CTRL_LIVE:
 		case NVME_CTRL_ADMIN_ONLY:
+		case NVME_CTRL_SUSPENDED:
 			changed = true;
 			/* FALLTHRU */
 		default:
@@ -354,6 +368,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 		case NVME_CTRL_ADMIN_ONLY:
 		case NVME_CTRL_RESETTING:
 		case NVME_CTRL_CONNECTING:
+		case NVME_CTRL_SUSPENDED:
 			changed = true;
 			/* FALLTHRU */
 		default:
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index c4a1bb41abf0..9320b0a87d79 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -142,6 +142,7 @@ static inline u16 nvme_req_qid(struct request *req)
 enum nvme_ctrl_state {
 	NVME_CTRL_NEW,
 	NVME_CTRL_LIVE,
+	NVME_CTRL_SUSPENDED,
 	NVME_CTRL_ADMIN_ONLY,    /* Only admin queue live */
 	NVME_CTRL_RESETTING,
 	NVME_CTRL_CONNECTING,
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 4/9] nvme/pci: use the NVME_CTRL_SUSPENDED state
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


When enteriing low power state, the nvme
driver will now inform the core with the NVME_CTRL_SUSPENDED state
which will allow mdev driver to act on this information

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/pci.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 7fee665ec45e..a188ab6ffaf8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2451,7 +2451,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 		u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
 		if (dev->ctrl.state == NVME_CTRL_LIVE ||
-		    dev->ctrl.state == NVME_CTRL_RESETTING)
+		    dev->ctrl.state == NVME_CTRL_RESETTING ||
+		    dev->ctrl.state == NVME_CTRL_SUSPENDED)
 			nvme_start_freeze(&dev->ctrl);
 		dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
 			pdev->error_state  != pci_channel_io_normal);
@@ -2897,6 +2898,9 @@ static int nvme_suspend(struct device *dev)
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
+	if (!nvme_change_ctrl_state(&ndev->ctrl, NVME_CTRL_SUSPENDED))
+		WARN_ON(1);
+
 	nvme_dev_disable(ndev, true);
 	return 0;
 }
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 4/9] nvme/pci: use the NVME_CTRL_SUSPENDED state
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

When enteriing low power state, the nvme
driver will now inform the core with the NVME_CTRL_SUSPENDED state
which will allow mdev driver to act on this information

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/pci.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 7fee665ec45e..a188ab6ffaf8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2451,7 +2451,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
 		u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
 		if (dev->ctrl.state == NVME_CTRL_LIVE ||
-		    dev->ctrl.state == NVME_CTRL_RESETTING)
+		    dev->ctrl.state == NVME_CTRL_RESETTING ||
+		    dev->ctrl.state == NVME_CTRL_SUSPENDED)
 			nvme_start_freeze(&dev->ctrl);
 		dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) ||
 			pdev->error_state  != pci_channel_io_normal);
@@ -2897,6 +2898,9 @@ static int nvme_suspend(struct device *dev)
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct nvme_dev *ndev = pci_get_drvdata(pdev);
 
+	if (!nvme_change_ctrl_state(&ndev->ctrl, NVME_CTRL_SUSPENDED))
+		WARN_ON(1);
+
 	nvme_dev_disable(ndev, true);
 	return 0;
 }
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 5/9] nvme/pci: add known admin effects to augument admin effects log page
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


Add known admin effects even if hardware has known admin effects page,
since hardware can't be ever trusted to report sane values.
(on my Intel DC P3700, it reports no side effects for namespace format)

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index cf9de026cb93..e1cef428c7e9 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1260,8 +1260,8 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 
 	if (ctrl->effects)
 		effects = le32_to_cpu(ctrl->effects->acs[opcode]);
-	else
-		effects = nvme_known_admin_effects(opcode);
+
+	effects |= nvme_known_admin_effects(opcode);
 
 	/*
 	 * For simplicity, IO to all namespaces is quiesced even if the command
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 5/9] nvme/pci: add known admin effects to augument admin effects log page
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

Add known admin effects even if hardware has known admin effects page,
since hardware can't be ever trusted to report sane values.
(on my Intel DC P3700, it reports no side effects for namespace format)

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index cf9de026cb93..e1cef428c7e9 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1260,8 +1260,8 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 
 	if (ctrl->effects)
 		effects = le32_to_cpu(ctrl->effects->acs[opcode]);
-	else
-		effects = nvme_known_admin_effects(opcode);
+
+	effects |= nvme_known_admin_effects(opcode);
 
 	/*
 	 * For simplicity, IO to all namespaces is quiesced even if the command
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 6/9] nvme/pci: init shadow doorbell after each reset
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


The spec states
"The settings are not retained across a Controller Level Reset"
Therefore the driver must enable the shadow doorbell,
after each reset.

This was caught while testing the nvme driver over
upcoming nvme-mdev device

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index a188ab6ffaf8..806b551d3582 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2347,8 +2347,6 @@ static int nvme_dev_add(struct nvme_dev *dev)
 			return ret;
 		}
 		dev->ctrl.tagset = &dev->tagset;
-
-		nvme_dbbuf_set(dev);
 	} else {
 		blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
 
@@ -2356,6 +2354,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
 		nvme_free_queues(dev, dev->online_queues);
 	}
 
+	nvme_dbbuf_set(dev);
 	return 0;
 }
 
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 6/9] nvme/pci: init shadow doorbell after each reset
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

The spec states
"The settings are not retained across a Controller Level Reset"
Therefore the driver must enable the shadow doorbell,
after each reset.

This was caught while testing the nvme driver over
upcoming nvme-mdev device

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index a188ab6ffaf8..806b551d3582 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2347,8 +2347,6 @@ static int nvme_dev_add(struct nvme_dev *dev)
 			return ret;
 		}
 		dev->ctrl.tagset = &dev->tagset;
-
-		nvme_dbbuf_set(dev);
 	} else {
 		blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
 
@@ -2356,6 +2354,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
 		nvme_free_queues(dev, dev->online_queues);
 	}
 
+	nvme_dbbuf_set(dev);
 	return 0;
 }
 
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 7/9] nvme/core: add mdev interfaces
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


This adds infrastructure for a nvme-mdev
to attach to the core driver, to be able to
know which nvme controllers are present and which
namespaces they have.

It also adds an interface to nvme device drivers
which expose the its queues in a controlled manner
to the nvme mdev core driver. A driver must opt-in
for this using a new flag NVME_F_MDEV_SUPPORTED

If the mdev device driver also sets the
NVME_F_MDEV_DMA_SUPPORTED, the mdev core will
dma map all the guest memory into the nvme device,
so that nvme device driver can use dma addresses as passed
from the mdev core driver

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/core.c | 125 ++++++++++++++++++++++++++++++++++++++-
 drivers/nvme/host/nvme.h |  54 +++++++++++++++--
 2 files changed, 172 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e1cef428c7e9..90561973bce9 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -97,11 +97,111 @@ static dev_t nvme_chr_devt;
 static struct class *nvme_class;
 static struct class *nvme_subsys_class;
 
+static void nvme_ns_remove(struct nvme_ns *ns);
 static int nvme_revalidate_disk(struct gendisk *disk);
 static void nvme_put_subsystem(struct nvme_subsystem *subsys);
 static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
 					   unsigned nsid);
 
+#ifdef CONFIG_NVME_MDEV
+
+static struct nvme_mdev_driver *mdev_driver_interface;
+static DEFINE_MUTEX(mdev_ctrl_lock);
+static LIST_HEAD(mdev_ctrl_list);
+
+static bool nvme_ctrl_has_mdev(struct nvme_ctrl *ctrl)
+{
+	return  (ctrl->ops->flags & NVME_F_MDEV_SUPPORTED) != 0;
+}
+
+static void nvme_mdev_add_ctrl(struct nvme_ctrl *ctrl)
+{
+	if (nvme_ctrl_has_mdev(ctrl)) {
+		mutex_lock(&mdev_ctrl_lock);
+		list_add_tail(&ctrl->link, &mdev_ctrl_list);
+		mutex_unlock(&mdev_ctrl_lock);
+	}
+}
+
+static void nvme_mdev_remove_ctrl(struct nvme_ctrl *ctrl)
+{
+	if (nvme_ctrl_has_mdev(ctrl)) {
+		mutex_lock(&mdev_ctrl_lock);
+		list_del_init(&ctrl->link);
+		mutex_unlock(&mdev_ctrl_lock);
+	}
+}
+
+int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
+{
+	struct nvme_ctrl *ctrl;
+
+	if (mdev_driver_interface)
+		return -EEXIST;
+
+	mdev_driver_interface = driver_ops;
+
+	mutex_lock(&mdev_ctrl_lock);
+	list_for_each_entry(ctrl, &mdev_ctrl_list, link)
+		mdev_driver_interface->nvme_ctrl_state_changed(ctrl);
+
+	mutex_unlock(&mdev_ctrl_lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nvme_core_register_mdev_driver);
+
+void nvme_core_unregister_mdev_driver(struct nvme_mdev_driver *driver_ops)
+{
+	if (WARN_ON(driver_ops != mdev_driver_interface))
+		return;
+	mdev_driver_interface = NULL;
+}
+EXPORT_SYMBOL_GPL(nvme_core_unregister_mdev_driver);
+
+static void nvme_mdev_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+	if (!mdev_driver_interface || !nvme_ctrl_has_mdev(ctrl))
+		return;
+	if (!try_module_get(mdev_driver_interface->owner))
+		return;
+
+	mdev_driver_interface->nvme_ctrl_state_changed(ctrl);
+	module_put(mdev_driver_interface->owner);
+}
+
+static void nvme_mdev_ns_state_changed(struct nvme_ctrl *ctrl,
+				       struct nvme_ns *ns, bool removed)
+{
+	if (!mdev_driver_interface || !nvme_ctrl_has_mdev(ctrl))
+		return;
+	if (!try_module_get(mdev_driver_interface->owner))
+		return;
+
+	mdev_driver_interface->nvme_ns_state_changed(ctrl,
+			ns->head->ns_id, removed);
+	module_put(mdev_driver_interface->owner);
+}
+
+#else
+static void nvme_mdev_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+}
+
+static void nvme_mdev_ns_state_changed(struct nvme_ctrl *ctrl,
+				       struct nvme_ns *ns, bool removed)
+{
+}
+
+static void nvme_mdev_add_ctrl(struct nvme_ctrl *ctrl)
+{
+}
+
+static void nvme_mdev_remove_ctrl(struct nvme_ctrl *ctrl)
+{
+}
+
+#endif
+
 static void nvme_set_queue_dying(struct nvme_ns *ns)
 {
 	/*
@@ -390,10 +490,13 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 
 	if (changed)
 		ctrl->state = new_state;
-
 	spin_unlock_irqrestore(&ctrl->lock, flags);
+
+	nvme_mdev_ctrl_state_changed(ctrl);
+
 	if (changed && ctrl->state == NVME_CTRL_LIVE)
 		nvme_kick_requeue_lists(ctrl);
+
 	return changed;
 }
 EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
@@ -429,10 +532,11 @@ static void nvme_free_ns(struct kref *kref)
 	kfree(ns);
 }
 
-static void nvme_put_ns(struct nvme_ns *ns)
+void nvme_put_ns(struct nvme_ns *ns)
 {
 	kref_put(&ns->kref, nvme_free_ns);
 }
+EXPORT_SYMBOL_GPL(nvme_put_ns);
 
 static inline void nvme_clear_nvme_request(struct request *req)
 {
@@ -1275,6 +1379,11 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 	return effects;
 }
 
+static void nvme_update_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
+{
+	nvme_mdev_ns_state_changed(ctrl, ns, false);
+}
+
 static void nvme_update_formats(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
@@ -1283,6 +1392,8 @@ static void nvme_update_formats(struct nvme_ctrl *ctrl)
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		if (ns->disk && nvme_revalidate_disk(ns->disk))
 			nvme_set_queue_dying(ns);
+		else
+			nvme_update_ns(ctrl, ns);
 	up_read(&ctrl->namespaces_rwsem);
 
 	nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
@@ -3133,7 +3244,7 @@ static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
 	return nsa->head->ns_id - nsb->head->ns_id;
 }
 
-static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned int nsid)
 {
 	struct nvme_ns *ns, *ret = NULL;
 
@@ -3151,6 +3262,7 @@ static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	up_read(&ctrl->namespaces_rwsem);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(nvme_find_get_ns);
 
 static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
 {
@@ -3271,6 +3383,8 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags))
 		return;
 
+	nvme_mdev_ns_state_changed(ns->ctrl, ns, true);
+
 	nvme_fault_inject_fini(ns);
 	if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
 		del_gendisk(ns->disk);
@@ -3301,6 +3415,8 @@ static void nvme_validate_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	if (ns) {
 		if (ns->disk && revalidate_disk(ns->disk))
 			nvme_ns_remove(ns);
+		else
+			nvme_update_ns(ctrl, ns);
 		nvme_put_ns(ns);
 	} else
 		nvme_alloc_ns(ctrl, nsid);
@@ -3654,6 +3770,7 @@ static void nvme_free_ctrl(struct device *dev)
 		sysfs_remove_link(&subsys->dev.kobj, dev_name(ctrl->device));
 	}
 
+	nvme_mdev_remove_ctrl(ctrl);
 	ctrl->ops->free_ctrl(ctrl);
 
 	if (subsys)
@@ -3726,6 +3843,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
 	dev_pm_qos_update_user_latency_tolerance(ctrl->device,
 		min(default_ps_max_latency_us, (unsigned long)S32_MAX));
 
+	nvme_mdev_add_ctrl(ctrl);
+
 	return 0;
 out_free_name:
 	kfree_const(ctrl->device->kobj.name);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9320b0a87d79..2df6c9f0e1cc 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -151,6 +151,7 @@ enum nvme_ctrl_state {
 };
 
 struct nvme_ctrl {
+	struct list_head link;
 	bool comp_seen;
 	enum nvme_ctrl_state state;
 	bool identified;
@@ -253,6 +254,23 @@ struct nvme_ctrl {
 	unsigned long discard_page_busy;
 };
 
+#ifdef CONFIG_NVME_MDEV
+/* Interface to the host driver  */
+struct nvme_mdev_driver {
+	struct module *owner;
+
+	/* a controller state has changed*/
+	void (*nvme_ctrl_state_changed)(struct nvme_ctrl *ctrl);
+
+	/* NS is updated in some way (after format or so) */
+	void (*nvme_ns_state_changed)(struct nvme_ctrl *ctrl,
+				      u32 nsid, bool removed);
+};
+
+int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops);
+void nvme_core_unregister_mdev_driver(struct nvme_mdev_driver *driver_ops);
+#endif
+
 struct nvme_subsystem {
 	int			instance;
 	struct device		dev;
@@ -275,7 +293,7 @@ struct nvme_subsystem {
 };
 
 /*
- * Container structure for uniqueue namespace identifiers.
+ * Container structure for unique namespace identifiers.
  */
 struct nvme_ns_ids {
 	u8	eui64[8];
@@ -351,13 +369,22 @@ struct nvme_ns {
 
 };
 
+struct nvme_ext_data_iter;
+struct nvme_ext_cmd_result {
+	u32 tag;
+	u16 status;
+};
+
 struct nvme_ctrl_ops {
 	const char *name;
 	struct module *module;
 	unsigned int flags;
-#define NVME_F_FABRICS			(1 << 0)
-#define NVME_F_METADATA_SUPPORTED	(1 << 1)
-#define NVME_F_PCI_P2PDMA		(1 << 2)
+#define NVME_F_FABRICS			BIT(0)
+#define NVME_F_METADATA_SUPPORTED	BIT(1)
+#define NVME_F_PCI_P2PDMA		BIT(2)
+#define NVME_F_MDEV_SUPPORTED		BIT(3)
+#define NVME_F_MDEV_DMA_SUPPORTED	BIT(4)
+
 	int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
 	int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
 	int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
@@ -366,6 +393,23 @@ struct nvme_ctrl_ops {
 	void (*delete_ctrl)(struct nvme_ctrl *ctrl);
 	int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
 	void (*stop_ctrl)(struct nvme_ctrl *ctrl);
+
+#ifdef CONFIG_NVME_MDEV
+	int (*ext_queues_available)(struct nvme_ctrl *ctrl);
+	int (*ext_queue_alloc)(struct nvme_ctrl *ctrl, u16 *qid);
+	void (*ext_queue_free)(struct nvme_ctrl *ctrl, u16 qid);
+
+	int (*ext_queue_submit)(struct nvme_ctrl *ctrl,
+				u16 qid, u32 tag,
+				struct nvme_command *command,
+				struct nvme_ext_data_iter *iter);
+
+	bool (*ext_queue_full)(struct nvme_ctrl *ctrl, u16 qid);
+
+	int (*ext_queue_poll)(struct nvme_ctrl *ctrl, u16 qid,
+			      struct nvme_ext_cmd_result *results,
+			      unsigned int max_len);
+#endif
 };
 
 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
@@ -427,6 +471,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
 void nvme_put_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_identify(struct nvme_ctrl *ctrl);
 
+struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned int nsid);
+void nvme_put_ns(struct nvme_ns *ns);
 void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
 
 int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 7/9] nvme/core: add mdev interfaces
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

This adds infrastructure for a nvme-mdev
to attach to the core driver, to be able to
know which nvme controllers are present and which
namespaces they have.

It also adds an interface to nvme device drivers
which expose the its queues in a controlled manner
to the nvme mdev core driver. A driver must opt-in
for this using a new flag NVME_F_MDEV_SUPPORTED

If the mdev device driver also sets the
NVME_F_MDEV_DMA_SUPPORTED, the mdev core will
dma map all the guest memory into the nvme device,
so that nvme device driver can use dma addresses as passed
from the mdev core driver

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/core.c | 125 ++++++++++++++++++++++++++++++++++++++-
 drivers/nvme/host/nvme.h |  54 +++++++++++++++--
 2 files changed, 172 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e1cef428c7e9..90561973bce9 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -97,11 +97,111 @@ static dev_t nvme_chr_devt;
 static struct class *nvme_class;
 static struct class *nvme_subsys_class;
 
+static void nvme_ns_remove(struct nvme_ns *ns);
 static int nvme_revalidate_disk(struct gendisk *disk);
 static void nvme_put_subsystem(struct nvme_subsystem *subsys);
 static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
 					   unsigned nsid);
 
+#ifdef CONFIG_NVME_MDEV
+
+static struct nvme_mdev_driver *mdev_driver_interface;
+static DEFINE_MUTEX(mdev_ctrl_lock);
+static LIST_HEAD(mdev_ctrl_list);
+
+static bool nvme_ctrl_has_mdev(struct nvme_ctrl *ctrl)
+{
+	return  (ctrl->ops->flags & NVME_F_MDEV_SUPPORTED) != 0;
+}
+
+static void nvme_mdev_add_ctrl(struct nvme_ctrl *ctrl)
+{
+	if (nvme_ctrl_has_mdev(ctrl)) {
+		mutex_lock(&mdev_ctrl_lock);
+		list_add_tail(&ctrl->link, &mdev_ctrl_list);
+		mutex_unlock(&mdev_ctrl_lock);
+	}
+}
+
+static void nvme_mdev_remove_ctrl(struct nvme_ctrl *ctrl)
+{
+	if (nvme_ctrl_has_mdev(ctrl)) {
+		mutex_lock(&mdev_ctrl_lock);
+		list_del_init(&ctrl->link);
+		mutex_unlock(&mdev_ctrl_lock);
+	}
+}
+
+int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
+{
+	struct nvme_ctrl *ctrl;
+
+	if (mdev_driver_interface)
+		return -EEXIST;
+
+	mdev_driver_interface = driver_ops;
+
+	mutex_lock(&mdev_ctrl_lock);
+	list_for_each_entry(ctrl, &mdev_ctrl_list, link)
+		mdev_driver_interface->nvme_ctrl_state_changed(ctrl);
+
+	mutex_unlock(&mdev_ctrl_lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nvme_core_register_mdev_driver);
+
+void nvme_core_unregister_mdev_driver(struct nvme_mdev_driver *driver_ops)
+{
+	if (WARN_ON(driver_ops != mdev_driver_interface))
+		return;
+	mdev_driver_interface = NULL;
+}
+EXPORT_SYMBOL_GPL(nvme_core_unregister_mdev_driver);
+
+static void nvme_mdev_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+	if (!mdev_driver_interface || !nvme_ctrl_has_mdev(ctrl))
+		return;
+	if (!try_module_get(mdev_driver_interface->owner))
+		return;
+
+	mdev_driver_interface->nvme_ctrl_state_changed(ctrl);
+	module_put(mdev_driver_interface->owner);
+}
+
+static void nvme_mdev_ns_state_changed(struct nvme_ctrl *ctrl,
+				       struct nvme_ns *ns, bool removed)
+{
+	if (!mdev_driver_interface || !nvme_ctrl_has_mdev(ctrl))
+		return;
+	if (!try_module_get(mdev_driver_interface->owner))
+		return;
+
+	mdev_driver_interface->nvme_ns_state_changed(ctrl,
+			ns->head->ns_id, removed);
+	module_put(mdev_driver_interface->owner);
+}
+
+#else
+static void nvme_mdev_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+}
+
+static void nvme_mdev_ns_state_changed(struct nvme_ctrl *ctrl,
+				       struct nvme_ns *ns, bool removed)
+{
+}
+
+static void nvme_mdev_add_ctrl(struct nvme_ctrl *ctrl)
+{
+}
+
+static void nvme_mdev_remove_ctrl(struct nvme_ctrl *ctrl)
+{
+}
+
+#endif
+
 static void nvme_set_queue_dying(struct nvme_ns *ns)
 {
 	/*
@@ -390,10 +490,13 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 
 	if (changed)
 		ctrl->state = new_state;
-
 	spin_unlock_irqrestore(&ctrl->lock, flags);
+
+	nvme_mdev_ctrl_state_changed(ctrl);
+
 	if (changed && ctrl->state == NVME_CTRL_LIVE)
 		nvme_kick_requeue_lists(ctrl);
+
 	return changed;
 }
 EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
@@ -429,10 +532,11 @@ static void nvme_free_ns(struct kref *kref)
 	kfree(ns);
 }
 
-static void nvme_put_ns(struct nvme_ns *ns)
+void nvme_put_ns(struct nvme_ns *ns)
 {
 	kref_put(&ns->kref, nvme_free_ns);
 }
+EXPORT_SYMBOL_GPL(nvme_put_ns);
 
 static inline void nvme_clear_nvme_request(struct request *req)
 {
@@ -1275,6 +1379,11 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 	return effects;
 }
 
+static void nvme_update_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
+{
+	nvme_mdev_ns_state_changed(ctrl, ns, false);
+}
+
 static void nvme_update_formats(struct nvme_ctrl *ctrl)
 {
 	struct nvme_ns *ns;
@@ -1283,6 +1392,8 @@ static void nvme_update_formats(struct nvme_ctrl *ctrl)
 	list_for_each_entry(ns, &ctrl->namespaces, list)
 		if (ns->disk && nvme_revalidate_disk(ns->disk))
 			nvme_set_queue_dying(ns);
+		else
+			nvme_update_ns(ctrl, ns);
 	up_read(&ctrl->namespaces_rwsem);
 
 	nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
@@ -3133,7 +3244,7 @@ static int ns_cmp(void *priv, struct list_head *a, struct list_head *b)
 	return nsa->head->ns_id - nsb->head->ns_id;
 }
 
-static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned int nsid)
 {
 	struct nvme_ns *ns, *ret = NULL;
 
@@ -3151,6 +3262,7 @@ static struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	up_read(&ctrl->namespaces_rwsem);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(nvme_find_get_ns);
 
 static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns)
 {
@@ -3271,6 +3383,8 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 	if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags))
 		return;
 
+	nvme_mdev_ns_state_changed(ns->ctrl, ns, true);
+
 	nvme_fault_inject_fini(ns);
 	if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
 		del_gendisk(ns->disk);
@@ -3301,6 +3415,8 @@ static void nvme_validate_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	if (ns) {
 		if (ns->disk && revalidate_disk(ns->disk))
 			nvme_ns_remove(ns);
+		else
+			nvme_update_ns(ctrl, ns);
 		nvme_put_ns(ns);
 	} else
 		nvme_alloc_ns(ctrl, nsid);
@@ -3654,6 +3770,7 @@ static void nvme_free_ctrl(struct device *dev)
 		sysfs_remove_link(&subsys->dev.kobj, dev_name(ctrl->device));
 	}
 
+	nvme_mdev_remove_ctrl(ctrl);
 	ctrl->ops->free_ctrl(ctrl);
 
 	if (subsys)
@@ -3726,6 +3843,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
 	dev_pm_qos_update_user_latency_tolerance(ctrl->device,
 		min(default_ps_max_latency_us, (unsigned long)S32_MAX));
 
+	nvme_mdev_add_ctrl(ctrl);
+
 	return 0;
 out_free_name:
 	kfree_const(ctrl->device->kobj.name);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9320b0a87d79..2df6c9f0e1cc 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -151,6 +151,7 @@ enum nvme_ctrl_state {
 };
 
 struct nvme_ctrl {
+	struct list_head link;
 	bool comp_seen;
 	enum nvme_ctrl_state state;
 	bool identified;
@@ -253,6 +254,23 @@ struct nvme_ctrl {
 	unsigned long discard_page_busy;
 };
 
+#ifdef CONFIG_NVME_MDEV
+/* Interface to the host driver  */
+struct nvme_mdev_driver {
+	struct module *owner;
+
+	/* a controller state has changed*/
+	void (*nvme_ctrl_state_changed)(struct nvme_ctrl *ctrl);
+
+	/* NS is updated in some way (after format or so) */
+	void (*nvme_ns_state_changed)(struct nvme_ctrl *ctrl,
+				      u32 nsid, bool removed);
+};
+
+int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops);
+void nvme_core_unregister_mdev_driver(struct nvme_mdev_driver *driver_ops);
+#endif
+
 struct nvme_subsystem {
 	int			instance;
 	struct device		dev;
@@ -275,7 +293,7 @@ struct nvme_subsystem {
 };
 
 /*
- * Container structure for uniqueue namespace identifiers.
+ * Container structure for unique namespace identifiers.
  */
 struct nvme_ns_ids {
 	u8	eui64[8];
@@ -351,13 +369,22 @@ struct nvme_ns {
 
 };
 
+struct nvme_ext_data_iter;
+struct nvme_ext_cmd_result {
+	u32 tag;
+	u16 status;
+};
+
 struct nvme_ctrl_ops {
 	const char *name;
 	struct module *module;
 	unsigned int flags;
-#define NVME_F_FABRICS			(1 << 0)
-#define NVME_F_METADATA_SUPPORTED	(1 << 1)
-#define NVME_F_PCI_P2PDMA		(1 << 2)
+#define NVME_F_FABRICS			BIT(0)
+#define NVME_F_METADATA_SUPPORTED	BIT(1)
+#define NVME_F_PCI_P2PDMA		BIT(2)
+#define NVME_F_MDEV_SUPPORTED		BIT(3)
+#define NVME_F_MDEV_DMA_SUPPORTED	BIT(4)
+
 	int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
 	int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
 	int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
@@ -366,6 +393,23 @@ struct nvme_ctrl_ops {
 	void (*delete_ctrl)(struct nvme_ctrl *ctrl);
 	int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
 	void (*stop_ctrl)(struct nvme_ctrl *ctrl);
+
+#ifdef CONFIG_NVME_MDEV
+	int (*ext_queues_available)(struct nvme_ctrl *ctrl);
+	int (*ext_queue_alloc)(struct nvme_ctrl *ctrl, u16 *qid);
+	void (*ext_queue_free)(struct nvme_ctrl *ctrl, u16 qid);
+
+	int (*ext_queue_submit)(struct nvme_ctrl *ctrl,
+				u16 qid, u32 tag,
+				struct nvme_command *command,
+				struct nvme_ext_data_iter *iter);
+
+	bool (*ext_queue_full)(struct nvme_ctrl *ctrl, u16 qid);
+
+	int (*ext_queue_poll)(struct nvme_ctrl *ctrl, u16 qid,
+			      struct nvme_ext_cmd_result *results,
+			      unsigned int max_len);
+#endif
 };
 
 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
@@ -427,6 +471,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl);
 void nvme_put_ctrl(struct nvme_ctrl *ctrl);
 int nvme_init_identify(struct nvme_ctrl *ctrl);
 
+struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned int nsid);
+void nvme_put_ns(struct nvme_ns *ns);
 void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
 
 int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 8/9] nvme/core: add nvme-mdev core driver
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


This is main commit in the series, adding the mediated nvme
driver.

The idea behind this driver is based on paper you can find at
https://www.usenix.org/conference/atc18/presentation/peng
But this is an independent implementation.

This mdev device exposes a NVME 1.3 virtual device to any VFIO user
which represents an partition (or whole namespace) of a host NVME device.

Unlike the paper, the driver/device uses
one polling thread per mediated device,
and only needs one hw queue per it to achieve near native performance
(but can use more that one hw queue, in which case it splits the queues
between virtual nvme queues thus supporting n:m mapping between
host hw queues and the guest virtual queues).

The nvme-mdev can't yet be used after this commit, as no nvme device
drivers support mediation (support is added in the next commit to
nvme-pci)

The driver can use the shadow doorbell nvme optional feature,
to stop polling after a timeout.

Currently the device has redhat	pci vendor ID, and 0x1234 pci device id,
which is only a	placeholder till a real	device id is allocated.

Use example:

# load the nvme-mdev driver
$ modprobe nvme-mdev

# load the nvme pci driver with 4 polling queues reserved
# (will work with the next patch)
$ modprobe nvme mdev_queues=4


# generate random UUID for the mediated device
$ UUID=$(uuidgen)
$ MDEV_DEVICE=/sys/bus/mdev/devices/$UUID

# the location of the real nvme device (replace with yours)
$ PCI_DEVICE=/sys/bus/pci/devices/0000:44:00.0

# create the mediated device using 2 host polling queues
$ echo $UUID > $PCI_DEVICE/mdev_supported_types/nvme-2Q_V1/create

# attach partition 1 of namespace 1 to a free virtual namespace
# (use n1 to attach whole namespace)
# you can attach up to 16 virtual namespaces for now
$ echo n1p1 > $MDEV_DEVICE/namespaces/add_namespace

# move the polling thread to cpu 11
$ echo 11 > $MDEV_DEVICE/settings/iothread_cpu

# now you can boot qemu with
#  -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID

Note that you can attach and detach virtual namespaces
even while the guest is running which will make the
device sent namespace changed AEN notifications to the guest
prior to attach/detach action.

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 MAINTAINERS                  |   5 +
 drivers/nvme/Kconfig         |   1 +
 drivers/nvme/Makefile        |   1 +
 drivers/nvme/host/core.c     |   5 +-
 drivers/nvme/mdev/Kconfig    |  16 +
 drivers/nvme/mdev/Makefile   |   5 +
 drivers/nvme/mdev/adm.c      | 873 +++++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/events.c   | 142 ++++++
 drivers/nvme/mdev/host.c     | 491 ++++++++++++++++++++
 drivers/nvme/mdev/instance.c | 802 ++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/io.c       | 563 ++++++++++++++++++++++
 drivers/nvme/mdev/irq.c      | 264 +++++++++++
 drivers/nvme/mdev/mdev.h     |  56 +++
 drivers/nvme/mdev/mmio.c     | 591 ++++++++++++++++++++++++
 drivers/nvme/mdev/pci.c      | 247 ++++++++++
 drivers/nvme/mdev/priv.h     | 700 ++++++++++++++++++++++++++++
 drivers/nvme/mdev/udata.c    | 390 ++++++++++++++++
 drivers/nvme/mdev/vcq.c      | 209 +++++++++
 drivers/nvme/mdev/vctrl.c    | 515 +++++++++++++++++++++
 drivers/nvme/mdev/viommu.c   | 322 +++++++++++++
 drivers/nvme/mdev/vns.c      | 356 ++++++++++++++
 drivers/nvme/mdev/vsq.c      | 181 ++++++++
 22 files changed, 6733 insertions(+), 2 deletions(-)
 create mode 100644 drivers/nvme/mdev/Kconfig
 create mode 100644 drivers/nvme/mdev/Makefile
 create mode 100644 drivers/nvme/mdev/adm.c
 create mode 100644 drivers/nvme/mdev/events.c
 create mode 100644 drivers/nvme/mdev/host.c
 create mode 100644 drivers/nvme/mdev/instance.c
 create mode 100644 drivers/nvme/mdev/io.c
 create mode 100644 drivers/nvme/mdev/irq.c
 create mode 100644 drivers/nvme/mdev/mdev.h
 create mode 100644 drivers/nvme/mdev/mmio.c
 create mode 100644 drivers/nvme/mdev/pci.c
 create mode 100644 drivers/nvme/mdev/priv.h
 create mode 100644 drivers/nvme/mdev/udata.c
 create mode 100644 drivers/nvme/mdev/vcq.c
 create mode 100644 drivers/nvme/mdev/vctrl.c
 create mode 100644 drivers/nvme/mdev/viommu.c
 create mode 100644 drivers/nvme/mdev/vns.c
 create mode 100644 drivers/nvme/mdev/vsq.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dce5c099f43c..d143e929d7ed 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10896,6 +10896,11 @@ W:	http://git.infradead.org/nvme.git
 S:	Supported
 F:	drivers/nvme/target/
 
+NVM EXPRESS MDEV DRIVER
+M:	Maxim Levitsky <mlevitsk at redhat.com>
+S:	Supported
+F:	drivers/nvme/mdev/
+
 NVMEM FRAMEWORK
 M:	Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
 S:	Maintained
diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig
index 04008e0bbe81..cbf867e6ac1e 100644
--- a/drivers/nvme/Kconfig
+++ b/drivers/nvme/Kconfig
@@ -2,5 +2,6 @@ menu "NVME Support"
 
 source "drivers/nvme/host/Kconfig"
 source "drivers/nvme/target/Kconfig"
+source "drivers/nvme/mdev/Kconfig"
 
 endmenu
diff --git a/drivers/nvme/Makefile b/drivers/nvme/Makefile
index 0096a7fd1431..0458efc57aee 100644
--- a/drivers/nvme/Makefile
+++ b/drivers/nvme/Makefile
@@ -1,3 +1,4 @@
 
 obj-y		+= host/
 obj-y		+= target/
+obj-y		+= mdev/
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 90561973bce9..a835884fcbcd 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1687,6 +1687,7 @@ static void nvme_update_disk_info(struct gendisk *disk,
 	if (ns->ms && !ns->ext &&
 	    (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
 		nvme_init_integrity(disk, ns->ms, ns->pi_type);
+
 	if (ns->ms && !nvme_ns_has_pi(ns) && !blk_get_integrity(disk))
 		capacity = 0;
 
@@ -2302,7 +2303,7 @@ static void nvme_init_subnqn(struct nvme_subsystem *subsys, struct nvme_ctrl *ct
 	size_t nqnlen;
 	int off;
 
-	if(!(ctrl->quirks & NVME_QUIRK_IGNORE_DEV_SUBNQN)) {
+	if (!(ctrl->quirks & NVME_QUIRK_IGNORE_DEV_SUBNQN)) {
 		nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
 		if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
 			strlcpy(subsys->subnqn, id->subnqn, NVMF_NQN_SIZE);
@@ -3361,8 +3362,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 
 	nvme_mpath_add_disk(ns, id);
 	nvme_fault_inject_init(ns);
-	kfree(id);
 
+	kfree(id);
 	return;
  out_put_disk:
 	put_disk(ns->disk);
diff --git a/drivers/nvme/mdev/Kconfig b/drivers/nvme/mdev/Kconfig
new file mode 100644
index 000000000000..7ebc66cdeac0
--- /dev/null
+++ b/drivers/nvme/mdev/Kconfig
@@ -0,0 +1,16 @@
+
+config NVME_MDEV
+	bool
+
+config NVME_MDEV_VFIO
+	tristate "NVME Mediated VFIO virtual device"
+	select NVME_MDEV
+	depends on BLOCK
+	depends on VFIO_MDEV
+	depends on NVME_CORE
+	help
+	  This provides EXPEREMENTAL support for lightweight software
+	  passthrough of an partition on a NVME storage device to
+	  guest, also as a NVME namespace, attached to a virtual NVME
+	  controller
+	  If unsure, say N.
diff --git a/drivers/nvme/mdev/Makefile b/drivers/nvme/mdev/Makefile
new file mode 100644
index 000000000000..114016c48476
--- /dev/null
+++ b/drivers/nvme/mdev/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_NVME_MDEV_VFIO) 	+=	nvme-mdev.o
+
+nvme-mdev-y += adm.o events.o instance.o host.o io.o irq.o \
+	       udata.o viommu.o vns.o vsq.o vcq.o vctrl.o mmio.o pci.o
diff --git a/drivers/nvme/mdev/adm.c b/drivers/nvme/mdev/adm.c
new file mode 100644
index 000000000000..39a7ad252c69
--- /dev/null
+++ b/drivers/nvme/mdev/adm.c
@@ -0,0 +1,873 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe admin command implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+struct adm_ctx {
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl;
+	const struct nvme_command *in;
+	struct nvme_mdev_vns *ns;
+	struct nvme_ext_data_iter udatait;
+	unsigned int datalen;
+};
+
+/*Identify Controller */
+static int nvme_mdev_adm_handle_id_cntrl(struct adm_ctx *ctx)
+{
+	int ret;
+	const struct nvme_identify *in = &ctx->in->identify;
+	struct nvme_id_ctrl *id;
+
+	if (in->nsid != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	id =  kzalloc(sizeof(*id), GFP_KERNEL);
+	if (!id)
+		return NVME_SC_INTERNAL;
+
+	/** Controller Capabilities and Features ************************/
+	// PCI vendor ID
+	store_le16(&id->vid, NVME_MDEV_PCI_VENDOR_ID);
+	// PCI Subsystem Vendor ID
+	store_le16(&id->ssvid, NVME_MDEV_PCI_SUBVENDOR_ID);
+	// Serial Number
+	store_strsp(id->sn, ctx->vctrl->serial);
+	// Model Number
+	store_strsp(id->mn, "NVMe MDEV virtual device");
+	// Firmware Revision
+	store_strsp(id->fr, NVME_MDEV_FIRMWARE_VERSION);
+	// Recommended Arbitration Burst
+	id->rab = 6;
+	// IEEE OUI Identifier for the controller vendor
+	id->ieee[0] = 0;
+	// Controller Multi-Path I/O and Namespace Sharing Capabilities
+	id->cmic = 0;
+	// Maximum Data Transfer Size (power of two, in page size units)
+	id->mdts = ctx->hctrl->mdts;
+	// controller ID
+	id->cntlid = 0;
+	// NVME supported version
+	store_le32(&id->ver, NVME_MDEV_NVME_VER);
+	// RTD3 Resume Latency
+	id->rtd3r = 0;
+	//RTD3 Entry Latency
+	id->rtd3e = 0;
+	// Optional Asynchronous Events Supported
+	store_le32(&id->oaes, NVME_AEN_CFG_NS_ATTR);
+	// Controller Attributes (misc junk)
+	id->ctratt = 0;
+
+	/*Admin Command Set Attributes & Optional Controller Capabilities */
+	// Optional Admin Command Support
+	id->oacs = ctx->vctrl->mmio.shadow_db_supported ?
+			NVME_CTRL_OACS_DBBUF_SUPP : 0;
+	// Abort Command Limit (dummy, zero based)
+	id->acl = 3;
+	 // Asynchronous Event Request Limit (zero based)
+	id->aerl = MAX_AER_COMMANDS - 1;
+	// Firmware Updates (dummy)
+	id->frmw = 3;
+	// Log Page Attributes
+	// (IMPLEMENT: bit for commands supported and effects)
+	id->lpa = 0;
+	// Error Log Page Entries
+	// (zero based, IMPLEMENT: dummy for now)
+	id->elpe = 0;
+	// Number of Power States Support
+	// (zero based, IMPLEMENT: dummy for now)
+	id->npss = 0;
+	// Admin Vendor Specific Command Configuration (junk)
+	id->avscc = 0;
+	// Autonomous Power State Transition Attributes
+	id->apsta = 0;
+	// Warning Composite Temperature Threshold (dummy)
+	id->wctemp = 0x157;
+	// Critical Composite Temperature Threshold (dummy)
+	id->cctemp = 0x175;
+	// Maximum Time for Firmware Activation (dummy)
+	id->mtfa = 0;
+	// Host Memory Buffer Preferred Size (dummy)
+	id->hmpre = 0;
+	// Host Memory Buffer Minimum Size (dummy)
+	id->hmmin = 0;
+	// Total NVM Capacity (not supported)
+	id->tnvmcap[0] = 0;
+	// Unallocated NVM Capacity (not supported for now)
+	id->unvmcap[0] = 0;
+	// Replay Protected Memory Block Support
+	id->rpmbs = 0;
+	// Extended Device Self-test Time (dummy)
+	id->edstt = 0;
+	// Device Self-test Options (dummy)
+	id->dsto = 0;
+	// Firmware Update Granularity (dummy)
+	id->fwug = 0;
+	// Keep Alive Support (not supported)
+	id->kas = 0;
+	// Host Controlled Thermal Management Attributes (not supported)
+	id->hctma = 0;
+	// Minimum Thermal Management Temperature (not supported)
+	id->mntmt = 0;
+	// Maximum Thermal Management Temperature (not supported)
+	id->mxtmt = 0;
+	// Sanitize capabilities (not supported)
+	id->sanicap = 0;
+
+	/****************** NVM Command Set Attributes ********************/
+	// Submission Queue Entry Size
+	id->sqes = (0x6 << 4) | 0x6;
+	// Completion Queue Entry Size
+	id->cqes = (0x4 << 4) | 0x4;
+	// Maximum Outstanding Commands
+	id->maxcmd = 0;
+	// Number of Namespaces
+	id->nn = MAX_VIRTUAL_NAMESPACES;
+	// Optional NVM Command Support
+	// (we add dsm and write zeros if host supports them)
+	id->oncs = ctx->hctrl->oncs;
+	// TODOLATER: IO: Fused Operation Support
+	id->fuses = 0;
+	// Format NVM Attributes (don't support)
+	id->fna = 0;
+	// Volatile Write Cache (tell that always exist)
+	id->vwc = 1;
+	// Atomic Write Unit Normal (zero based value in blocks)
+	id->awun = 0;
+	// Atomic Write Unit Power Fail (ditto)
+	id->awupf = 0;
+	// NVM Vendor Specific Command Configuration
+	id->nvscc = 0;
+	// Atomic Compare & Write Unit  (zero based value in blocks)
+	id->acwu = 0;
+	// SGL Support
+	id->sgls = 0;
+	// NVM Subsystem NVMe Qualified Name
+	strncpy(id->subnqn, ctx->vctrl->subnqn, sizeof(id->subnqn));
+
+	/******************Power state descriptors ***********************/
+	store_le16(&id->psd[0].max_power, 0x9c4); // dummy
+	store_le32(&id->psd[0].entry_lat, 0x10);
+	store_le32(&id->psd[0].exit_lat, 0x4);
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, id, sizeof(*id));
+	kfree(id);
+	return nvme_mdev_translate_error(ret);
+}
+
+/*Identify Namespace data structure for the specified NSID or common one */
+static int nvme_mdev_adm_handle_id_ns(struct adm_ctx *ctx)
+{
+	int ret;
+	struct nvme_id_ns *idns;
+	u32 nsid = le32_to_cpu(ctx->in->identify.nsid);
+
+	if (nsid == 0xffffffff || nsid == 0 || nsid > MAX_VIRTUAL_NAMESPACES)
+		return DNR(NVME_SC_INVALID_NS);
+
+	/* Allocate return structure*/
+	idns =  kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+	if (!idns)
+		return NVME_SC_INTERNAL;
+
+	if (ctx->ns) {
+		//Namespace Size
+		store_le64(&idns->nsze, ctx->ns->ns_size);
+		// Namespace Capacity
+		store_le64(&idns->ncap, ctx->ns->ns_size);
+		// Namespace Utilization
+		store_le64(&idns->nuse, ctx->ns->ns_size);
+		// Namespace Features (nothing to set here yet)
+		idns->nsfeat = 0;
+		// Number of LBA Formats (dummy, zero based)
+		idns->nlbaf = 0;
+		// Formatted LBA Size (current LBA format in use)
+		// + external metadata bit
+		idns->flbas = 0;
+		// Metadata Capabilities
+		idns->mc = 0;
+		// End-to-end Data Protection Capabilities
+		idns->dpc = 0;
+		// End-to-end Data Protection Type Settings
+		idns->dps = 0;
+		// Namespace Multi-path I/O and Namespace Sharing Capabilities
+		idns->nmic = 0;
+		// Reservation Capabilities
+		idns->rescap = 0;
+		// Format Progress Indicator (dummy)
+		idns->fpi = 0;
+		// Namespace Atomic Write Unit Normal
+		idns->nawun = 0;
+		// Namespace Atomic Write Unit Power Fail
+		idns->nawupf = 0;
+		// Namespace Atomic Compare & Write Unit
+		idns->nacwu = 0;
+		// Namespace Atomic Boundary Size Normal
+		idns->nabsn = 0;
+		// Namespace Atomic Boundary Offset
+		idns->nabo = 0;
+		// Namespace Atomic Boundary Size Power Fail
+		idns->nabspf = 0;
+		// Namespace Optimal IO Boundary
+		idns->noiob = ctx->ns->noiob;
+		// NVM Capacity (another capacity but in bytes)
+		idns->nvmcap[0]  = 0;
+
+		// TODOLATER: NS: support NGUID/EUI64
+		idns->nguid[0] = 0;
+		idns->eui64[0] = 0;
+		// format 0 metadata size
+		idns->lbaf[0].ms = 0;
+		// format 0 block size (in power of two)
+		idns->lbaf[0].ds = ctx->ns->blksize_shift;
+		// format 0 relative performance
+		idns->lbaf[0].rp = 0;
+	}
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, idns,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(idns);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Namespace Identification Descriptor list for the specified NSID.*/
+static int nvme_mdev_adm_handle_id_ns_desc(struct adm_ctx *ctx)
+{
+	struct ns_desc {
+		struct nvme_ns_id_desc uuid_desc;
+		uuid_t uuid;
+		struct nvme_ns_id_desc null_desc;
+	};
+
+	int ret;
+	struct ns_desc *id;
+
+	if (!ctx->ns)
+		return DNR(NVME_SC_INVALID_NS);
+
+	/* Allocate return structure */
+	id = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+	if (!id)
+		return NVME_SC_INTERNAL;
+
+	id->uuid_desc.nidt = NVME_NIDT_UUID;
+	id->uuid_desc.nidl = NVME_NIDT_UUID_LEN;
+	memcpy(&id->uuid, &ctx->ns->uuid, sizeof(id->uuid));
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, id,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(id);
+	return nvme_mdev_translate_error(ret);
+}
+
+/*Active Namespace ID list */
+static int nvme_mdev_adm_handle_id_active_ns_list(struct adm_ctx *ctx)
+{
+	u32 nsid, start_nsid = le32_to_cpu(ctx->in->identify.nsid);
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	int i = 0, ret;
+
+	__le32 *nslist = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+
+	if (start_nsid >= 0xfffffffe)
+		return DNR(NVME_SC_INVALID_NS);
+
+	for (nsid = start_nsid + 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++)
+		if (nvme_mdev_vns_from_vnsid(vctrl, nsid))
+			nslist[i++] = nsid;
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, nslist,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(nslist);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Handle Identify command*/
+static int nvme_mdev_adm_handle_id(struct adm_ctx *ctx)
+{
+	const struct nvme_identify *in = &ctx->in->identify;
+
+	int ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait,
+						&ctx->in->common.dptr,
+						NVME_IDENTIFY_DATA_SIZE);
+
+	u32 nsid = le32_to_cpu(in->nsid);
+
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (in->ctrlid)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->ns = nvme_mdev_vns_from_vnsid(ctx->vctrl, nsid);
+
+	switch (ctx->in->identify.cns) {
+	case NVME_ID_CNS_CTRL:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY CTRL\n");
+		return nvme_mdev_adm_handle_id_cntrl(ctx);
+	case NVME_ID_CNS_NS_ACTIVE_LIST:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY ACTIVE_NS_LIST\n");
+		return nvme_mdev_adm_handle_id_active_ns_list(ctx);
+	case NVME_ID_CNS_NS:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY NS=0x%08x\n", nsid);
+		return nvme_mdev_adm_handle_id_ns(ctx);
+	case NVME_ID_CNS_NS_DESC_LIST:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY NS_DESC NS=0x%08x\n", nsid);
+		return nvme_mdev_adm_handle_id_ns_desc(ctx);
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Error log for AER */
+static int nvme_mdev_adm_handle_get_log_page_err(struct adm_ctx *ctx)
+{
+	struct nvme_err_log_entry dummy_entry;
+	int ret;
+
+	// write one dummy entry with 0 error count
+	memset(&dummy_entry, 0, sizeof(dummy_entry));
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait,
+				       &dummy_entry,
+				       min((unsigned int)sizeof(dummy_entry),
+					   ctx->datalen));
+
+	return nvme_mdev_translate_error(ret);
+}
+
+/* This log page allows to tell user about connected/disconnected namespaces */
+static int nvme_mdev_adm_handle_get_log_page_changed_ns(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min(ctx->vctrl->ns_log_size * 4, ctx->datalen);
+
+	int ret = nvme_mdev_write_to_udata(&ctx->udatait,
+					   &ctx->vctrl->ns_log, datasize);
+
+	nvme_mdev_vns_log_reset(ctx->vctrl);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* S.M.A.R.T. log*/
+static int nvme_mdev_adm_handle_get_log_page_smart(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min_t(unsigned int,
+			sizeof(struct nvme_smart_log), ctx->datalen);
+	int ret;
+	struct nvme_smart_log *log = kzalloc(sizeof(*log), GFP_KERNEL);
+
+	if (!log)
+		return NVME_SC_INTERNAL;
+
+	/* Some dummy values */
+	log->avail_spare = 100;
+	log->spare_thresh = 10;
+	store_le16(&log->temperature, 0x140);
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, log, datasize);
+	kfree(log);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* FW slot log - useless */
+static int nvme_mdev_adm_handle_get_log_page_fw_slot(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min_t(unsigned int,
+				      sizeof(struct nvme_fw_slot_info_log),
+				      ctx->datalen);
+	int ret;
+	struct nvme_fw_slot_info_log *log = kzalloc(sizeof(*log), GFP_KERNEL);
+
+	if (!log)
+		return NVME_SC_INTERNAL;
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, log, datasize);
+	kfree(log);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to GET LOG PAGE command */
+static int nvme_mdev_adm_handle_get_log_page(struct adm_ctx *ctx)
+{
+	const struct nvme_get_log_page_command *in = &ctx->in->get_log_page;
+	u8 log_page_id = ctx->in->get_log_page.lid;
+	int ret;
+
+	ctx->datalen = (le16_to_cpu(in->numdl) + 1) * 4;
+
+	/*  We don't support extensions (NUMDU,LPOL,LPOU) */
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* Currently ignore the NSID in the command */
+
+	/* ACK the AER */
+	if ((in->lsp & 0x80) == 0)
+		nvme_mdev_event_process_ack(ctx->vctrl, log_page_id);
+
+	/* map data pointer */
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait,
+					    &in->dptr, ctx->datalen);
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	switch (log_page_id) {
+	case NVME_LOG_ERROR:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : ERRLOG\n");
+		return nvme_mdev_adm_handle_get_log_page_err(ctx);
+	case NVME_LOG_CHANGED_NS:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : CHANGED_NS\n");
+		return nvme_mdev_adm_handle_get_log_page_changed_ns(ctx);
+	case NVME_LOG_SMART:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : SMART\n");
+		return nvme_mdev_adm_handle_get_log_page_smart(ctx);
+	case NVME_LOG_FW_SLOT:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : FWSLOT\n");
+		return nvme_mdev_adm_handle_get_log_page_fw_slot(ctx);
+	default:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : log page 0x%02x\n",
+		     log_page_id);
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Response to CREATE CQ command */
+static int nvme_mdev_adm_handle_create_cq(struct adm_ctx *ctx)
+{
+	int irq = -1, ret;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_create_cq *in = &ctx->in->create_cq;
+	u16 cqid = le16_to_cpu(in->cqid);
+	u16 qsize = le16_to_cpu(in->qsize);
+	u16 cq_flags = le16_to_cpu(in->cq_flags);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR_PRP2 |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* QID checks*/
+	if (!cqid ||
+	    cqid >= MAX_VIRTUAL_QUEUES || test_bit(cqid, vctrl->vcq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	/* Queue size checks*/
+	if (qsize > (MAX_VIRTUAL_QUEUE_DEPTH - 1) || qsize < 1)
+		return DNR(NVME_SC_QUEUE_SIZE);
+
+	/* Queue flags checks */
+	if (cq_flags & ~(NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (cq_flags & NVME_CQ_IRQ_ENABLED) {
+		irq = le16_to_cpu(in->irq_vector);
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_VECTOR);
+	}
+
+	ret = nvme_mdev_vcq_init(ctx->vctrl, cqid,
+				 le64_to_cpu(in->prp1),
+				 cq_flags & NVME_QUEUE_PHYS_CONTIG,
+				 qsize + 1, irq);
+
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to DELETE CQ command */
+static int nvme_mdev_adm_handle_delete_cq(struct adm_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_delete_queue *in =  &ctx->in->delete_queue;
+	u16 qid = le16_to_cpu(in->qid), sqid;
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!qid || qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vcq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	for_each_set_bit(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		if (vctrl->vsqs[sqid].vcq == &vctrl->vcqs[qid])
+			return DNR(NVME_SC_INVALID_QUEUE);
+
+	nvme_mdev_vcq_delete(vctrl, qid);
+	return NVME_SC_SUCCESS;
+}
+
+/* Response to CREATE SQ command */
+static int nvme_mdev_adm_handle_create_sq(struct adm_ctx *ctx)
+{
+	const struct nvme_create_sq *in = &ctx->in->create_sq;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	int ret;
+
+	u16 sqid = le16_to_cpu(in->sqid);
+	u16 cqid = le16_to_cpu(in->cqid);
+	u16 qsize = le16_to_cpu(in->qsize);
+	u16 sq_flags = le16_to_cpu(in->sq_flags);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR_PRP2 |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!sqid ||
+	    sqid >= MAX_VIRTUAL_QUEUES || test_bit(sqid, vctrl->vsq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	if (!cqid || cqid  >= MAX_VIRTUAL_QUEUES)
+		return DNR(NVME_SC_QID_INVALID);
+
+	if (!test_bit(cqid, vctrl->vcq_en))
+		return DNR(NVME_SC_CQ_INVALID);
+
+	/* Queue size checks */
+	if (qsize > (MAX_VIRTUAL_QUEUE_DEPTH - 1) || qsize < 1)
+		return DNR(NVME_SC_QUEUE_SIZE);
+
+	/* Queue flags checks */
+	if (sq_flags & ~(NVME_QUEUE_PHYS_CONTIG | NVME_SQ_PRIO_MASK))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ret = nvme_mdev_vsq_init(ctx->vctrl, sqid,
+				 le64_to_cpu(in->prp1),
+				 sq_flags & NVME_QUEUE_PHYS_CONTIG,
+				 qsize + 1, cqid);
+	if (ret)
+		goto error;
+
+	return NVME_SC_SUCCESS;
+error:
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to DELETE SQ command */
+static int nvme_mdev_adm_handle_delete_sq(struct adm_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_delete_queue *in =  &ctx->in->delete_queue;
+	u16 qid = le16_to_cpu(in->qid);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!qid || qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vsq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	nvme_mdev_vsq_delete(ctx->vctrl, qid);
+	return NVME_SC_SUCCESS;
+}
+
+/* Set the shadow doorbell */
+static int nvme_mdev_adm_handle_dbbuf(struct adm_ctx *ctx)
+{
+	const struct nvme_dbbuf *in = &ctx->in->dbbuf;
+	int ret;
+
+	dma_addr_t sdb_iova = le64_to_cpu(in->prp1);
+	dma_addr_t eidx_iova = le64_to_cpu(in->prp2);
+
+	/* Check if we support the shadow doorbell */
+	if (!ctx->vctrl->mmio.shadow_db_supported)
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	/* Don't allow to enable the shadow doorbell more that once */
+	if (ctx->vctrl->mmio.shadow_db_en)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* check input buffers */
+	if ((OFFSET_IN_PAGE(sdb_iova) != 0) || (OFFSET_IN_PAGE(eidx_iova) != 0))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* switch to the new doorbell buffer */
+	ret = nvme_mdev_mmio_enable_dbs_shadow(ctx->vctrl, sdb_iova, eidx_iova);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to GET_FEATURES command */
+static int nvme_mdev_adm_handle_get_features(struct adm_ctx *ctx)
+{
+	u32 value = 0;
+	u32 irq;
+	const struct nvme_features *in = &ctx->in->features;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	unsigned int tmp;
+
+	u32 fid = le32_to_cpu(in->fid);
+	u16 cid = le16_to_cpu(in->command_id);
+
+	_DBG(ctx->vctrl, "ADMINQ: GET_FEATURES FID=0x%x\n", fid);
+
+	/* common reserved bits*/
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* reserved bits in dword10*/
+	if (fid > 0xFF)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* reserved bits in dword11*/
+	if (fid != NVME_FEAT_IRQ_CONFIG && in->dword11 != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (fid) {
+	/* Number of queues */
+	case NVME_FEAT_NUM_QUEUES:
+		value = (MAX_VIRTUAL_QUEUES - 1) |
+			((MAX_VIRTUAL_QUEUES - 1) << 16);
+		goto out;
+
+	/* Arbitration */
+	case NVME_FEAT_ARBITRATION:
+		value = vctrl->arb_burst_shift & 0x7;
+		goto out;
+
+	/* Interrupt coalescing settings*/
+	case NVME_FEAT_IRQ_COALESCE:
+		tmp = vctrl->irqs.irq_coalesc_time_us;
+		do_div(tmp, 100);
+		value = (vctrl->irqs.irq_coalesc_max - 1) | (tmp << 8);
+		goto out;
+
+	/* Interrupt coalescing disable for a specific interrupt */
+	case NVME_FEAT_IRQ_CONFIG:
+		irq = le32_to_cpu(in->dword11);
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_FIELD);
+
+		value = irq;
+		if (vctrl->irqs.vecs[irq].irq_coalesc_en)
+			value |= (1 << 16);
+		goto out;
+
+	/* Volatile write cache */
+	case NVME_FEAT_VOLATILE_WC:
+		/*we always report write cache due to mediation*/
+		value = 0x1;
+		goto out;
+
+	/* Limited error recovery */
+	case NVME_FEAT_ERR_RECOVERY:
+		value = 0;
+		break;
+
+	/* Workload hint + power state */
+	case NVME_FEAT_POWER_MGMT:
+		value = vctrl->worload_hint << 4;
+		break;
+
+	/* Temperature threshold */
+	case NVME_FEAT_TEMP_THRESH:
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* AEN permanent masking*/
+	case NVME_FEAT_ASYNC_EVENT:
+		value = nvme_mdev_event_read_aen_config(vctrl);
+		goto out;
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+out:
+	nvme_mdev_vsq_cmd_done_adm(ctx->vctrl, value, cid, NVME_SC_SUCCESS);
+	return -1;
+}
+
+/* Response to SET_FEATURES command */
+static int nvme_mdev_adm_handle_set_features(struct adm_ctx *ctx)
+{
+	const struct nvme_features *in = &ctx->in->features;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+
+	u32 value = le32_to_cpu(in->dword11);
+	u8 fid = le32_to_cpu(in->fid) & 0xFF;
+	u16 cid = le16_to_cpu(in->command_id);
+	u32 nsid = le32_to_cpu(in->nsid);
+
+	_DBG(ctx->vctrl, "ADMINQ: SET_FEATURES cmd. FID=0x%x\n", fid);
+
+	if (nsid != 0xffffffff && nsid != 0)
+		return DNR(NVME_SC_FEATURE_NOT_PER_NS);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (fid) {
+	case NVME_FEAT_NUM_QUEUES:
+		/* need to return the value here as well */
+		value = (MAX_VIRTUAL_QUEUES - 1) |
+			((MAX_VIRTUAL_QUEUES - 1) << 16);
+
+		nvme_mdev_vsq_cmd_done_adm(ctx->vctrl, value,
+					   cid, NVME_SC_SUCCESS);
+		return -1;
+
+	case NVME_FEAT_ARBITRATION:
+		vctrl->arb_burst_shift = value & 0x7;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_IRQ_COALESCE:
+		vctrl->irqs.irq_coalesc_max = (value & 0xFF) + 1;
+		vctrl->irqs.irq_coalesc_time_us = ((value >> 8) & 0xFF) * 100;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_IRQ_CONFIG: {
+		u16 irq = value & 0xFFFF;
+
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_FIELD);
+
+		vctrl->irqs.vecs[irq].irq_coalesc_en = (value & 0x10000) != 0;
+		return NVME_SC_SUCCESS;
+	}
+	case NVME_FEAT_VOLATILE_WC:
+		return (value != 0x1) ? DNR(NVME_SC_FEATURE_NOT_CHANGEABLE) :
+							NVME_SC_SUCCESS;
+
+	case NVME_FEAT_ERR_RECOVERY:
+		return (value != 0) ? DNR(NVME_SC_FEATURE_NOT_CHANGEABLE) :
+							NVME_SC_SUCCESS;
+	case NVME_FEAT_POWER_MGMT:
+		if (value & 0xFFFFFF0F)
+			return DNR(NVME_SC_INVALID_FIELD);
+		vctrl->worload_hint = value >> 4;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_TEMP_THRESH:
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	case NVME_FEAT_ASYNC_EVENT:
+		nvme_mdev_event_set_aen_config(vctrl, value);
+		return NVME_SC_SUCCESS;
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Response to AER command */
+static int nvme_mdev_adm_handle_async_event(struct adm_ctx *ctx)
+{
+	u16 cid = le16_to_cpu(ctx->in->common.command_id);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	return nvme_mdev_event_request_receive(ctx->vctrl, cid);
+}
+
+/* (Dummy) response to ABORT command*/
+static int nvme_mdev_adm_handle_abort(struct adm_ctx *ctx)
+{
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	return DNR(NVME_SC_ABORT_MISSING);
+}
+
+/* Process one new command in the admin queue*/
+static int nvme_mdev_adm_handle_cmd(struct adm_ctx *ctx)
+{
+	u8 optcode = ctx->in->common.opcode;
+
+	ctx->ns = NULL;
+	ctx->datalen = 0;
+
+	if (ctx->in->common.flags != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (optcode) {
+	case nvme_admin_identify:
+		return nvme_mdev_adm_handle_id(ctx);
+	case nvme_admin_create_cq:
+		_DBG(ctx->vctrl, "ADMINQ: CREATE_CQ\n");
+		return nvme_mdev_adm_handle_create_cq(ctx);
+	case nvme_admin_create_sq:
+		_DBG(ctx->vctrl, "ADMINQ: CREATE_SQ\n");
+		return nvme_mdev_adm_handle_create_sq(ctx);
+	case nvme_admin_delete_sq:
+		_DBG(ctx->vctrl, "ADMINQ: DELETE_SQ\n");
+		return nvme_mdev_adm_handle_delete_sq(ctx);
+	case nvme_admin_delete_cq:
+		_DBG(ctx->vctrl, "ADMINQ: DELETE_CQ\n");
+		return nvme_mdev_adm_handle_delete_cq(ctx);
+	case nvme_admin_dbbuf:
+		_DBG(ctx->vctrl, "ADMINQ: DBBUF_CONFIG\n");
+		return nvme_mdev_adm_handle_dbbuf(ctx);
+	case nvme_admin_get_log_page:
+		return nvme_mdev_adm_handle_get_log_page(ctx);
+	case nvme_admin_get_features:
+		return nvme_mdev_adm_handle_get_features(ctx);
+	case nvme_admin_set_features:
+		return nvme_mdev_adm_handle_set_features(ctx);
+	case nvme_admin_async_event:
+		_DBG(ctx->vctrl, "ADMINQ: ASYNC_EVENT_REQ\n");
+		return nvme_mdev_adm_handle_async_event(ctx);
+	case nvme_admin_abort_cmd:
+		_DBG(ctx->vctrl, "ADMINQ: ABORT\n");
+		return nvme_mdev_adm_handle_abort(ctx);
+	default:
+		_DBG(ctx->vctrl, "ADMINQ: optcode 0x%04x\n", optcode);
+		return DNR(NVME_SC_INVALID_OPCODE);
+	}
+}
+
+/* Process all pending admin commands */
+void nvme_mdev_adm_process_sq(struct nvme_mdev_vctrl *vctrl)
+{
+	struct adm_ctx ctx;
+
+	lockdep_assert_held(&vctrl->lock);
+	memset(&ctx, 0, sizeof(struct adm_ctx));
+	ctx.vctrl = vctrl;
+	ctx.hctrl = vctrl->hctrl;
+	nvme_mdev_udata_iter_setup(&vctrl->viommu, &ctx.udatait);
+
+	nvme_mdev_io_pause(ctx.vctrl);
+
+	while (!(nvme_mdev_vctrl_is_dead(vctrl))) {
+		int ret;
+		u16 cid;
+
+		ctx.in = nvme_mdev_vsq_get_cmd(vctrl, &vctrl->vsqs[0]);
+		if (!ctx.in)
+			break;
+
+		cid = le16_to_cpu(ctx.in->common.command_id);
+		ret = nvme_mdev_adm_handle_cmd(&ctx);
+
+		if (ret == -1)
+			continue;
+
+		if (ret != 0)
+			_DBG(vctrl, "ADMINQ: CID 0x%x FAILED: status 0x%x\n",
+			     cid, ret);
+		nvme_mdev_vsq_cmd_done_adm(vctrl, 0, cid, ret);
+	}
+	nvme_mdev_io_resume(ctx.vctrl);
+}
diff --git a/drivers/nvme/mdev/events.c b/drivers/nvme/mdev/events.c
new file mode 100644
index 000000000000..9854c1cabdcb
--- /dev/null
+++ b/drivers/nvme/mdev/events.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe async events implementation (AER, changed namespace log)
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* complete an AER event on the admin queue if it is pending*/
+static void nvme_mdev_event_complete(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 lid, cid;
+	u32 dw0;
+
+	for_each_set_bit(lid, vctrl->events.events_pending, MAX_LOG_PAGES) {
+		/* we have pending aer requests, but no requests*/
+		if (vctrl->events.aer_cid_count == 0)
+			break;
+
+		if (!test_bit(lid, vctrl->events.events_enabled))
+			continue;
+
+		cid = vctrl->events.aer_cids[--vctrl->events.aer_cid_count];
+		dw0 = vctrl->events.event_values[lid];
+		clear_bit(lid, vctrl->events.events_pending);
+
+		_DBG(vctrl,
+		     "AEN: replying to AER (CID=%d) with status 0x%08x\n",
+		     cid, dw0);
+
+		nvme_mdev_vsq_cmd_done_adm(vctrl, dw0, cid, NVME_SC_SUCCESS);
+	}
+}
+
+/* deal with received async event request from the user*/
+int nvme_mdev_event_request_receive(struct nvme_mdev_vctrl *vctrl,
+				    u16 cid)
+{
+	int cnt = vctrl->events.aer_cid_count;
+
+	if (cnt >= MAX_AER_COMMANDS)
+		return DNR(NVME_SC_ASYNC_LIMIT);
+
+	/* don't allow AER to be pending if there is no space left in the
+	 * completion queue permanently
+	 */
+	if ((cnt + 1) >= vctrl->vcqs[0].size - 1)
+		return DNR(NVME_SC_ASYNC_LIMIT);
+
+	vctrl->events.aer_cids[cnt++] = cid;
+	vctrl->events.aer_cid_count = cnt;
+
+	_DBG(vctrl, "AEN: received new request (cid=%d)\n", cid);
+	nvme_mdev_event_complete(vctrl);
+	return -1;
+}
+
+/* Send an async event request */
+void nvme_mdev_event_send(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_async_event_type type,
+			  enum nvme_async_event info)
+{
+	u8 log_page;
+	u32 event;
+
+	// determine the log page for event types that we support
+	switch (type) {
+	case NVME_AER_TYPE_ERROR:
+		log_page = NVME_LOG_ERROR;
+		break;
+	case NVME_AER_TYPE_SMART:
+		log_page = NVME_LOG_SMART;
+		break;
+	case NVME_AER_TYPE_NOTICE:
+		WARN_ON(info != NVME_AER_NOTICE_NS_CHANGED);
+		log_page = NVME_LOG_CHANGED_NS;
+		break;
+	default:
+		WARN_ON(1);
+		return;
+	}
+
+	if (test_and_set_bit(log_page, vctrl->events.events_masked))
+		return;
+
+	event = (u32)type | ((u32)info << 8) | ((u32)log_page << 16);
+	vctrl->events.event_values[log_page] = event;
+	set_bit(log_page, vctrl->events.events_masked);
+	set_bit(log_page, vctrl->events.events_pending);
+	nvme_mdev_event_complete(vctrl);
+}
+
+u32 nvme_mdev_event_read_aen_config(struct nvme_mdev_vctrl *vctrl)
+{
+	u32 value = 0;
+
+	if (test_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled))
+		value |= NVME_AEN_CFG_NS_ATTR;
+	return value;
+}
+
+void nvme_mdev_event_set_aen_config(struct nvme_mdev_vctrl *vctrl, u32 value)
+{
+	_DBG(vctrl, "AEN: set config: 0x%04x\n", value);
+
+	if (value & NVME_AEN_CFG_NS_ATTR)
+		set_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+	else
+		clear_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+
+	nvme_mdev_event_complete(vctrl);
+}
+
+/* called when user acks an log page which causes an AER event to be unmasked*/
+void nvme_mdev_event_process_ack(struct nvme_mdev_vctrl *vctrl, u8 log_page)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	_DBG(vctrl, "AEN: log page %d ACK\n", log_page);
+
+	if (log_page >= MAX_LOG_PAGES)
+		return;
+
+	clear_bit(log_page, vctrl->events.events_masked);
+	nvme_mdev_event_complete(vctrl);
+}
+
+/* reset event state*/
+void nvme_mdev_events_init(struct nvme_mdev_vctrl *vctrl)
+{
+	memset(&vctrl->events, 0, sizeof(vctrl->events));
+	set_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+	set_bit(NVME_LOG_ERROR, vctrl->events.events_enabled);
+}
+
+/* reset event state*/
+void nvme_mdev_events_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	memset(&vctrl->events, 0, sizeof(vctrl->events));
+}
+
diff --git a/drivers/nvme/mdev/host.c b/drivers/nvme/mdev/host.c
new file mode 100644
index 000000000000..d90275baf5f8
--- /dev/null
+++ b/drivers/nvme/mdev/host.c
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe parent (host) device abstraction
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include <linux/mdev.h>
+#include <linux/module.h>
+#include "priv.h"
+
+static LIST_HEAD(nvme_mdev_hctrl_list);
+static DEFINE_MUTEX(nvme_mdev_hctrl_list_mutex);
+static struct nvme_mdev_inst_type **instance_types;
+
+unsigned int io_timeout_ms = 30000;
+module_param_named(io_timeout, io_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(io_timeout,
+		 "Maximum I/O command completion timeout (in msec)");
+
+unsigned int poll_timeout_ms = 500;
+module_param_named(poll_timeout, poll_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(poll_timeout,
+		 "Maximum idle time to keep polling (in msec) (0 - poll forever)");
+
+unsigned int admin_poll_rate_ms = 100;
+module_param_named(admin_poll_rate, poll_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(admin_poll_rate,
+		 "Admin queue polling rate (in msec) (used only when shadow doorbell is disabled)");
+
+bool use_shadow_doorbell = true;
+module_param(use_shadow_doorbell, bool, 0644);
+MODULE_PARM_DESC(use_shadow_doorbell,
+		 "Enable the shadow doorbell NVMe extension");
+
+/* Create a new host controller */
+static struct nvme_mdev_hctrl *nvme_mdev_hctrl_create(struct nvme_ctrl *ctrl)
+{
+	struct nvme_mdev_hctrl *hctrl;
+	u32 max_lba_transfer;
+
+	/* TODOLATER: IO: support more page size configurations*/
+	if (ctrl->page_size != PAGE_SIZE)
+		return NULL;
+
+	hctrl = kzalloc_node(sizeof(*hctrl), GFP_KERNEL,
+			     dev_to_node(ctrl->dev));
+	if (!hctrl)
+		return NULL;
+
+	kref_init(&hctrl->ref);
+	mutex_init(&hctrl->lock);
+
+	hctrl->nvme_ctrl = ctrl;
+	nvme_get_ctrl(ctrl);
+
+	hctrl->oncs = ctrl->oncs &
+		(NVME_CTRL_ONCS_DSM | NVME_CTRL_ONCS_WRITE_ZEROES);
+
+	hctrl->id = ctrl->instance;
+	hctrl->node = dev_to_node(ctrl->dev);
+
+	max_lba_transfer = ctrl->max_hw_sectors >> (PAGE_SHIFT - 9);
+	hctrl->mdts = ilog2(__rounddown_pow_of_two(max_lba_transfer));
+
+	hctrl->nr_host_queues = ctrl->ops->ext_queues_available(ctrl);
+
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+
+	dev_info(ctrl->dev,
+		 "mediated nvme support enabled, using up to %d host queues\n",
+		 hctrl->nr_host_queues);
+
+	list_add_tail(&hctrl->link, &nvme_mdev_hctrl_list);
+
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+
+	if (mdev_register_device(ctrl->dev, &mdev_fops) < 0) {
+		nvme_put_ctrl(ctrl);
+		kfree(hctrl);
+		return NULL;
+	}
+	return hctrl;
+}
+
+/* Release an unused host controller*/
+static void nvme_mdev_hctrl_free(struct kref *ref)
+{
+	struct nvme_mdev_hctrl *hctrl =
+		container_of(ref, struct nvme_mdev_hctrl, ref);
+
+	dev_info(hctrl->nvme_ctrl->dev, "mediated nvme support disabled");
+
+	nvme_put_ctrl(hctrl->nvme_ctrl);
+	hctrl->nvme_ctrl = NULL;
+	kfree(hctrl);
+}
+
+/* Lookup a host controller based on mdev parent device*/
+struct nvme_mdev_hctrl *nvme_mdev_hctrl_lookup_get(struct device *parent)
+{
+	struct nvme_mdev_hctrl *hctrl = NULL, *tmp;
+
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+	list_for_each_entry(tmp, &nvme_mdev_hctrl_list, link) {
+		if (tmp->nvme_ctrl->dev == parent) {
+			hctrl = tmp;
+			kref_get(&hctrl->ref);
+			break;
+		}
+	}
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+	return hctrl;
+}
+
+/* Release a held reference to a host controller*/
+void nvme_mdev_hctrl_put(struct nvme_mdev_hctrl *hctrl)
+{
+	kref_put(&hctrl->ref, nvme_mdev_hctrl_free);
+}
+
+/* Destroy a host controller. It might still be kept in zombie state
+ * if someone uses a reference to it
+ */
+static void nvme_mdev_hctrl_destroy(struct nvme_mdev_hctrl *hctrl)
+{
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+	list_del(&hctrl->link);
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+
+	hctrl->removing = true;
+	mdev_unregister_device(hctrl->nvme_ctrl->dev);
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+/* Check how many host queues are still available */
+int nvme_mdev_hctrl_hqs_available(struct nvme_mdev_hctrl *hctrl)
+{
+	int ret;
+
+	mutex_lock(&hctrl->lock);
+	ret =  hctrl->nr_host_queues;
+	mutex_unlock(&hctrl->lock);
+	return ret;
+}
+
+/* Reserve N host IO queues, for later allocation to a specific user*/
+bool nvme_mdev_hctrl_hqs_reserve(struct nvme_mdev_hctrl *hctrl,
+				 unsigned int n)
+{
+	mutex_lock(&hctrl->lock);
+
+	if (n > hctrl->nr_host_queues) {
+		mutex_unlock(&hctrl->lock);
+		return false;
+	}
+
+	hctrl->nr_host_queues -= n;
+	mutex_unlock(&hctrl->lock);
+	return true;
+}
+
+/* Free N host IO queues, for allocation for other users*/
+void nvme_mdev_hctrl_hqs_unreserve(struct nvme_mdev_hctrl *hctrl,
+				   unsigned int n)
+{
+	mutex_lock(&hctrl->lock);
+	hctrl->nr_host_queues += n;
+	mutex_unlock(&hctrl->lock);
+}
+
+/* Allocate a host IO queue */
+int nvme_mdev_hctrl_hq_alloc(struct nvme_mdev_hctrl *hctrl)
+{
+	u16 qid = 0;
+	int ret = hctrl->nvme_ctrl->ops->ext_queue_alloc(hctrl->nvme_ctrl,
+			&qid);
+
+	if (ret)
+		return ret;
+	return qid;
+}
+
+/* Free an host IO queue */
+void nvme_mdev_hctrl_hq_free(struct nvme_mdev_hctrl *hctrl, u16 qid)
+{
+	hctrl->nvme_ctrl->ops->ext_queue_free(hctrl->nvme_ctrl, qid);
+}
+
+/* Check if we can submit another IO passthrough command */
+bool nvme_mdev_hctrl_hq_can_submit(struct nvme_mdev_hctrl *hctrl, u16 qid)
+{
+	return hctrl->nvme_ctrl->ops->ext_queue_full(hctrl->nvme_ctrl, qid);
+}
+
+/* Check if IO passthrough is supported for given IO optcode */
+bool nvme_mdev_hctrl_hq_check_op(struct nvme_mdev_hctrl *hctrl, u8 optcode)
+{
+	switch (optcode) {
+	case nvme_cmd_flush:
+	case nvme_cmd_read:
+	case nvme_cmd_write:
+		/* these are mandatory*/
+		return true;
+	case nvme_cmd_write_zeroes:
+		return (hctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES);
+	case nvme_cmd_dsm:
+		return (hctrl->oncs & NVME_CTRL_ONCS_DSM);
+	default:
+		return false;
+	}
+}
+
+/* Submit a IO passthrough command */
+int nvme_mdev_hctrl_hq_submit(struct nvme_mdev_hctrl *hctrl,
+			      u16 qid, u32 tag,
+			      struct nvme_command *cmd,
+			      struct nvme_ext_data_iter *datait)
+{
+	struct nvme_ctrl *ctrl = hctrl->nvme_ctrl;
+
+	return ctrl->ops->ext_queue_submit(ctrl, qid, tag, cmd, datait);
+}
+
+/* Poll for completion of IO passthrough commands */
+int nvme_mdev_hctrl_hq_poll(struct nvme_mdev_hctrl *hctrl,
+			    u32 qid,
+			    struct nvme_ext_cmd_result *results,
+			    unsigned int max_len)
+{
+	struct nvme_ctrl *ctrl = hctrl->nvme_ctrl;
+
+	return ctrl->ops->ext_queue_poll(ctrl, qid, results, max_len);
+}
+
+/* Destroy all host controllers */
+void nvme_mdev_hctrl_destroy_all(void)
+{
+	struct nvme_mdev_hctrl *hctrl = NULL, *tmp;
+
+	list_for_each_entry_safe(hctrl, tmp, &nvme_mdev_hctrl_list, link) {
+		list_del(&hctrl->link);
+		hctrl->removing = true;
+		mdev_unregister_device(hctrl->nvme_ctrl->dev);
+		nvme_mdev_hctrl_put(hctrl);
+	}
+}
+
+/* Get the mdev instance given it sysfs name */
+struct nvme_mdev_inst_type *nvme_mdev_inst_type_get(const char *name)
+{
+	int i;
+
+	for (i = 0; instance_types[i]; i++) {
+		const char *test =
+			name + strlen(name) - strlen(instance_types[i]->name);
+
+		if (strcmp(instance_types[i]->name, test) == 0)
+			return instance_types[i];
+	}
+	return NULL;
+}
+
+/* This shows name of the instance type */
+static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)
+{
+	return sprintf(buf, "%s\n", kobj->name);
+}
+static MDEV_TYPE_ATTR_RO(name);
+
+/* This shows description of the instance type */
+static ssize_t description_show(struct kobject *kobj,
+				struct device *dev, char *buf)
+{
+	struct nvme_mdev_inst_type *type = nvme_mdev_inst_type_get(kobj->name);
+
+	return sprintf(buf,
+		       "MDEV nvme device, using maximum %d hw submission queues\n",
+		       type->max_hw_queues);
+}
+static MDEV_TYPE_ATTR_RO(description);
+
+/* This shows the device API of the instance type */
+static ssize_t device_api_show(struct kobject *kobj,
+			       struct device *dev, char *buf)
+{
+	return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
+}
+static MDEV_TYPE_ATTR_RO(device_api);
+
+/* This shows how many instances of this instance type can be created  */
+static ssize_t available_instances_show(struct kobject *kobj,
+					struct device *dev, char *buf)
+{
+	struct nvme_mdev_inst_type *type = nvme_mdev_inst_type_get(kobj->name);
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(dev);
+	int count;
+
+	if (!hctrl)
+		return -ENODEV;
+
+	count = nvme_mdev_hctrl_hqs_available(hctrl);
+	do_div(count, type->max_hw_queues);
+
+	nvme_mdev_hctrl_put(hctrl);
+	return sprintf(buf, "%d\n", count);
+}
+static MDEV_TYPE_ATTR_RO(available_instances);
+
+static struct attribute *nvme_mdev_types_attrs[] = {
+	&mdev_type_attr_name.attr,
+	&mdev_type_attr_description.attr,
+	&mdev_type_attr_device_api.attr,
+	&mdev_type_attr_available_instances.attr,
+	NULL,
+};
+
+/* Undo the creation of mdev array of instance types */
+static void nvme_mdev_instance_types_fini(struct mdev_parent_ops *ops)
+{
+	int i;
+
+	for (i = 0; instance_types[i]; i++) {
+		struct nvme_mdev_inst_type *type = instance_types[i];
+
+		kfree(type->attrgroup);
+		kfree(type);
+	}
+
+	kfree(instance_types);
+	instance_types = NULL;
+
+	kfree(ops->supported_type_groups);
+	ops->supported_type_groups = NULL;
+}
+
+/* Create the array of mdev instance types from our array of them */
+static int nvme_mdev_instance_types_init(struct mdev_parent_ops *ops)
+{
+	unsigned int i;
+	struct nvme_mdev_inst_type *type;
+	struct attribute_group *attrgroup;
+
+	ops->supported_type_groups = kzalloc(sizeof(struct attribute_group *)
+			* (MAX_HOST_QUEUES + 1), GFP_KERNEL);
+
+	if (!ops->supported_type_groups)
+		return -ENOMEM;
+
+	instance_types = kzalloc(sizeof(struct nvme_mdev_inst_type *)
+			* MAX_HOST_QUEUES + 1, GFP_KERNEL);
+
+	if (!instance_types) {
+		kfree(ops->supported_type_groups);
+		ops->supported_type_groups = NULL;
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_HOST_QUEUES; i++) {
+		type = kzalloc(sizeof(*type), GFP_KERNEL);
+		if (!type) {
+			nvme_mdev_instance_types_fini(ops);
+			return -ENOMEM;
+		}
+		snprintf(type->name, sizeof(type->name), "%dQ_V1", i + 1);
+		type->max_hw_queues = i + 1;
+
+		attrgroup = kzalloc(sizeof(*attrgroup), GFP_KERNEL);
+		if (!attrgroup) {
+			kfree(type);
+			nvme_mdev_instance_types_fini(ops);
+			return -ENOMEM;
+		}
+
+		attrgroup->attrs = nvme_mdev_types_attrs;
+		attrgroup->name = type->name;
+		type->attrgroup = attrgroup;
+		instance_types[i] = type;
+		ops->supported_type_groups[i] = attrgroup;
+	}
+	return 0;
+}
+
+/* Updates in host controller state*/
+static void nvme_mdev_nvme_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(ctrl->dev);
+	struct nvme_mdev_vctrl *vctrl;
+
+	switch (ctrl->state) {
+	case NVME_CTRL_NEW:
+		/* do nothing as new controller is not yet initialized*/
+		break;
+
+	case NVME_CTRL_LIVE:
+		/* new controller is live, create a mdev for it*/
+		if (!hctrl) {
+			hctrl = nvme_mdev_hctrl_create(ctrl);
+			return;
+		/* a controller is live again after reset/reconnect/suspend*/
+		} else {
+			mutex_lock(&nvme_mdev_vctrl_list_mutex);
+			list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+				if (vctrl->hctrl == hctrl)
+					nvme_mdev_vctrl_resume(vctrl);
+			mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+		}
+		break;
+
+	case NVME_CTRL_RESETTING:
+	case NVME_CTRL_CONNECTING:
+	case NVME_CTRL_SUSPENDED:
+		/* controller is temporarily not usable, stop using its queues*/
+		if (!hctrl)
+			return;
+
+		mutex_lock(&nvme_mdev_vctrl_list_mutex);
+		list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+			if (vctrl->hctrl == hctrl)
+				nvme_mdev_vctrl_pause(vctrl);
+		mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+		break;
+
+	case NVME_CTRL_DELETING:
+	case NVME_CTRL_DEAD:
+	case NVME_CTRL_ADMIN_ONLY:
+		/* host nvme controller is dead, remove it*/
+		if (!hctrl)
+			return;
+		nvme_mdev_hctrl_destroy(hctrl);
+		break;
+	}
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+/* A host namespace might have its properties changed/removed.*/
+static void nvme_mdev_nvme_ctrl_ns_updated(struct nvme_ctrl *ctrl,
+					   u32 nsid, bool removed)
+{
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(ctrl->dev);
+
+	if (!hctrl)
+		return;
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+		if (vctrl->hctrl == hctrl)
+			nvme_mdev_vns_host_ns_update(vctrl, nsid, removed);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+static struct nvme_mdev_driver nvme_mdev_driver = {
+	.owner = THIS_MODULE,
+	.nvme_ctrl_state_changed = nvme_mdev_nvme_ctrl_state_changed,
+	.nvme_ns_state_changed = nvme_mdev_nvme_ctrl_ns_updated,
+};
+
+static int __init nvme_mdev_init(void)
+{
+	int ret;
+
+	nvme_mdev_instance_types_init(&mdev_fops);
+	ret = nvme_core_register_mdev_driver(&nvme_mdev_driver);
+	if (ret) {
+		nvme_mdev_instance_types_fini(&mdev_fops);
+		return ret;
+	}
+
+	pr_info("nvme_mdev " NVME_MDEV_FIRMWARE_VERSION " loaded\n");
+	return 0;
+}
+
+static void __exit nvme_mdev_exit(void)
+{
+	nvme_core_unregister_mdev_driver(&nvme_mdev_driver);
+	nvme_mdev_hctrl_destroy_all();
+	nvme_mdev_instance_types_fini(&mdev_fops);
+	pr_info("nvme_mdev unloaded\n");
+}
+
+MODULE_AUTHOR("Maxim Levitsky <mlevitsk at redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(NVME_MDEV_FIRMWARE_VERSION);
+
+module_init(nvme_mdev_init)
+module_exit(nvme_mdev_exit)
+
diff --git a/drivers/nvme/mdev/instance.c b/drivers/nvme/mdev/instance.c
new file mode 100644
index 000000000000..da523006aeda
--- /dev/null
+++ b/drivers/nvme/mdev/instance.c
@@ -0,0 +1,802 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Mediated NVMe instance VFIO code
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/vfio.h>
+#include <linux/sysfs.h>
+#include <linux/mdev.h>
+#include "priv.h"
+
+#define OFFSET_TO_REGION(offset) ((offset) >> 20)
+#define REGION_TO_OFFSET(nr) (((u64)nr) << 20)
+
+LIST_HEAD(nvme_mdev_vctrl_list);
+/*protects the list */
+DEFINE_MUTEX(nvme_mdev_vctrl_list_mutex);
+
+struct mdev_nvme_vfio_region_info {
+	struct vfio_region_info base;
+	struct vfio_region_info_cap_sparse_mmap mmap_cap;
+};
+
+/* User memory added*/
+static int nvme_mdev_map_notifier(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	struct vfio_iommu_type1_dma_map *map = data;
+	struct nvme_mdev_vctrl *vctrl =
+		container_of(nb, struct nvme_mdev_vctrl, vfio_map_notifier);
+
+	int ret = nvme_mdev_vctrl_viommu_map(vctrl, map->flags,
+			map->iova, map->size);
+	return ret ? NOTIFY_OK : notifier_from_errno(ret);
+}
+
+/* User memory removed*/
+static int nvme_mdev_unmap_notifier(struct notifier_block *nb,
+				    unsigned long action, void *data)
+{
+	struct nvme_mdev_vctrl *vctrl =
+		container_of(nb, struct nvme_mdev_vctrl, vfio_unmap_notifier);
+	struct vfio_iommu_type1_dma_unmap *unmap = data;
+
+	int ret = nvme_mdev_vctrl_viommu_unmap(vctrl, unmap->iova, unmap->size);
+
+	WARN_ON(ret <= 0);
+	return NOTIFY_OK;
+}
+
+/* Called when new mediated device is created */
+static int nvme_mdev_ops_create(struct kobject *kobj, struct mdev_device *mdev)
+{
+	int ret = 0;
+	const struct nvme_mdev_inst_type *type = NULL;
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl = NULL;
+
+	hctrl = nvme_mdev_hctrl_lookup_get(mdev_parent_dev(mdev));
+	if (!hctrl)
+		return -ENODEV;
+
+	type = nvme_mdev_inst_type_get(kobj->name);
+	vctrl = nvme_mdev_vctrl_create(mdev, hctrl, type->max_hw_queues);
+
+	if (IS_ERR(vctrl))
+		ret = PTR_ERR(vctrl);
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_add_tail(&vctrl->link, &nvme_mdev_vctrl_list);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+
+	nvme_mdev_hctrl_put(hctrl);
+	return ret;
+}
+
+/* Called when a mediated device is removed */
+static int nvme_mdev_ops_remove(struct mdev_device *mdev)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return nvme_mdev_vctrl_destroy(vctrl);
+}
+
+/* Called when new mediated device is opened by a user */
+static int nvme_mdev_ops_open(struct mdev_device *mdev)
+{
+	int ret;
+	unsigned long events;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	ret =  nvme_mdev_vctrl_open(vctrl);
+	if (ret)
+		return ret;
+
+	/* register unmap IOMMU notifier*/
+	vctrl->vfio_unmap_notifier.notifier_call = nvme_mdev_unmap_notifier;
+	events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
+
+	ret = vfio_register_notifier(mdev_dev(vctrl->mdev),
+				     VFIO_IOMMU_NOTIFY, &events,
+				     &vctrl->vfio_unmap_notifier);
+
+	if (ret != 0) {
+		nvme_mdev_vctrl_release(vctrl);
+		return ret;
+	}
+
+	/* register map IOMMU notifier*/
+	vctrl->vfio_map_notifier.notifier_call = nvme_mdev_map_notifier;
+	events = VFIO_IOMMU_NOTIFY_DMA_MAP;
+
+	ret = vfio_register_notifier(mdev_dev(vctrl->mdev),
+				     VFIO_IOMMU_NOTIFY, &events,
+				     &vctrl->vfio_map_notifier);
+
+	if (ret != 0) {
+		vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+					 VFIO_IOMMU_NOTIFY,
+					 &vctrl->vfio_unmap_notifier);
+		nvme_mdev_vctrl_release(vctrl);
+		return ret;
+	}
+	return ret;
+}
+
+/* Called when new mediated device is closed (last close of the user) */
+static void nvme_mdev_ops_release(struct mdev_device *mdev)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+	int ret;
+
+	ret = vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+				       VFIO_IOMMU_NOTIFY,
+				       &vctrl->vfio_unmap_notifier);
+	WARN_ON(ret);
+
+	ret = vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+				       VFIO_IOMMU_NOTIFY,
+				       &vctrl->vfio_map_notifier);
+	WARN_ON(ret);
+
+	nvme_mdev_vctrl_release(vctrl);
+}
+
+/* Helper function for bar/pci config read/write access */
+static ssize_t nvme_mdev_access(struct nvme_mdev_vctrl *vctrl,
+				char *buf, size_t count,
+				loff_t pos, bool is_write)
+{
+	int index = OFFSET_TO_REGION(pos);
+	int ret = -EINVAL;
+	unsigned int offset;
+
+	if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].rw)
+		goto out;
+
+	offset = pos - REGION_TO_OFFSET(index);
+	if (offset + count > vctrl->regions[index].size)
+		goto out;
+
+	ret = vctrl->regions[index].rw(vctrl, offset, buf, count, is_write);
+out:
+	return ret;
+}
+
+/* Called when read() is done on the device */
+static ssize_t nvme_mdev_ops_read(struct mdev_device *mdev, char __user *buf,
+				  size_t count, loff_t *ppos)
+{
+	unsigned int done = 0;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	while (count) {
+		size_t filled;
+
+		if (count >= 4 && !(*ppos % 4)) {
+			u32 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		} else if (count >= 2 && !(*ppos % 2)) {
+			u16 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		} else {
+			u8 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		}
+
+		count -= filled;
+		done += filled;
+		*ppos += filled;
+		buf += filled;
+	}
+	return done;
+read_err:
+	return -EFAULT;
+}
+
+/* Called when write() is done on the device */
+static ssize_t nvme_mdev_ops_write(struct mdev_device *mdev,
+				   const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	unsigned int done = 0;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	while (count) {
+		size_t filled;
+
+		if (count >= 4 && !(*ppos % 4)) {
+			u32 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		} else if (count >= 2 && !(*ppos % 2)) {
+			u16 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		} else {
+			u8 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		}
+		count -= filled;
+		done += filled;
+		*ppos += filled;
+		buf += filled;
+	}
+	return done;
+write_err:
+	return -EFAULT;
+}
+
+/*Helper for IRQ number VFIO query */
+static int nvme_mdev_irq_counts(struct nvme_mdev_vctrl *vctrl,
+				unsigned int irq_type)
+{
+	switch (irq_type) {
+	case VFIO_PCI_INTX_IRQ_INDEX:
+		return 1;
+	case VFIO_PCI_MSIX_IRQ_INDEX:
+		return MAX_VIRTUAL_IRQS;
+	case VFIO_PCI_REQ_IRQ_INDEX:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/* VFIO VFIO_IRQ_SET_ACTION_TRIGGER implementation */
+static int nvme_mdev_ioctl_set_irqs_trigger(struct nvme_mdev_vctrl *vctrl,
+					    u32 flags,
+					    unsigned int irq_type,
+					    unsigned int start,
+					    unsigned int count,
+					    void *data)
+{
+	u32 data_type = flags & VFIO_IRQ_SET_DATA_TYPE_MASK;
+	u8 *bools = NULL;
+	unsigned int i;
+	int ret = -EINVAL;
+
+	/* Asked to disable the current interrupt mode*/
+	if (data_type == VFIO_IRQ_SET_DATA_NONE && count == 0) {
+		switch (irq_type) {
+		case VFIO_PCI_REQ_IRQ_INDEX:
+			nvme_mdev_irqs_set_unplug_trigger(vctrl, -1);
+			return 0;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			nvme_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_INTX);
+			return 0;
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			nvme_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_MSIX);
+			return 0;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (start + count > nvme_mdev_irq_counts(vctrl, irq_type))
+		return -EINVAL;
+
+	switch (data_type) {
+	case VFIO_IRQ_SET_DATA_BOOL:
+		bools = (u8 *)data;
+		/*fallthrough*/
+	case VFIO_IRQ_SET_DATA_NONE:
+		if (irq_type == VFIO_PCI_REQ_IRQ_INDEX)
+			return -EINVAL;
+
+		for (i = 0 ; i < count ; i++) {
+			int index = start + i;
+
+			if (!bools || bools[i])
+				nvme_mdev_irq_trigger(vctrl, index);
+		}
+		return 0;
+
+	case VFIO_IRQ_SET_DATA_EVENTFD:
+		switch (irq_type) {
+		case VFIO_PCI_REQ_IRQ_INDEX:
+			return nvme_mdev_irqs_set_unplug_trigger(vctrl,
+							*(int32_t *)data);
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			ret = nvme_mdev_irqs_enable(vctrl,
+						    NVME_MDEV_IMODE_INTX);
+			break;
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			ret = nvme_mdev_irqs_enable(vctrl,
+						    NVME_MDEV_IMODE_MSIX);
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (ret)
+			return ret;
+
+		return nvme_mdev_irqs_set_triggers(vctrl, start,
+						   count, (int32_t *)data);
+	default:
+		return -EINVAL;
+	}
+}
+
+/* VFIO_DEVICE_GET_INFO ioctl implementation */
+static int nvme_mdev_ioctl_get_info(struct nvme_mdev_vctrl *vctrl,
+				    void __user *arg)
+{
+	struct vfio_device_info info;
+	unsigned int minsz = offsetofend(struct vfio_device_info, num_irqs);
+
+	if (copy_from_user(&info, (void __user *)arg, minsz))
+		return -EFAULT;
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	info.flags = VFIO_DEVICE_FLAGS_PCI | VFIO_DEVICE_FLAGS_RESET;
+	info.num_regions = VFIO_PCI_NUM_REGIONS;
+	info.num_irqs = VFIO_PCI_NUM_IRQS;
+
+	if (copy_to_user(arg, &info, minsz))
+		return -EFAULT;
+	return 0;
+}
+
+/* VFIO_DEVICE_GET_REGION_INFO ioctl implementation*/
+static int nvme_mdev_ioctl_get_reg_info(struct nvme_mdev_vctrl *vctrl,
+					void __user *arg)
+{
+	struct nvme_mdev_io_region *region;
+	struct mdev_nvme_vfio_region_info *info;
+	unsigned long minsz, outsz, maxsz;
+	int ret = 0;
+
+	minsz = offsetofend(struct vfio_region_info, offset);
+	maxsz = sizeof(struct mdev_nvme_vfio_region_info) +
+				sizeof(struct vfio_region_sparse_mmap_area);
+
+	info = kzalloc(maxsz, GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	if (copy_from_user(info, arg, minsz)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	outsz = info->base.argsz;
+	if (outsz < minsz || outsz > maxsz) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (info->base.index >= VFIO_PCI_NUM_REGIONS) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	region = &vctrl->regions[info->base.index];
+	info->base.offset = REGION_TO_OFFSET(info->base.index);
+	info->base.argsz = maxsz;
+	info->base.size = region->size;
+
+	info->base.flags = VFIO_REGION_INFO_FLAG_READ |
+				VFIO_REGION_INFO_FLAG_WRITE;
+
+	if (region->mmap_ops) {
+		info->base.flags |= (VFIO_REGION_INFO_FLAG_MMAP |
+						VFIO_REGION_INFO_FLAG_CAPS);
+
+		info->base.cap_offset =
+			offsetof(struct mdev_nvme_vfio_region_info, mmap_cap);
+
+		info->mmap_cap.header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
+		info->mmap_cap.header.version = 1;
+		info->mmap_cap.header.next = 0;
+		info->mmap_cap.nr_areas = 1;
+		info->mmap_cap.areas[0].offset = region->mmap_area_start;
+		info->mmap_cap.areas[0].size = region->mmap_area_size;
+	}
+
+	if (copy_to_user(arg, info, outsz))
+		ret = -EFAULT;
+out:
+	kfree(info);
+	return ret;
+}
+
+/* VFIO_DEVICE_GET_IRQ_INFO ioctl implementation */
+static int nvme_mdev_ioctl_get_irq_info(struct nvme_mdev_vctrl *vctrl,
+					void __user *arg)
+{
+	struct vfio_irq_info info;
+	unsigned int minsz = offsetofend(struct vfio_irq_info, count);
+
+	if (copy_from_user(&info, arg, minsz))
+		return -EFAULT;
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	info.count = nvme_mdev_irq_counts(vctrl, info.index);
+	info.flags = VFIO_IRQ_INFO_EVENTFD;
+
+	if (info.index == VFIO_PCI_INTX_IRQ_INDEX)
+		info.flags |= VFIO_IRQ_INFO_MASKABLE | VFIO_IRQ_INFO_AUTOMASKED;
+
+	if (copy_to_user(arg, &info, minsz))
+		return -EFAULT;
+	return 0;
+}
+
+/* VFIO VFIO_DEVICE_SET_IRQS ioctl implementation */
+static int nvme_mdev_ioctl_set_irqs(struct nvme_mdev_vctrl *vctrl,
+				    void __user *arg)
+{
+	int ret, irqcount;
+	struct vfio_irq_set hdr;
+	u8 *data = NULL;
+	size_t data_size = 0;
+	unsigned long minsz = offsetofend(struct vfio_irq_set, count);
+
+	if (copy_from_user(&hdr, arg, minsz))
+		return -EFAULT;
+
+	irqcount = nvme_mdev_irq_counts(vctrl, hdr.index);
+	ret = vfio_set_irqs_validate_and_prepare(&hdr,
+						 irqcount,
+						 VFIO_PCI_NUM_IRQS,
+						 &data_size);
+	if (ret)
+		return ret;
+
+	if (data_size) {
+		data = memdup_user((arg + minsz), data_size);
+		if (IS_ERR(data))
+			return PTR_ERR(data);
+	}
+
+	ret = -ENOTTY;
+	switch (hdr.index) {
+	case VFIO_PCI_INTX_IRQ_INDEX:
+	case VFIO_PCI_MSIX_IRQ_INDEX:
+	case VFIO_PCI_REQ_IRQ_INDEX:
+		switch (hdr.flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+		case VFIO_IRQ_SET_ACTION_MASK:
+		case VFIO_IRQ_SET_ACTION_UNMASK:
+			// pretend to support this (even with eventfd)
+			ret = hdr.index == VFIO_PCI_INTX_IRQ_INDEX ?
+					0 : -EINVAL;
+			break;
+		case VFIO_IRQ_SET_ACTION_TRIGGER:
+			ret = nvme_mdev_ioctl_set_irqs_trigger(vctrl, hdr.flags,
+							       hdr.index,
+							       hdr.start,
+							       hdr.count,
+							       data);
+			break;
+		}
+		break;
+	}
+
+	kfree(data);
+	return ret;
+}
+
+/* ioctl() implementation */
+static long nvme_mdev_ops_ioctl(struct mdev_device *mdev, unsigned int cmd,
+				unsigned long arg)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	switch (cmd) {
+	case VFIO_DEVICE_GET_INFO:
+		return nvme_mdev_ioctl_get_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_GET_REGION_INFO:
+		return nvme_mdev_ioctl_get_reg_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_GET_IRQ_INFO:
+		return nvme_mdev_ioctl_get_irq_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_SET_IRQS:
+		return nvme_mdev_ioctl_set_irqs(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_RESET:
+		nvme_mdev_vctrl_reset(vctrl);
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
+
+/* mmap() implementation (doorbell area) */
+static int nvme_mdev_ops_mmap(struct mdev_device *mdev,
+			      struct vm_area_struct *vma)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+	int index = OFFSET_TO_REGION((u64)vma->vm_pgoff << PAGE_SHIFT);
+	unsigned long size, start;
+
+	if (!vctrl)
+		return -EFAULT;
+
+	if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].mmap_ops)
+		return -EINVAL;
+
+	if (vma->vm_end < vma->vm_start)
+		return -EINVAL;
+
+	size = vma->vm_end - vma->vm_start;
+	start = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (start < vctrl->regions[index].mmap_area_start)
+		return -EINVAL;
+	if (size > vctrl->regions[index].mmap_area_size)
+		return -EINVAL;
+
+	if ((vma->vm_flags & VM_SHARED) == 0)
+		return -EINVAL;
+
+	vma->vm_ops = vctrl->regions[index].mmap_ops;
+	vma->vm_private_data = vctrl;
+	return 0;
+}
+
+/* Request removal of the device*/
+static void nvme_mdev_ops_request(struct mdev_device *mdev, unsigned int count)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+
+	if (vctrl)
+		nvme_mdev_irq_raise_unplug_event(vctrl, count);
+}
+
+/* Adding a new namespace given host NS id and partition ID (e/g. n1p2 or n1) */
+static ssize_t add_namespace_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+	int ret;
+	unsigned long partno = 0, nsid;
+	char *buf_copy, *token, *tmp;
+
+	if (!vctrl)
+		return -ENODEV;
+
+	buf_copy = kstrdup(buf, GFP_KERNEL);
+	if (!buf_copy)
+		return -ENOMEM;
+
+	tmp = buf_copy;
+	if (tmp[0] != 'n') {
+		ret = -EINVAL;
+		goto out;
+	}
+	tmp++;
+
+	// read namespace ID (mandatory)
+	token = strsep(&tmp, "p");
+	if (!token) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = kstrtoul(token, 10, &nsid);
+	if (ret)
+		goto out;
+
+	// read partition ID (optional)
+	if (tmp) {
+		ret = kstrtoul(tmp, 10, &partno);
+		if (ret)
+			goto out;
+	}
+
+	// create the user namespace
+	ret = nvme_mdev_vns_open(vctrl, nsid, partno);
+	if (ret)
+		goto out;
+	ret = count;
+out:
+	kfree(buf_copy);
+	return ret;
+}
+static DEVICE_ATTR_WO(add_namespace);
+
+/* Remove a user namespace */
+static ssize_t remove_namespace_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	unsigned long user_nsid;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	ret = kstrtoul(buf, 10, &user_nsid);
+	if (ret)
+		return ret;
+
+	ret =  nvme_mdev_vns_destroy(vctrl, user_nsid);
+	if (ret)
+		return ret;
+	return count;
+}
+static DEVICE_ATTR_WO(remove_namespace);
+
+/* Show list of user namespaces */
+static ssize_t namespaces_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return nvme_mdev_vns_print_description(vctrl, buf, PAGE_SIZE - 1);
+}
+static DEVICE_ATTR_RO(namespaces);
+
+/* change the cpu binding of the IO threads*/
+static ssize_t iothread_cpu_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+	nvme_mdev_vctrl_bind_iothread(vctrl, val);
+	return count;
+}
+
+/* change the cpu binding of the IO threads*/
+static ssize_t
+iothread_cpu_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return sprintf(buf, "%d\n", vctrl->iothread_cpu);
+}
+static DEVICE_ATTR_RW(iothread_cpu);
+
+/* change the cpu binding of the IO threads*/
+static ssize_t shadow_doorbell_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	bool val;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	ret = kstrtobool(buf, &val);
+	if (ret)
+		return ret;
+	ret = nvme_mdev_vctrl_set_shadow_doorbell_supported(vctrl, val);
+	if (ret)
+		return ret;
+	return count;
+}
+
+/* change the cpu binding of the IO threads*/
+static ssize_t shadow_doorbell_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	return sprintf(buf, "%d\n", vctrl->mmio.shadow_db_supported ? 1 : 0);
+}
+static DEVICE_ATTR_RW(shadow_doorbell);
+
+static struct attribute *nvme_mdev_dev_ns_atttributes[] = {
+	&dev_attr_add_namespace.attr,
+	&dev_attr_remove_namespace.attr,
+	&dev_attr_namespaces.attr,
+	NULL
+};
+
+static struct attribute *nvme_mdev_dev_settings_atttributes[] = {
+	&dev_attr_iothread_cpu.attr,
+	&dev_attr_shadow_doorbell.attr,
+	NULL
+};
+
+static const struct attribute_group nvme_mdev_ns_attr_group = {
+	.name = "namespaces",
+	.attrs = nvme_mdev_dev_ns_atttributes,
+};
+
+static const struct attribute_group nvme_mdev_setting_attr_group = {
+	.name = "settings",
+	.attrs = nvme_mdev_dev_settings_atttributes,
+};
+
+static const struct attribute_group *nvme_mdev_dev_attributte_groups[] = {
+	&nvme_mdev_ns_attr_group,
+	&nvme_mdev_setting_attr_group,
+	NULL,
+};
+
+struct mdev_parent_ops mdev_fops = {
+	.owner			= THIS_MODULE,
+	.create			= nvme_mdev_ops_create,
+	.remove			= nvme_mdev_ops_remove,
+	.open			= nvme_mdev_ops_open,
+	.release		= nvme_mdev_ops_release,
+	.read			= nvme_mdev_ops_read,
+	.write			= nvme_mdev_ops_write,
+	.mmap			= nvme_mdev_ops_mmap,
+	.ioctl			= nvme_mdev_ops_ioctl,
+	.request		= nvme_mdev_ops_request,
+	.mdev_attr_groups	= nvme_mdev_dev_attributte_groups,
+	.dev_attr_groups	= NULL,
+};
+
diff --git a/drivers/nvme/mdev/io.c b/drivers/nvme/mdev/io.c
new file mode 100644
index 000000000000..a731196d0365
--- /dev/null
+++ b/drivers/nvme/mdev/io.c
@@ -0,0 +1,563 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe IO command translation and polling IO thread
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include <linux/timekeeping.h>
+#include <linux/ktime.h>
+#include "priv.h"
+
+struct io_ctx {
+	struct nvme_mdev_hctrl *hctrl;
+	struct nvme_mdev_vctrl *vctrl;
+
+	const struct nvme_command *in;
+	struct nvme_command out;
+	struct nvme_mdev_vns *ns;
+	struct nvme_ext_data_iter udatait;
+	struct nvme_ext_data_iter *kdatait;
+
+	ktime_t last_io_t;
+	ktime_t last_admin_poll_time;
+	unsigned int idle_timeout_ms;
+	unsigned int admin_poll_rate_ms;
+	unsigned int arb_burst;
+};
+
+/* Handle read/write command.*/
+static int nvme_mdev_io_translate_rw(struct io_ctx *ctx)
+{
+	int ret;
+	const struct nvme_rw_command *in = &ctx->in->rw;
+
+	u64 slba = le64_to_cpu(in->slba);
+	u64 length = le16_to_cpu(in->length) + 1;
+	u16 control = le16_to_cpu(in->control);
+
+	_DBG(ctx->vctrl, "IOQ: READ/WRITE\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW14_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16, 0b1100000000111100))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (in->opcode == nvme_cmd_write && ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	if (!check_range(slba, length, ctx->ns->ns_size))
+		return DNR(NVME_SC_LBA_RANGE);
+
+	ctx->out.rw.slba = cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	ctx->out.rw.length = in->length;
+
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait, &in->dptr,
+					    length << ctx->ns->blksize_shift);
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	ctx->kdatait = &ctx->udatait;
+	if (control & ~(NVME_RW_LR | NVME_RW_FUA))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->out.rw.control = in->control;
+	return -1;
+}
+
+/*Handle flush command */
+static int nvme_mdev_io_translate_flush(struct io_ctx *ctx)
+{
+	ctx->kdatait = NULL;
+
+	_DBG(ctx->vctrl, "IOQ: FLUSH\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	return -1;
+}
+
+/* Handle write zeros command */
+static int nvme_mdev_io_translate_write_zeros(struct io_ctx *ctx)
+{
+	const struct nvme_write_zeroes_cmd *in = &ctx->in->write_zeroes;
+	u64 slba = le64_to_cpu(in->slba);
+	u64 length = le16_to_cpu(in->length) + 1;
+	u16 control = le16_to_cpu(in->control);
+
+	_DBG(ctx->vctrl, "IOQ: WRITE_ZEROS\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW13_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!nvme_mdev_hctrl_hq_check_op(ctx->hctrl, in->opcode))
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+	ctx->kdatait = NULL;
+
+	if (!check_range(slba, length, ctx->ns->ns_size))
+		return DNR(NVME_SC_LBA_RANGE);
+
+	ctx->out.write_zeroes.slba =
+		cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	ctx->out.write_zeroes.length = in->length;
+
+	if (control & ~(NVME_RW_LR | NVME_RW_FUA | NVME_WZ_DEAC))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->out.write_zeroes.control = in->control;
+	return -1;
+}
+
+/* Handle dataset management command */
+static int nvme_mdev_io_translate_dsm(struct io_ctx *ctx)
+{
+	unsigned int size, i, nr;
+	int ret;
+	const struct nvme_dsm_cmd *in = &ctx->in->dsm;
+	struct nvme_dsm_range *data_ptr;
+
+	_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (le32_to_cpu(in->nr) & 0xFFFFFF00)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!nvme_mdev_hctrl_hq_check_op(ctx->hctrl, in->opcode))
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	nr = le32_to_cpu(in->nr) + 1;
+	size = nr * sizeof(struct nvme_dsm_range);
+
+	ctx->out.dsm.nr = in->nr;
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait, &in->dptr, size);
+	if (ret)
+		goto error;
+
+	ctx->kdatait = nvme_mdev_kdata_iter_alloc(&ctx->vctrl->viommu, size);
+	if (!ctx->kdatait)
+		return NVME_SC_INTERNAL;
+
+	_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT: NR=%d\n", nr);
+
+	ret = nvme_mdev_read_from_udata(ctx->kdatait->kmem.data, &ctx->udatait,
+					size);
+	if (ret)
+		goto error2;
+
+	data_ptr = (struct nvme_dsm_range *)ctx->kdatait->kmem.data;
+
+	for (i = 0 ; i < nr; i++) {
+		u64 slba = le64_to_cpu(data_ptr[i].slba);
+		/* looks like not zero based value*/
+		u32 nlb = le32_to_cpu(data_ptr[i].nlb);
+
+		if (!check_range(slba, nlb, ctx->ns->ns_size))
+			goto error2;
+
+		_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT: RANGE 0x%llx-0x%x\n",
+		     slba, nlb);
+
+		data_ptr[i].slba = cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	}
+
+	ctx->out.dsm.attributes = in->attributes;
+	return -1;
+error2:
+	ctx->kdatait->release(ctx->kdatait);
+error:
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Process one new command in the io queue*/
+static int nvme_mdev_io_translate_cmd(struct io_ctx *ctx)
+{
+	memset(&ctx->out, 0, sizeof(ctx->out));
+	/* translate opcode */
+	ctx->out.common.opcode = ctx->in->common.opcode;
+
+	/* check flags */
+	if (ctx->in->common.flags != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* namespace*/
+	ctx->ns = nvme_mdev_vns_from_vnsid(ctx->vctrl,
+					   le32_to_cpu(ctx->in->rw.nsid));
+	if (!ctx->ns) {
+		_DBG(ctx->vctrl, "IOQ: invalid NSID\n");
+		return DNR(NVME_SC_INVALID_NS);
+	}
+
+	if (!ctx->ns->readonly && bdev_read_only(ctx->ns->host_part))
+		ctx->ns->readonly = true;
+
+	ctx->out.common.nsid = cpu_to_le32(ctx->ns->host_nsid);
+
+	switch (ctx->in->common.opcode) {
+	case nvme_cmd_flush:
+		return nvme_mdev_io_translate_flush(ctx);
+	case nvme_cmd_read:
+		return nvme_mdev_io_translate_rw(ctx);
+	case nvme_cmd_write:
+		return nvme_mdev_io_translate_rw(ctx);
+	case nvme_cmd_write_zeroes:
+		return nvme_mdev_io_translate_write_zeros(ctx);
+	case nvme_cmd_dsm:
+		return nvme_mdev_io_translate_dsm(ctx);
+	default:
+		return DNR(NVME_SC_INVALID_OPCODE);
+	}
+}
+
+static bool nvme_mdev_io_process_sq(struct io_ctx *ctx, u16 sqid)
+{
+	struct nvme_vsq *vsq = &ctx->vctrl->vsqs[sqid];
+	u16 ucid;
+	int ret;
+
+	/* If host queue is full, we can't process a command
+	 * as a command will likely result in passthrough
+	 */
+	if (!nvme_mdev_hctrl_hq_can_submit(ctx->hctrl, vsq->hsq))
+		return false;
+
+	/* read the command */
+	ctx->in = nvme_mdev_vsq_get_cmd(ctx->vctrl, vsq);
+	if (!ctx->in)
+		return false;
+	ucid = le16_to_cpu(ctx->in->common.command_id);
+
+	/* translate the command */
+	ret = nvme_mdev_io_translate_cmd(ctx);
+	if (ret != -1) {
+		_DBG(ctx->vctrl,
+		     "IOQ: QID %d CID %d FAILED: status 0x%x (translate)\n",
+		     sqid, ucid, ret);
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, sqid, ucid, ret);
+		return true;
+	}
+
+	/*passthrough*/
+	ret = nvme_mdev_hctrl_hq_submit(ctx->hctrl,
+					vsq->hsq,
+					(((u32)vsq->qid) << 16) | ((u32)ucid),
+					&ctx->out,
+					ctx->kdatait);
+	if (ret) {
+		ret = nvme_mdev_translate_error(ret);
+
+		_DBG(ctx->vctrl,
+		     "IOQ: QID %d CID %d FAILED: status 0x%x (host submit)\n",
+		     sqid, ucid, ret);
+
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, sqid, ucid, ret);
+	}
+	return true;
+}
+
+/* process host replies to the passed through commands */
+static int nvme_mdev_io_process_hwq(struct io_ctx *ctx, u16 hwq)
+{
+	int n, i;
+	struct nvme_ext_cmd_result res[16];
+
+	/* process the completions from the hardware */
+	n = nvme_mdev_hctrl_hq_poll(ctx->hctrl, hwq, res, 16);
+	if (n == -1)
+		return -1;
+
+	for (i = 0; i < n; i++) {
+		u16 qid = res[i].tag >> 16;
+		u16 cid = res[i].tag & 0xFFFF;
+		u16 status = res[i].status;
+
+		if (status != 0)
+			_DBG(ctx->vctrl,
+			     "IOQ: QID %d CID %d FAILED: status 0x%x (host response)\n",
+			     qid, cid, status);
+
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, qid, cid, status);
+	}
+	return n;
+}
+
+/* Check if we need to read a command from the admin queue */
+static bool nvme_mdev_adm_needs_processing(struct io_ctx *ctx)
+{
+	if (!timeout(ctx->last_admin_poll_time,
+		     ctx->vctrl->now, ctx->admin_poll_rate_ms))
+		return false;
+
+	if (nvme_mdev_vsq_has_data(ctx->vctrl, &ctx->vctrl->vsqs[0]))
+		return true;
+
+	ctx->last_admin_poll_time = ctx->vctrl->now;
+	return false;
+}
+
+/* do polling till one of events stops it */
+static void nvme_mdev_io_maintask(struct io_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	u16 i, cqid, sqid, hsqcnt;
+	u16 hsqs[MAX_HOST_QUEUES];
+	bool idle = false;
+
+	hsqcnt = nvme_mdev_vctrl_hqs_list(vctrl, hsqs);
+	ctx->arb_burst = 1 << ctx->vctrl->arb_burst_shift;
+
+	/* can't stop polling when shadow db not enabled */
+	ctx->idle_timeout_ms = vctrl->mmio.shadow_db_en ? poll_timeout_ms : 0;
+	ctx->admin_poll_rate_ms = admin_poll_rate_ms;
+
+	vctrl->now = ktime_get();
+	ctx->last_admin_poll_time = vctrl->now;
+	ctx->last_io_t = vctrl->now;
+
+	/* main loop */
+	while (!kthread_should_park()) {
+		vctrl->now = ktime_get();
+
+		/* check if we have to exit to support admin polling */
+		if (!vctrl->mmio.shadow_db_supported)
+			if (nvme_mdev_adm_needs_processing(ctx))
+				break;
+
+		/* process the submission queues*/
+		sqid = 1;
+		for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+			for (i = 0 ; i < ctx->arb_burst ; i++)
+				if (!nvme_mdev_io_process_sq(ctx, sqid))
+					break;
+
+		/* process the completions from the guest*/
+		cqid = 1;
+		for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+			nvme_mdev_vcq_process(vctrl, cqid, true);
+
+		/* process the completions from the hardware*/
+		for (i = 0 ; i < hsqcnt ; i++)
+			if (nvme_mdev_io_process_hwq(ctx, hsqs[i]) > 0)
+				ctx->last_io_t = vctrl->now;
+
+		/* Check if we need to stop polling*/
+		if (ctx->idle_timeout_ms) {
+			if (timeout(ctx->last_io_t,
+				    vctrl->now, ctx->idle_timeout_ms)) {
+				idle = true;
+				break;
+			}
+		}
+		cond_resched();
+	}
+
+	/* Drain the host IO */
+	for (;;) {
+		bool pending_io = false;
+
+		vctrl->now = ktime_get_coarse_boottime();
+
+		if (nvme_mdev_vctrl_is_dead(vctrl) || ctx->hctrl->removing) {
+			idle = false;
+			break;
+		}
+
+		for (i = 0; i < hsqcnt; i++) {
+			int n = nvme_mdev_io_process_hwq(ctx, hsqs[i]);
+
+			if (n != -1)
+				pending_io = true;
+			if (n > 0)
+				ctx->last_io_t = vctrl->now;
+		}
+
+		if (!pending_io)
+			break;
+
+		cond_resched();
+
+		if (!timeout(ctx->last_io_t, vctrl->now, io_timeout_ms))
+			continue;
+
+		_WARN(ctx->vctrl, "IO: skipping flush - host IO timeout\n");
+		idle = false;
+		break;
+	}
+
+	/* Drain all the pending completion interrupts to the guest*/
+	cqid = 1;
+	for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		if (nvme_mdev_vcq_flush(vctrl, cqid))
+			idle = false;
+
+	/* Park IO thread if IO is truly idle*/
+	if (idle) {
+		/* don't bother going idle if someone holds the vctrl
+		 * lock. It might try to park us, and thus
+		 * cause a deadlock
+		 */
+		if (!mutex_trylock(&vctrl->lock))
+			return;
+
+		sqid = 1;
+		for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+			if (!nvme_mdev_vsq_suspend_io(vctrl, sqid)) {
+				idle = false;
+				break;
+			}
+
+		if (idle) {
+			_DBG(ctx->vctrl, "IO: self-parking\n");
+			vctrl->io_idle = true;
+			nvme_mdev_io_pause(vctrl);
+		}
+
+		mutex_unlock(&vctrl->lock);
+	}
+
+	/* Admin poll for cases when shadow doorbell is not supported */
+	if (!vctrl->mmio.shadow_db_supported) {
+		if (mutex_trylock(&vctrl->lock)) {
+			nvme_mdev_vcq_process(vctrl, 0, false);
+			nvme_mdev_adm_process_sq(ctx->vctrl);
+			ctx->last_admin_poll_time = vctrl->now;
+			mutex_unlock(&ctx->vctrl->lock);
+		}
+	}
+}
+
+/* the main IO thread */
+static int nvme_mdev_io_polling_thread(void *data)
+{
+	struct io_ctx ctx;
+
+	if (kthread_should_stop())
+		return 0;
+
+	memset(&ctx, 0, sizeof(struct io_ctx));
+	ctx.vctrl = (struct nvme_mdev_vctrl *)data;
+	ctx.hctrl = ctx.vctrl->hctrl;
+	nvme_mdev_udata_iter_setup(&ctx.vctrl->viommu, &ctx.udatait);
+
+	_DBG(ctx.vctrl, "IO: iothread started\n");
+
+	for (;;) {
+		if (kthread_should_park()) {
+			_DBG(ctx.vctrl, "IO: iothread parked\n");
+			kthread_parkme();
+		}
+
+		if (kthread_should_stop())
+			break;
+
+		nvme_mdev_io_maintask(&ctx);
+	}
+
+	_DBG(ctx.vctrl, "IO: iothread stopped\n");
+	return 0;
+}
+
+/* Kick the IO thread into running state*/
+void nvme_mdev_io_resume(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!vctrl->iothread || !vctrl->iothread_parked)
+		return;
+	if (vctrl->io_idle || vctrl->vctrl_paused)
+		return;
+
+	vctrl->iothread_parked = false;
+	/* has memory barrier*/
+	kthread_unpark(vctrl->iothread);
+}
+
+/* Pause the IO thread */
+void nvme_mdev_io_pause(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!vctrl->iothread || vctrl->iothread_parked)
+		return;
+
+	vctrl->iothread_parked = true;
+	kthread_park(vctrl->iothread);
+}
+
+/* setup the main IO thread */
+int nvme_mdev_io_create(struct nvme_mdev_vctrl *vctrl, unsigned int cpu)
+{
+	/*TODOLATER: IO: Better thread name*/
+	char name[TASK_COMM_LEN];
+
+	_DBG(vctrl, "IO: creating the polling iothread\n");
+
+	if (WARN_ON(vctrl->iothread))
+		return -EINVAL;
+
+	snprintf(name, sizeof(name), "nvme%d_poll_io", vctrl->hctrl->id);
+
+	vctrl->iothread_cpu = cpu;
+	vctrl->iothread_parked = false;
+	vctrl->io_idle = true;
+
+	vctrl->iothread = kthread_create_on_node(nvme_mdev_io_polling_thread,
+						 vctrl,
+						 vctrl->hctrl->node,
+						 name);
+	if (IS_ERR(vctrl->iothread)) {
+		vctrl->iothread = NULL;
+		return PTR_ERR(vctrl->iothread);
+	}
+
+	kthread_bind(vctrl->iothread, cpu);
+
+	if (vctrl->io_idle) {
+		vctrl->iothread_parked = true;
+		kthread_park(vctrl->iothread);
+		return 0;
+	}
+
+	wake_up_process(vctrl->iothread);
+	return 0;
+}
+
+/* End the  main IO thread */
+void nvme_mdev_io_free(struct nvme_mdev_vctrl *vctrl)
+{
+	int ret;
+
+	_DBG(vctrl, "IO: destroying the polling iothread\n");
+
+	lockdep_assert_held(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+	ret = kthread_stop(vctrl->iothread);
+	WARN_ON(ret);
+	vctrl->iothread = NULL;
+}
+
+void nvme_mdev_assert_io_not_running(struct nvme_mdev_vctrl *vctrl)
+{
+	if (WARN_ON(vctrl->iothread && !vctrl->iothread_parked))
+		nvme_mdev_io_pause(vctrl);
+}
diff --git a/drivers/nvme/mdev/irq.c b/drivers/nvme/mdev/irq.c
new file mode 100644
index 000000000000..5809cdb4d84c
--- /dev/null
+++ b/drivers/nvme/mdev/irq.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller IRQ implementation (MSIx and INTx)
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* Setup the interrupt subsystem */
+void nvme_mdev_irqs_setup(struct nvme_mdev_vctrl *vctrl)
+{
+	vctrl->irqs.mode = NVME_MDEV_IMODE_NONE;
+	vctrl->irqs.irq_coalesc_max = 1;
+}
+
+/* Enable INTx or MSIx interrupts  */
+static int __nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+				   enum nvme_mdev_irq_mode mode)
+{
+	if (vctrl->irqs.mode == mode)
+		return 0;
+	if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE)
+		return -EBUSY;
+
+	if (mode == NVME_MDEV_IMODE_INTX)
+		_DBG(vctrl, "IRQ: enable INTx interrupts\n");
+	else if (mode == NVME_MDEV_IMODE_MSIX)
+		_DBG(vctrl, "IRQ: enable MSIX interrupts\n");
+	else
+		WARN_ON(1);
+
+	nvme_mdev_io_pause(vctrl);
+	vctrl->irqs.mode = mode;
+	nvme_mdev_io_resume(vctrl);
+	return 0;
+}
+
+int nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_mdev_irq_mode mode)
+{
+	int retval = 0;
+
+	mutex_lock(&vctrl->lock);
+	retval = __nvme_mdev_irqs_enable(vctrl, mode);
+	mutex_unlock(&vctrl->lock);
+	return retval;
+}
+
+/* Disable INTx or MSIx interrupts  */
+static void __nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+				     enum nvme_mdev_irq_mode mode)
+{
+	unsigned int i;
+
+	if (vctrl->irqs.mode == NVME_MDEV_IMODE_NONE)
+		return;
+	if (vctrl->irqs.mode != mode)
+		return;
+
+	if (vctrl->irqs.mode == NVME_MDEV_IMODE_INTX)
+		_DBG(vctrl, "IRQ: disable INTx interrupts\n");
+	else if (vctrl->irqs.mode == NVME_MDEV_IMODE_MSIX)
+		_DBG(vctrl, "IRQ: disable MSIX interrupts\n");
+	else
+		WARN_ON(1);
+
+	nvme_mdev_io_pause(vctrl);
+
+	for (i = 0; i < MAX_VIRTUAL_IRQS; i++) {
+		struct nvme_mdev_user_irq *vec = &vctrl->irqs.vecs[i];
+
+		if (vec->trigger) {
+			eventfd_ctx_put(vec->trigger);
+			vec->trigger = NULL;
+		}
+		vec->irq_pending_cnt = 0;
+		vec->irq_time = 0;
+	}
+	vctrl->irqs.mode = NVME_MDEV_IMODE_NONE;
+	nvme_mdev_io_resume(vctrl);
+}
+
+void nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+			    enum nvme_mdev_irq_mode mode)
+{
+	mutex_lock(&vctrl->lock);
+	__nvme_mdev_irqs_disable(vctrl, mode);
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Set eventfd triggers for INTx or MSIx interrupts */
+int nvme_mdev_irqs_set_triggers(struct nvme_mdev_vctrl *vctrl,
+				int start, int count, int32_t *fds)
+{
+	unsigned int i;
+
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+
+	for (i = 0; i < count; i++) {
+		int irqindex = start + i;
+		struct eventfd_ctx *trigger;
+		struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[irqindex];
+
+		if (irq->trigger) {
+			eventfd_ctx_put(irq->trigger);
+			irq->trigger = NULL;
+		}
+
+		if (fds[i] < 0)
+			continue;
+
+		trigger = eventfd_ctx_fdget(fds[i]);
+		if (IS_ERR(trigger))
+			return PTR_ERR(trigger);
+
+		irq->trigger = trigger;
+	}
+	nvme_mdev_io_resume(vctrl);
+	mutex_unlock(&vctrl->lock);
+	return 0;
+}
+
+/* Set eventfd trigger for unplug interrupt */
+static int __nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+					       int32_t fd)
+{
+	struct eventfd_ctx *trigger;
+
+	if (vctrl->irqs.request_trigger) {
+		_DBG(vctrl, "IRQ: clear hotplug trigger\n");
+		eventfd_ctx_put(vctrl->irqs.request_trigger);
+		vctrl->irqs.request_trigger = NULL;
+	}
+
+	if (fd < 0)
+		return 0;
+
+	_DBG(vctrl, "IRQ: set hotplug trigger\n");
+
+	trigger = eventfd_ctx_fdget(fd);
+	if (IS_ERR(trigger))
+		return PTR_ERR(trigger);
+
+	vctrl->irqs.request_trigger = trigger;
+	return 0;
+}
+
+int nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+				      int32_t fd)
+{
+	int retval;
+
+	mutex_lock(&vctrl->lock);
+	retval = __nvme_mdev_irqs_set_unplug_trigger(vctrl, fd);
+	mutex_unlock(&vctrl->lock);
+	return retval;
+}
+
+/* Reset the interrupts subsystem */
+void nvme_mdev_irqs_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	int i;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE)
+		__nvme_mdev_irqs_disable(vctrl, vctrl->irqs.mode);
+
+	__nvme_mdev_irqs_set_unplug_trigger(vctrl, -1);
+
+	for (i = 0; i < MAX_VIRTUAL_IRQS; i++) {
+		struct nvme_mdev_user_irq *vec = &vctrl->irqs.vecs[i];
+
+		vec->irq_coalesc_en = false;
+		vec->irq_pending_cnt = 0;
+		vec->irq_time = 0;
+	}
+
+	vctrl->irqs.irq_coalesc_time_us = 0;
+}
+
+/* Check if interrupt can be coalesced */
+static bool nvme_mdev_irq_coalesce(struct nvme_mdev_vctrl *vctrl,
+				   struct nvme_mdev_user_irq *irq)
+{
+	s64 delta;
+
+	if (!irq->irq_coalesc_en)
+		return false;
+
+	if (irq->irq_pending_cnt >= vctrl->irqs.irq_coalesc_max)
+		return false;
+
+	delta = ktime_us_delta(vctrl->now, irq->irq_time);
+	return (delta < vctrl->irqs.irq_coalesc_time_us);
+}
+
+void nvme_mdev_irq_raise_unplug_event(struct nvme_mdev_vctrl *vctrl,
+				      unsigned int count)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->irqs.request_trigger) {
+		if (!(count % 10))
+			dev_notice_ratelimited(mdev_dev(vctrl->mdev),
+					       "Relaying device request to user (#%u)\n",
+					       count);
+
+		eventfd_signal(vctrl->irqs.request_trigger, 1);
+
+	} else if (count == 0) {
+		dev_notice(mdev_dev(vctrl->mdev),
+			   "No device request channel registered, blocked until released by user\n");
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Raise an interrupt */
+void nvme_mdev_irq_raise(struct nvme_mdev_vctrl *vctrl, unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	irq->irq_pending_cnt++;
+}
+
+/* Unraise an interrupt */
+void nvme_mdev_irq_clear(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	irq->irq_time = vctrl->now;
+	irq->irq_pending_cnt = 0;
+}
+
+/* Directly trigger an interrupt without affecting irq coalescing settings */
+void nvme_mdev_irq_trigger(struct nvme_mdev_vctrl *vctrl,
+			   unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	if (irq->trigger)
+		eventfd_signal(irq->trigger, 1);
+}
+
+/* Trigger previously raised interrupt */
+void nvme_mdev_irq_cond_trigger(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	if (irq->irq_pending_cnt == 0)
+		return;
+
+	if (!nvme_mdev_irq_coalesce(vctrl, irq)) {
+		nvme_mdev_irq_trigger(vctrl, index);
+		nvme_mdev_irq_clear(vctrl, index);
+	}
+}
diff --git a/drivers/nvme/mdev/mdev.h b/drivers/nvme/mdev/mdev.h
new file mode 100644
index 000000000000..d139e090520e
--- /dev/null
+++ b/drivers/nvme/mdev/mdev.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * NVME VFIO mediated driver
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#ifndef _MDEV_NVME_MDEV_H
+#define _MDEV_NVME_MDEV_H
+
+#include <linux/kernel.h>
+#include <linux/byteorder/generic.h>
+#include <linux/nvme.h>
+
+struct page_map {
+	void *kmap;
+	struct page *page;
+	dma_addr_t iova;
+};
+
+struct user_prplist {
+	/* used by user data iterator*/
+	struct page_map page;
+	unsigned int index;	/* index of current entry */
+};
+
+struct kernel_data {
+	/* used by kernel data iterator*/
+	void		*data;
+	unsigned int	size;
+	dma_addr_t	dma_addr;
+};
+
+struct nvme_ext_data_iter {
+	/* private */
+	struct nvme_mdev_viommu *viommu;
+	union {
+		const union nvme_data_ptr *dptr;
+		struct user_prplist uprp;
+		struct kernel_data kmem;
+	};
+
+	/* user interface */
+	u64		count;	/* number of data pages, yet to be covered */
+
+	phys_addr_t	physical; /* iterator physical address value*/
+	dma_addr_t	host_iova; /* iterator dma address value*/
+
+	/* moves iterator to the next item */
+	int (*next)(struct nvme_ext_data_iter *data_iter);
+
+	/* if != NULL, user should call this when it done with data
+	 * pointed by the iterator
+	 */
+	void (*release)(struct nvme_ext_data_iter *data_iter);
+};
+#endif
diff --git a/drivers/nvme/mdev/mmio.c b/drivers/nvme/mdev/mmio.c
new file mode 100644
index 000000000000..cf03c1f22f4c
--- /dev/null
+++ b/drivers/nvme/mdev/mmio.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller MMIO implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include "priv.h"
+
+#define DB_AREA_SIZE (MAX_VIRTUAL_QUEUES * 2 * (4 << DB_STRIDE_SHIFT))
+#define DB_MASK ((4 << DB_STRIDE_SHIFT) - 1)
+#define MMIO_BAR_SIZE __roundup_pow_of_two(NVME_REG_DBS + DB_AREA_SIZE)
+
+/* Put the controller into fatal error state. Only way out is reset */
+static void nvme_mdev_mmio_fatal_error(struct nvme_mdev_vctrl *vctrl)
+{
+	if (vctrl->mmio.csts & NVME_CSTS_CFS)
+		return;
+
+	vctrl->mmio.csts |= NVME_CSTS_CFS;
+	nvme_mdev_io_pause(vctrl);
+
+	if (vctrl->mmio.csts & NVME_CSTS_RDY)
+		nvme_mdev_vctrl_disable(vctrl);
+}
+
+/* This sends an generic error notification to the user */
+static void nvme_mdev_mmio_error(struct nvme_mdev_vctrl *vctrl,
+				 enum nvme_async_event info)
+{
+	nvme_mdev_event_send(vctrl, NVME_AER_TYPE_ERROR, info);
+}
+
+/* This is memory fault handler for the mmap area of the doorbells*/
+static vm_fault_t nvme_mdev_mmio_dbs_mmap_fault(struct vm_fault *vmf)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct nvme_mdev_vctrl *vctrl = vma->vm_private_data;
+
+	/* DB area is just one page, starting at offset 4096 of the mmio*/
+	if (WARN_ON(vmf->pgoff != 1))
+		return VM_FAULT_SIGBUS;
+
+	get_page(vctrl->mmio.dbs_page);
+	vmf->page = vctrl->mmio.dbs_page;
+	return 0;
+}
+
+static const struct vm_operations_struct nvme_mdev_mmio_dbs_vm_ops = {
+	.fault = nvme_mdev_mmio_dbs_mmap_fault,
+};
+
+/* check that user db write is valid and send an error if not*/
+bool nvme_mdev_mmio_db_check(struct nvme_mdev_vctrl *vctrl,
+			     u16 qid, u16 size, u16 db)
+{
+	if (get_current() != vctrl->iothread)
+		lockdep_assert_held(&vctrl->lock);
+
+	if (db < size)
+		return true;
+	if (qid == 0) {
+		_DBG(vctrl, "MMIO: invalid admin DB write - fatal error\n");
+		nvme_mdev_mmio_fatal_error(vctrl);
+		return false;
+	}
+
+	_DBG(vctrl, "MMIO: invalid DB value write qid=%d, size=%d, value=%d\n",
+	     qid, size, db);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_VALUE);
+	return false;
+}
+
+/* handle submission queue doorbell write */
+static void nvme_mdev_mmio_db_write_sq(struct nvme_mdev_vctrl *vctrl,
+				       u32 qid, u32 val)
+{
+	_DBG(vctrl, "MMIO: doorbell SQID %d, DB write %d\n", qid, val);
+
+	lockdep_assert_held(&vctrl->lock);
+	/* check if the db belongs to a valid queue */
+	if (qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vsq_en))
+		goto err_db;
+
+	/* emulate the shadow doorbell functionality */
+	if (!vctrl->mmio.shadow_db_en || qid == 0)
+		vctrl->mmio.dbs[qid].sqt = cpu_to_le32(val & 0x0000FFFF);
+
+	if (qid != 0)
+		vctrl->io_idle = false;
+
+	if (vctrl->vctrl_paused || !vctrl->mmio.shadow_db_supported)
+		return;
+
+	qid ? nvme_mdev_io_resume(vctrl) : nvme_mdev_adm_process_sq(vctrl);
+	return;
+err_db:
+
+	_DBG(vctrl, "MMIO: inactive/invalid SQ DB write qid=%d, value=%d\n",
+	     qid, val);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_REG);
+}
+
+/* handle doorbell write */
+static void nvme_mdev_mmio_db_write_cq(struct nvme_mdev_vctrl *vctrl,
+				       u32 qid, u32 val)
+{
+	_DBG(vctrl, "MMIO: doorbell CQID %d, DB write %d\n", qid, val);
+
+	lockdep_assert_held(&vctrl->lock);
+	/* check if the db belongs to a valid queue */
+	if (qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vcq_en))
+		goto err_db;
+
+	/* emulate the shadow doorbell functionality */
+	if (!vctrl->mmio.shadow_db_en || qid == 0)
+		vctrl->mmio.dbs[qid].cqh = cpu_to_le16(val & 0xFFFF);
+
+	if (vctrl->vctrl_paused || !vctrl->mmio.shadow_db_supported)
+		return;
+
+	if (qid == 0) {
+		nvme_mdev_vcq_process(vctrl, 0, false);
+		// if completion queue was full prior to that, we
+		// might have some admin commands pending,
+		// and this is the last chance to process them
+		nvme_mdev_adm_process_sq(vctrl);
+	}
+	return;
+err_db:
+	_DBG(vctrl,
+	     "MMIO: inactive/invalid CQ DB write qid=%d, value=%d\n",
+	     qid, val);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_REG);
+}
+
+/* This is called when user enables the controller */
+static void nvme_mdev_mmio_cntrl_enable(struct nvme_mdev_vctrl *vctrl)
+{
+	u64 acq, asq;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	// Controller must be reset from the dead state
+	if (nvme_mdev_vctrl_is_dead(vctrl))
+		goto error;
+
+	/* only NVME command set supported */
+	if (((vctrl->mmio.cc >> NVME_CC_CSS_SHIFT) & 0x7) != 0)
+		goto error;
+
+	/* Check the queue arbitration method*/
+	if ((vctrl->mmio.cc & NVME_CC_AMS_MASK) != NVME_CC_AMS_RR)
+		goto error;
+
+	/* Check the page size*/
+	if (((vctrl->mmio.cc >> NVME_CC_MPS_SHIFT) & 0xF) != (PAGE_SHIFT - 12))
+		goto error;
+
+	/* Start the admin completion queue*/
+	acq = vctrl->mmio.acql | ((u64)vctrl->mmio.acqh << 32);
+	asq = vctrl->mmio.asql | ((u64)vctrl->mmio.asqh << 32);
+
+	if (!nvme_mdev_vctrl_enable(vctrl, acq, asq, vctrl->mmio.aqa))
+		goto error;
+
+	/* Success! */
+	vctrl->mmio.csts |= NVME_CSTS_RDY;
+	return;
+error:
+	_DBG(vctrl, "MMIO: failure to enable the controller - fatal error\n");
+	nvme_mdev_mmio_fatal_error(vctrl);
+}
+
+/* This is called when user sends a notification that controller is
+ * about to be disabled
+ */
+static void nvme_mdev_mmio_cntrl_shutdown(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	/* clear shutdown notification bits */
+	vctrl->mmio.cc &= ~NVME_CC_SHN_MASK;
+
+	if (nvme_mdev_vctrl_is_dead(vctrl)) {
+		_DBG(vctrl, "MMIO: shutdown notification for dead ctrl\n");
+		return;
+	}
+
+	/* not enabled */
+	if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) {
+		_DBG(vctrl, "MMIO: shutdown notification with CSTS.RDY==0\n");
+		nvme_mdev_assert_io_not_running(vctrl);
+		return;
+	}
+
+	nvme_mdev_io_pause(vctrl);
+	nvme_mdev_vctrl_disable(vctrl);
+	vctrl->mmio.csts |= NVME_CSTS_SHST_CMPLT;
+}
+
+/* MMIO BAR read/write */
+static int nvme_mdev_mmio_bar_access(struct nvme_mdev_vctrl *vctrl,
+				     u16 offset, char *buf,
+				     u32 count, bool is_write)
+{
+	u32 val, oldval;
+
+	mutex_lock(&vctrl->lock);
+
+	/* Drop non DWORD sized and aligned reads/writes
+	 * (QWORD  read/writes are split by the caller)
+	 */
+	if (count != 4 || (offset & 0x3))
+		goto drop;
+
+	val = is_write ? le32_to_cpu(*(__le32 *)buf) : 0;
+
+	switch (offset) {
+	case NVME_REG_CAP:
+		/* controller capabilities (low 32 bit)*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.cap & 0xFFFFFFFF);
+		break;
+
+	case NVME_REG_CAP + 4:
+		/* controller capabilities (upper 32 bit)*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.cap >> 32);
+		break;
+
+	case NVME_REG_VS:
+		if (is_write)
+			goto drop;
+		store_le32(buf, NVME_MDEV_NVME_VER);
+		break;
+
+	case NVME_REG_INTMS:
+	case NVME_REG_INTMC:
+		/* Interrupt Mask Set & Clear */
+		goto drop;
+
+	case NVME_REG_CC:
+		/* Controller Configuration */
+		if (!is_write) {
+			store_le32(buf, vctrl->mmio.cc);
+			break;
+		}
+
+		oldval = vctrl->mmio.cc;
+		vctrl->mmio.cc = val;
+
+		/* drop if reserved bits set */
+		if (vctrl->mmio.cc & 0xFF00000E) {
+			_DBG(vctrl,
+			     "MMIO: reserved bits of CC set - fatal error\n");
+			nvme_mdev_mmio_fatal_error(vctrl);
+			goto drop;
+		}
+
+		/* CSS(command set),MPS(memory page size),AMS(queue arbitration)
+		 * must not be changed while controller is running
+		 */
+		if (vctrl->mmio.csts & NVME_CSTS_RDY) {
+			if ((vctrl->mmio.cc & 0x3FF0) != (oldval & 0x3FF0)) {
+				_DBG(vctrl,
+				     "MMIO: attempt to change setting bits of CC while CC.EN=1 - fatal error\n");
+
+				nvme_mdev_mmio_fatal_error(vctrl);
+				goto drop;
+			}
+		}
+
+		if ((vctrl->mmio.cc & NVME_CC_SHN_MASK) != NVME_CC_SHN_NONE) {
+			_DBG(vctrl, "MMIO: CC.SHN != 0 - shutdown\n");
+			nvme_mdev_mmio_cntrl_shutdown(vctrl);
+		}
+
+		/* change in controller enabled state */
+		if ((val & NVME_CC_ENABLE) == (oldval & NVME_CC_ENABLE))
+			break;
+
+		if (vctrl->mmio.cc & NVME_CC_ENABLE) {
+			_DBG(vctrl, "MMIO: CC.EN<=1 - enable the controller\n");
+			nvme_mdev_mmio_cntrl_enable(vctrl);
+		} else {
+			_DBG(vctrl, "MMIO: CC.EN<=0 - reset controller\n");
+			__nvme_mdev_vctrl_reset(vctrl, false);
+		}
+
+		break;
+
+	case NVME_REG_CSTS:
+		/* Controller Status */
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.csts);
+		break;
+
+	case NVME_REG_AQA:
+		/* admin queue submission and completion size*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.aqa);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.aqa = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ASQ:
+		/* admin submission queue address (low 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.asql);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.asql = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ASQ + 4:
+		/* admin submission queue address (high 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.asqh);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.asqh = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ACQ:
+		/* admin completion queue address (low 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.acql);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.acql = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ACQ + 4:
+		/* admin completion queue address (high 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.acqh);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.acqh = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_CMBLOC:
+	case NVME_REG_CMBSZ:
+		/* not supported - hardwired to 0*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, 0);
+		break;
+
+	case NVME_REG_DBS ... (NVME_REG_DBS + DB_AREA_SIZE - 1): {
+		/* completion and submission doorbells */
+		u16 db_offset = offset - NVME_REG_DBS;
+		u16 index = db_offset >> (DB_STRIDE_SHIFT + 2);
+		u16 qid = index >> 1;
+		bool sq = (index & 0x1) == 0;
+
+		if (!is_write || (db_offset & DB_MASK))
+			goto drop;
+
+		if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			goto drop;
+
+		if (nvme_mdev_vctrl_is_dead(vctrl))
+			goto drop;
+
+		sq ? nvme_mdev_mmio_db_write_sq(vctrl, qid, val) :
+		     nvme_mdev_mmio_db_write_cq(vctrl, qid, val);
+		break;
+	}
+	default:
+		goto drop;
+	}
+
+	mutex_unlock(&vctrl->lock);
+	return count;
+drop:
+	_DBG(vctrl, "MMIO: dropping write at 0x%x\n", offset);
+	mutex_unlock(&vctrl->lock);
+	return 0;
+}
+
+/* Called when the virtual controller is created */
+int nvme_mdev_mmio_create(struct nvme_mdev_vctrl *vctrl)
+{
+	int ret;
+
+	/* BAR0 */
+	nvme_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_0,
+				MMIO_BAR_SIZE, nvme_mdev_mmio_bar_access);
+
+	/* Spec allows for maximum depth of 0x10000, but we limit
+	 * it to 1 less to avoid various overflows
+	 */
+	BUILD_BUG_ON(MAX_VIRTUAL_QUEUE_DEPTH > 0xFFFF);
+
+	/* CAP has 4 bits for the doorbell stride shift*/
+	BUILD_BUG_ON(DB_STRIDE_SHIFT > 0xF);
+
+	/* Shadow doorbell limits doorbells to 1 page*/
+	BUILD_BUG_ON(DB_AREA_SIZE > PAGE_SIZE);
+
+	/* Just in case...*/
+	BUILD_BUG_ON((PAGE_SHIFT - 12) > 0xF);
+
+	vctrl->mmio.cap =
+		// MQES: maximum queue entries
+		((u64)(MAX_VIRTUAL_QUEUE_DEPTH - 1) << 0) |
+		// CQR: physically contiguous queues - no
+		(0ULL << 16) |
+		// AMS: Queue arbitration.
+		// TODOLATER: IO: implement WRRU
+		(0ULL << 17) |
+		// TO: RDY timeout - 0 (done in sync)
+		(0ULL << 24) |
+		// DSTRD: doorbell stride
+		((u64)DB_STRIDE_SHIFT << 32) |
+		// NSSRS: no support for nvme subsystem reset
+		(0ULL << 36) |
+		// CSS: NVM command set supported
+		(1ULL << 37) |
+		// BPS: no support for boot partition
+		(0ULL << 45) |
+		// MPSMIN: Minimum page size supported is PAGE_SIZE
+		((u64)(PAGE_SHIFT - 12) << 48) |
+		// MPSMAX: Maximum page size is PAGE_SIZE as well
+		((u64)(PAGE_SHIFT - 12) << 52);
+
+	/* Create the (regular) doorbell buffers */
+	vctrl->mmio.dbs_page = alloc_pages_node(vctrl->hctrl->node,
+						__GFP_ZERO, 0);
+
+	ret = -ENOMEM;
+
+	if (!vctrl->mmio.dbs_page)
+		goto error0;
+
+	vctrl->mmio.db_page_kmap = kmap(vctrl->mmio.dbs_page);
+	if (!vctrl->mmio.db_page_kmap)
+		goto error1;
+
+	vctrl->mmio.fake_eidx_page = alloc_pages_node(vctrl->hctrl->node,
+						      __GFP_ZERO, 0);
+	if (!vctrl->mmio.fake_eidx_page)
+		goto error2;
+
+	vctrl->mmio.fake_eidx_kmap = kmap(vctrl->mmio.fake_eidx_page);
+	if (!vctrl->mmio.fake_eidx_kmap)
+		goto error3;
+	return 0;
+error3:
+	put_page(vctrl->mmio.fake_eidx_kmap);
+error2:
+	kunmap(vctrl->mmio.dbs_page);
+error1:
+	put_page(vctrl->mmio.dbs_page);
+error0:
+	return ret;
+}
+
+/* Called when the virtual controller is reset */
+void nvme_mdev_mmio_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset)
+{
+	vctrl->mmio.cc = 0;
+	vctrl->mmio.csts = 0;
+
+	if (pci_reset) {
+		vctrl->mmio.aqa  = 0;
+		vctrl->mmio.asql = 0;
+		vctrl->mmio.asqh = 0;
+		vctrl->mmio.acql = 0;
+		vctrl->mmio.acqh = 0;
+	}
+}
+
+/* Called when the virtual controller is opened */
+void nvme_mdev_mmio_open(struct nvme_mdev_vctrl *vctrl)
+{
+	if (!vctrl->mmio.shadow_db_supported)
+		nvme_mdev_vctrl_region_set_mmap(vctrl,
+						VFIO_PCI_BAR0_REGION_INDEX,
+						NVME_REG_DBS, PAGE_SIZE,
+						&nvme_mdev_mmio_dbs_vm_ops);
+	else
+		nvme_mdev_vctrl_region_disable_mmap(vctrl,
+						    VFIO_PCI_BAR0_REGION_INDEX);
+}
+
+/* Called when the virtual controller queues are enabled */
+int nvme_mdev_mmio_enable_dbs(struct nvme_mdev_vctrl *vctrl)
+{
+	if (WARN_ON(vctrl->mmio.shadow_db_en))
+		return -EINVAL;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	/* setup normal doorbells and reset them*/
+	vctrl->mmio.dbs = vctrl->mmio.db_page_kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.fake_eidx_kmap;
+	memset((void *)vctrl->mmio.dbs, 0, DB_AREA_SIZE);
+	memset((void *)vctrl->mmio.eidxs, 0, DB_AREA_SIZE);
+	return 0;
+}
+
+/* Called when the virtual controller shadow doorbell is enabled */
+int nvme_mdev_mmio_enable_dbs_shadow(struct nvme_mdev_vctrl *vctrl,
+				     dma_addr_t sdb_iova,
+				     dma_addr_t eidx_iova)
+{
+	int ret;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	ret = nvme_mdev_viommu_create_kmap(&vctrl->viommu,
+					   sdb_iova, &vctrl->mmio.sdb_map);
+	if (ret)
+		return ret;
+
+	ret = nvme_mdev_viommu_create_kmap(&vctrl->viommu,
+					   eidx_iova, &vctrl->mmio.seidx_map);
+	if (ret) {
+		nvme_mdev_viommu_free_kmap(&vctrl->viommu,
+					   &vctrl->mmio.sdb_map);
+		return ret;
+	}
+
+	vctrl->mmio.dbs = vctrl->mmio.sdb_map.kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.seidx_map.kmap;
+
+	memcpy((void *)vctrl->mmio.dbs,
+	       vctrl->mmio.db_page_kmap, DB_AREA_SIZE);
+
+	memcpy((void *)vctrl->mmio.eidxs,
+	       vctrl->mmio.db_page_kmap, DB_AREA_SIZE);
+
+	vctrl->mmio.shadow_db_en = true;
+	return 0;
+}
+
+/* Called on guest mapping update to
+ * verify that our mappings are still intact
+ */
+void nvme_mdev_mmio_viommu_update(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+	if (!vctrl->mmio.shadow_db_en)
+		return;
+
+	nvme_mdev_viommu_update_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map);
+	nvme_mdev_viommu_update_kmap(&vctrl->viommu, &vctrl->mmio.seidx_map);
+
+	vctrl->mmio.dbs = vctrl->mmio.sdb_map.kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.seidx_map.kmap;
+}
+
+/* Disable the doorbells */
+void nvme_mdev_mmio_disable_dbs(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	/* Free the shadow doorbells */
+	nvme_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map);
+	nvme_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.seidx_map);
+
+	/* Clear the doorbells */
+	vctrl->mmio.dbs = NULL;
+	vctrl->mmio.eidxs = NULL;
+	vctrl->mmio.shadow_db_en = false;
+}
+
+/* Called when the virtual controller is about to be freed */
+void nvme_mdev_mmio_free(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+	kunmap(vctrl->mmio.dbs_page);
+	put_page(vctrl->mmio.dbs_page);
+	kunmap(vctrl->mmio.fake_eidx_page);
+	put_page(vctrl->mmio.fake_eidx_page);
+}
diff --git a/drivers/nvme/mdev/pci.c b/drivers/nvme/mdev/pci.c
new file mode 100644
index 000000000000..b7cdeaaf9c2e
--- /dev/null
+++ b/drivers/nvme/mdev/pci.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller minimal PCI/PCIe config space implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include "priv.h"
+
+/* setup a 64 bit PCI bar */
+void nvme_mdev_pci_setup_bar(struct nvme_mdev_vctrl *vctrl,
+			     u8 bar,
+			     unsigned int size,
+			     region_access_fn access_fn)
+{
+	nvme_mdev_vctrl_add_region(vctrl,
+				   VFIO_PCI_BAR0_REGION_INDEX +
+				   ((bar - PCI_BASE_ADDRESS_0) >> 2),
+				   size, access_fn);
+
+	store_le32(vctrl->pcicfg.wmask + bar, ~((u64)size - 1));
+	store_le32(vctrl->pcicfg.values + bar,
+		   PCI_BASE_ADDRESS_SPACE_MEMORY |
+		   PCI_BASE_ADDRESS_MEM_TYPE_64);
+}
+
+/* Allocate a pci capability*/
+static u8 nvme_mdev_pci_allocate_cap(struct nvme_mdev_vctrl *vctrl,
+				     u8 id, u8 size)
+{
+	u8 *cfg = vctrl->pcicfg.values;
+	u8 newcap = vctrl->pcicfg.end;
+	u8 cap = cfg[PCI_CAPABILITY_LIST];
+
+	size = round_up(size, 4);
+	// only standard cfg space caps for now
+	WARN_ON(newcap + size > 256);
+
+	if (!cfg[PCI_CAPABILITY_LIST]) {
+		/*special case for first capability*/
+		u16 status = load_le16(cfg + PCI_STATUS);
+
+		status |= PCI_STATUS_CAP_LIST;
+		store_le16(cfg + PCI_STATUS, status);
+
+		cfg[PCI_CAPABILITY_LIST] = newcap;
+		goto setupcap;
+	}
+
+	while (cfg[cap + PCI_CAP_LIST_NEXT] != 0)
+		cap = cfg[cap + PCI_CAP_LIST_NEXT];
+
+	cfg[cap + PCI_CAP_LIST_NEXT] = newcap;
+
+setupcap:
+	cfg[newcap + PCI_CAP_LIST_ID] = id;
+	cfg[newcap + PCI_CAP_LIST_NEXT] = 0;
+	vctrl->pcicfg.end += size;
+	return newcap;
+}
+
+static void nvme_mdev_pci_setup_pm_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg  =  vctrl->pcicfg.values;
+	u8 *cfgm =  vctrl->pcicfg.wmask;
+
+	u8 cap = nvme_mdev_pci_allocate_cap(vctrl,
+					    PCI_CAP_ID_PM, PCI_PM_SIZEOF);
+
+	store_le16(cfg + cap + PCI_PM_PMC, 0x3);
+	store_le16(cfg + cap + PCI_PM_CTRL, PCI_PM_CTRL_NO_SOFT_RESET);
+	store_le16(cfgm + cap + PCI_PM_CTRL, 0x3);
+	vctrl->pcicfg.pmcap = cap;
+}
+
+static void nvme_mdev_pci_setup_msix_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg  =  vctrl->pcicfg.values;
+	u8 *cfgm =  vctrl->pcicfg.wmask;
+	u8  cap = nvme_mdev_pci_allocate_cap(vctrl,
+					     PCI_CAP_ID_MSIX,
+					     PCI_CAP_MSIX_SIZEOF);
+
+	int MSIX_TBL_SIZE = roundup(MAX_VIRTUAL_IRQS * 16, PAGE_SIZE);
+	int MSIX_PBA_SIZE = roundup(DIV_ROUND_UP(MAX_VIRTUAL_IRQS, 8),
+				    PAGE_SIZE);
+
+	store_le16(cfg + cap + PCI_MSIX_FLAGS, MAX_VIRTUAL_IRQS - 1);
+	store_le16(cfgm + cap + PCI_MSIX_FLAGS,
+		   PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE);
+
+	store_le32(cfg + cap + PCI_MSIX_TABLE, 0x2);
+	store_le32(cfg + cap + PCI_MSIX_PBA, MSIX_TBL_SIZE | 0x2);
+
+	nvme_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_2,
+				__roundup_pow_of_two(MSIX_TBL_SIZE +
+						MSIX_PBA_SIZE), NULL);
+	vctrl->pcicfg.msixcap = cap;
+}
+
+static void nvme_mdev_pci_setup_pcie_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg = vctrl->pcicfg.values;
+	u8 cap = nvme_mdev_pci_allocate_cap(vctrl,
+					    PCI_CAP_ID_EXP,
+					    PCI_CAP_EXP_ENDPOINT_SIZEOF_V2);
+
+	store_le16(cfg + cap + PCI_EXP_FLAGS, 0x02 |
+		   (PCI_EXP_TYPE_ENDPOINT << 4));
+
+	store_le32(cfg + cap + PCI_EXP_DEVCAP,
+		   PCI_EXP_DEVCAP_RBER | PCI_EXP_DEVCAP_FLR);
+	store_le32(cfg + cap + PCI_EXP_LNKCAP,
+		   PCI_EXP_LNKCAP_SLS_8_0GB | (4 << 4) /*4x*/);
+	store_le16(cfg + cap + PCI_EXP_LNKSTA,
+		   PCI_EXP_LNKSTA_CLS_8_0GB | (4 << 4) /*4x*/);
+
+	store_le32(cfg + cap + PCI_EXP_LNKCAP2, PCI_EXP_LNKCAP2_SLS_8_0GB);
+	store_le16(cfg + cap + PCI_EXP_LNKCTL2, PCI_EXP_LNKCTL2_TLS_8_0GT);
+	vctrl->pcicfg.pciecap = cap;
+}
+
+/* This is called on PCI config read/write */
+static int nvme_mdev_pci_cfg_access(struct nvme_mdev_vctrl *vctrl,
+				    u16 offset, char *buf,
+				    u32 count, bool is_write)
+{
+	unsigned int i;
+
+	mutex_lock(&vctrl->lock);
+
+	if (!is_write) {
+		memcpy(buf, (vctrl->pcicfg.values + offset), count);
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		u8 address = offset + i;
+		u8 value = buf[i];
+		u8 old_value = vctrl->pcicfg.values[address];
+		u8 wmask = vctrl->pcicfg.wmask[address];
+		u8 new_value = (value & wmask) | (old_value & ~wmask);
+
+		/* D3/D0 power control */
+		if (address == vctrl->pcicfg.pmcap + PCI_PM_CTRL) {
+			u8 state = new_value & 0x03;
+
+			if (state != 0 && state != 3)
+				new_value = old_value;
+
+			if (old_value != new_value) {
+				const char *s = state == 3 ? "D3" : "D0";
+
+				if (state == 3)
+					__nvme_mdev_vctrl_reset(vctrl, true);
+				_DBG(vctrl, "PCI: going to %s\n", s);
+			}
+		}
+
+		/* FLR reset*/
+		if (address == vctrl->pcicfg.pciecap + PCI_EXP_DEVCTL + 1)
+			if (value & 0x80) {
+				_DBG(vctrl, "PCI: FLR reset\n");
+				__nvme_mdev_vctrl_reset(vctrl, true);
+			}
+		vctrl->pcicfg.values[offset + i] = new_value;
+	}
+out:
+	mutex_unlock(&vctrl->lock);
+	return count;
+}
+
+/* setup pci configuration */
+int nvme_mdev_pci_create(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg, *cfgm;
+
+	vctrl->pcicfg.values = kzalloc(PCI_CFG_SIZE, GFP_KERNEL);
+	if (!vctrl->pcicfg.values)
+		return -ENOMEM;
+
+	vctrl->pcicfg.wmask = kzalloc(PCI_CFG_SIZE, GFP_KERNEL);
+	if (!vctrl->pcicfg.wmask) {
+		kfree(vctrl->pcicfg.values);
+		return -ENOMEM;
+	}
+
+	cfg = vctrl->pcicfg.values;
+	cfgm = vctrl->pcicfg.wmask;
+
+	nvme_mdev_vctrl_add_region(vctrl,
+				   VFIO_PCI_CONFIG_REGION_INDEX,
+				   PCI_CFG_SIZE,
+				   nvme_mdev_pci_cfg_access);
+
+	/* vendor information */
+	store_le16(cfg + PCI_VENDOR_ID, NVME_MDEV_PCI_VENDOR_ID);
+	store_le16(cfg + PCI_DEVICE_ID, NVME_MDEV_PCI_DEVICE_ID);
+
+	/* pci command register */
+	store_le16(cfgm + PCI_COMMAND,
+		   PCI_COMMAND_INTX_DISABLE |
+		   PCI_COMMAND_MEMORY |
+		   PCI_COMMAND_MASTER);
+
+	/* pci status register */
+	store_le16(cfg + PCI_STATUS, PCI_STATUS_CAP_LIST);
+
+	/* subsystem information */
+	store_le16(cfg + PCI_SUBSYSTEM_VENDOR_ID, NVME_MDEV_PCI_SUBVENDOR_ID);
+	store_le16(cfg + PCI_SUBSYSTEM_ID, NVME_MDEV_PCI_SUBDEVICE_ID);
+	store_le8(cfg + PCI_CLASS_REVISION, NVME_MDEV_PCI_REVISION);
+
+	/*Programming Interface (NVM Express) */
+	store_le8(cfg + PCI_CLASS_PROG, 0x02);
+
+	/* Device class and subclass
+	 * (Mass storage controller, Non-Volatile memory controller)
+	 */
+	store_le16(cfg + PCI_CLASS_DEVICE, 0x0108);
+
+	/* dummy read/write */
+	store_le8(cfgm + PCI_CACHE_LINE_SIZE, 0xFF);
+
+	/* initial value*/
+	store_le8(cfg + PCI_CAPABILITY_LIST, 0);
+	vctrl->pcicfg.end = 0x40;
+
+	nvme_mdev_pci_setup_pm_cap(vctrl);
+	nvme_mdev_pci_setup_msix_cap(vctrl);
+	nvme_mdev_pci_setup_pcie_cap(vctrl);
+
+	/* INTX IRQ number - info only for BIOS */
+	store_le8(cfgm + PCI_INTERRUPT_LINE, 0xFF);
+	store_le8(cfg + PCI_INTERRUPT_PIN, 0x01);
+
+	return 0;
+}
+
+/* teardown pci configuration */
+void nvme_mdev_pci_free(struct nvme_mdev_vctrl *vctrl)
+{
+	kfree(vctrl->pcicfg.values);
+	kfree(vctrl->pcicfg.wmask);
+	vctrl->pcicfg.values = NULL;
+	vctrl->pcicfg.wmask = NULL;
+}
diff --git a/drivers/nvme/mdev/priv.h b/drivers/nvme/mdev/priv.h
new file mode 100644
index 000000000000..9f65e46c1ab2
--- /dev/null
+++ b/drivers/nvme/mdev/priv.h
@@ -0,0 +1,700 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Driver private data structures and helper macros
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#ifndef _MDEV_NVME_PRIV_H
+#define _MDEV_NVME_PRIV_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/vfio.h>
+#include <linux/mdev.h>
+#include <linux/pci.h>
+#include <linux/eventfd.h>
+#include <linux/byteorder/generic.h>
+#include "../host/nvme.h"
+#include "mdev.h"
+
+#define NVME_MDEV_NVME_VER  NVME_VS(0x01, 0x03, 0x00)
+#define NVME_MDEV_FIRMWARE_VERSION "1.0"
+
+#define NVME_MDEV_PCI_VENDOR_ID		PCI_VENDOR_ID_REDHAT_QUMRANET
+#define NVME_MDEV_PCI_DEVICE_ID		0x1234
+#define NVME_MDEV_PCI_SUBVENDOR_ID	PCI_SUBVENDOR_ID_REDHAT_QUMRANET
+#define NVME_MDEV_PCI_SUBDEVICE_ID	0
+#define NVME_MDEV_PCI_REVISION		0x0
+
+#define DB_STRIDE_SHIFT 4 /*4 = 1 cacheline */
+#define MAX_VIRTUAL_QUEUES 16
+#define MAX_VIRTUAL_QUEUE_DEPTH 0xFFFF
+#define MAX_VIRTUAL_NAMESPACES 16 /* NSID = 1..16*/
+#define MAX_VIRTUAL_IRQS 16
+
+#define MAX_HOST_QUEUES 4
+#define MAX_AER_COMMANDS 16
+#define MAX_LOG_PAGES 16
+
+extern bool use_shadow_doorbell;
+extern unsigned int io_timeout_ms;
+extern unsigned int poll_timeout_ms;
+extern unsigned int admin_poll_rate_ms;
+
+/* virtual submission queue*/
+struct  nvme_vsq {
+	u16 qid;
+	u16 size;
+	u16 head;	/*next item to read */
+
+	struct nvme_command *data; /*the queue*/
+	struct nvme_vcq *vcq; /* completion queue*/
+
+	dma_addr_t iova;
+	bool cont;
+
+	u16 hsq;
+};
+
+/* virtual completion queue*/
+struct nvme_vcq {
+	/* basic queue settings */
+	u16 qid;
+	u16 size;
+	u16 head;
+	u16 tail;
+	bool phase; /* current queue phase */
+
+	volatile struct nvme_completion *data;
+
+	/* number of items pending*/
+	u16 pending;
+
+	/* IRQ settings */
+	int irq /* -1 if disabled*/;
+
+	dma_addr_t iova;
+	bool cont;
+};
+
+/*A virtual namespace */
+struct nvme_mdev_vns {
+	/* host nvme namespace that we are attached to it*/
+	struct nvme_ns *host_ns;
+
+	/* block device that corresponds to the partition of that namespace */
+	struct block_device *host_part;
+	fmode_t fmode;
+
+	u32 nsid;
+
+	/* NSID on the host*/
+	u32 host_nsid;
+
+	/* host partition ID*/
+	unsigned int host_partid;
+
+	/* Offset inside the host namespace (start of the partition)*/
+	u64 host_lba_offset;
+
+	/* size of each block on the real namespace, same for host and guest */
+	u8 blksize_shift;
+
+	/* size of the namespace in lbas*/
+	u64 ns_size;
+
+	/* is the namespace read only?*/
+	bool readonly;
+
+	/* UUID of this namespace */
+	uuid_t uuid;
+
+	/* Optimal IO boundary*/
+	u16 noiob;
+};
+
+/* Virtual IOMMU */
+struct nvme_mdev_viommu {
+	struct device *hw_dev;
+	struct device *sw_dev;
+
+	/* dma/prp bookkeeping */
+	struct rb_root_cached maps_tree;
+	struct list_head maps_list;
+	struct nvme_mdev_vctrl *vctrl;
+};
+
+struct doorbell {
+	volatile __le32 sqt;
+	u8 rsvd1[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)];
+	volatile __le32 cqh;
+	u8 rsvd2[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)];
+};
+
+/* MMIO state */
+struct nvme_mdev_user_ctrl_mmio {
+	u32 cc;		/* controller configuration */
+	u32 csts;	/* controller status */
+	u64 cap		/* controller capabilities*/;
+
+	/* admin queue location & size */
+	u32 aqa;
+	u32 asql;
+	u32 asqh;
+	u32 acql;
+	u32 acqh;
+
+	bool shadow_db_supported;
+	bool shadow_db_en;
+
+	/* Regular doorbells */
+	struct page *dbs_page;
+	struct page *fake_eidx_page;
+	void *db_page_kmap;
+	void *fake_eidx_kmap;
+
+	/* Shadow doorbells */
+	struct page_map sdb_map;
+	struct page_map seidx_map;
+
+	/* Current doorbell mappings */
+	volatile struct doorbell *dbs;
+	volatile struct doorbell *eidxs;
+};
+
+/* pci configuration space of the device*/
+#define PCI_CFG_SIZE 4096
+struct nvme_mdev_pci_cfg_space {
+	u8 *values;
+	u8 *wmask;
+
+	u8 pmcap;
+	u8 pciecap;
+	u8 msixcap;
+	u8 end;
+};
+
+/*IRQ state of the controller */
+struct nvme_mdev_user_irq {
+	struct eventfd_ctx *trigger;
+	/* IRQ coalescing */
+	bool irq_coalesc_en;
+	time_t irq_time;
+	unsigned int irq_pending_cnt;
+};
+
+enum nvme_mdev_irq_mode {
+	NVME_MDEV_IMODE_NONE,
+	NVME_MDEV_IMODE_INTX,
+	NVME_MDEV_IMODE_MSIX,
+};
+
+struct nvme_mdev_user_irqs {
+	/* one of VFIO_PCI_{INTX|MSI|MSIX}_IRQ_INDEX */
+	enum nvme_mdev_irq_mode mode;
+
+	struct nvme_mdev_user_irq vecs[MAX_VIRTUAL_IRQS];
+	/* user interrupt coalescing settings */
+	u8 irq_coalesc_max;
+	unsigned int irq_coalesc_time_us;
+	/* device removal trigger*/
+	struct eventfd_ctx *request_trigger;
+};
+
+/*AER state */
+struct nvme_mdev_user_events {
+	/* async event request CIDs*/
+	u16 aer_cids[MAX_AER_COMMANDS];
+	unsigned int aer_cid_count;
+
+	/* events that are enabled */
+	unsigned long events_enabled[BITS_TO_LONGS(MAX_LOG_PAGES)];
+
+	/* events that are masked till next log page read*/
+	unsigned long events_masked[BITS_TO_LONGS(MAX_LOG_PAGES)];
+
+	/* events that are pending to be sent when user gives us an AER*/
+	unsigned long  events_pending[BITS_TO_LONGS(MAX_LOG_PAGES)];
+	u32 event_values[MAX_LOG_PAGES];
+};
+
+/* host IO queue */
+struct nvme_mdev_hq {
+	unsigned int usecount;
+	struct list_head link;
+	unsigned int hqid;
+};
+
+/* IO region abstraction (BARs, the PCI config space */
+struct nvme_mdev_vctrl;
+typedef int (*region_access_fn) (struct nvme_mdev_vctrl *vctrl,
+				 u16 offset, char *buf,
+				 u32 size, bool is_write);
+
+struct nvme_mdev_io_region {
+	unsigned int size;
+	region_access_fn rw;
+
+	/* IF != NULL, the mmap_area_start/size specify the mmaped window
+	 * of this region
+	 */
+	const struct vm_operations_struct *mmap_ops;
+	unsigned int mmap_area_start;
+	unsigned int mmap_area_size;
+};
+
+/*Virtual NVME controller state */
+struct nvme_mdev_vctrl {
+	struct kref ref;
+	struct mutex lock;
+	struct list_head link;
+
+	struct mdev_device *mdev;
+	struct nvme_mdev_hctrl *hctrl;
+	bool inuse;
+
+	struct nvme_mdev_io_region regions[VFIO_PCI_NUM_REGIONS];
+
+	/* virtual controller state */
+	struct nvme_mdev_user_ctrl_mmio mmio;
+	struct nvme_mdev_pci_cfg_space pcicfg;
+	struct nvme_mdev_user_irqs irqs;
+	struct nvme_mdev_user_events events;
+
+	/* emulated namespaces */
+	struct nvme_mdev_vns *namespaces[MAX_VIRTUAL_NAMESPACES];
+	__le32 ns_log[MAX_VIRTUAL_NAMESPACES];
+	unsigned int ns_log_size;
+
+	/* emulated submission queues*/
+	struct nvme_vsq vsqs[MAX_VIRTUAL_QUEUES];
+	unsigned long vsq_en[BITS_TO_LONGS(MAX_VIRTUAL_QUEUES)];
+
+	/* emulated completion queues*/
+	unsigned long vcq_en[BITS_TO_LONGS(MAX_VIRTUAL_QUEUES)];
+	struct nvme_vcq vcqs[MAX_VIRTUAL_QUEUES];
+
+	/* Host IO queues*/
+	int max_host_hw_queues;
+	struct list_head host_hw_queues;
+
+	/* Interface to access user memory */
+	struct notifier_block vfio_map_notifier;
+	struct notifier_block vfio_unmap_notifier;
+	struct nvme_mdev_viommu viommu;
+
+	/* the IO thread */
+	struct task_struct *iothread;
+	bool iothread_parked;
+	bool io_idle;
+	ktime_t now;
+
+	/* Settings */
+	unsigned int arb_burst_shift;
+	u8 worload_hint;
+	unsigned int iothread_cpu;
+
+	/* Identification*/
+	char subnqn[256];
+	char serial[9];
+
+	bool vctrl_paused; /* true when the host device paused our IO */
+};
+
+/* mdev instance type*/
+struct nvme_mdev_inst_type {
+	unsigned int max_hw_queues;
+	char name[16];
+	struct attribute_group *attrgroup;
+};
+
+/*Abstraction of the host controller that we are connected to */
+struct nvme_mdev_hctrl {
+	struct mutex lock;
+
+	/* numa node of the host controller*/
+	int node;
+
+	struct list_head link;
+	struct kref ref;
+	bool removing;
+
+	/* for reference counting */
+	struct nvme_ctrl *nvme_ctrl;
+
+	/* Host area*/
+	u16 oncs;
+	u8 mdts;
+	unsigned int id;
+
+	/* book-keeping for number of host queues we can allocate*/
+	unsigned int nr_host_queues;
+};
+
+/* vctrl.c*/
+struct nvme_mdev_vctrl *nvme_mdev_vctrl_create(struct mdev_device *mdev,
+					       struct nvme_mdev_hctrl *hctrl,
+					       unsigned int max_host_queues);
+
+int nvme_mdev_vctrl_destroy(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_vctrl_open(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_release(struct nvme_mdev_vctrl *vctrl);
+
+void nvme_mdev_vctrl_pause(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_resume(struct nvme_mdev_vctrl *vctrl);
+
+bool nvme_mdev_vctrl_enable(struct nvme_mdev_vctrl *vctrl,
+			    dma_addr_t cqiova, dma_addr_t sqiova, u32 sizes);
+
+void nvme_mdev_vctrl_disable(struct nvme_mdev_vctrl *vctrl);
+
+void nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl);
+void __nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset);
+
+void nvme_mdev_vctrl_add_region(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index, unsigned int size,
+				region_access_fn access_fn);
+
+void nvme_mdev_vctrl_region_set_mmap(struct nvme_mdev_vctrl *vctrl,
+				     unsigned int index,
+				     unsigned int offset,
+				     unsigned int size,
+				     const struct vm_operations_struct *ops);
+
+void nvme_mdev_vctrl_region_disable_mmap(struct nvme_mdev_vctrl *vctrl,
+					 unsigned int index);
+
+void nvme_mdev_vctrl_bind_iothread(struct nvme_mdev_vctrl *vctrl,
+				   unsigned int cpu);
+
+int nvme_mdev_vctrl_set_shadow_doorbell_supported(struct nvme_mdev_vctrl *vctrl,
+						  bool enable);
+
+int nvme_mdev_vctrl_hq_alloc(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_hq_free(struct nvme_mdev_vctrl *vctrl, u16 qid);
+unsigned int nvme_mdev_vctrl_hqs_list(struct nvme_mdev_vctrl *vctrl, u16 *out);
+bool nvme_mdev_vctrl_is_dead(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_vctrl_viommu_map(struct nvme_mdev_vctrl *vctrl, u32 flags,
+			       dma_addr_t iova, u64 size);
+
+int nvme_mdev_vctrl_viommu_unmap(struct nvme_mdev_vctrl *vctrl,
+				 dma_addr_t iova, u64 size);
+
+/* hctrl.c*/
+struct nvme_mdev_inst_type *nvme_mdev_inst_type_get(const char *name);
+struct nvme_mdev_hctrl *nvme_mdev_hctrl_lookup_get(struct device *parent);
+void nvme_mdev_hctrl_put(struct nvme_mdev_hctrl *hctrl);
+
+int nvme_mdev_hctrl_hqs_available(struct nvme_mdev_hctrl *hctrl);
+
+bool nvme_mdev_hctrl_hqs_reserve(struct nvme_mdev_hctrl *hctrl,
+				 unsigned int n);
+void nvme_mdev_hctrl_hqs_unreserve(struct nvme_mdev_hctrl *hctrl,
+				   unsigned int n);
+
+int nvme_mdev_hctrl_hq_alloc(struct nvme_mdev_hctrl *hctrl);
+void nvme_mdev_hctrl_hq_free(struct nvme_mdev_hctrl *hctrl, u16 qid);
+bool nvme_mdev_hctrl_hq_can_submit(struct nvme_mdev_hctrl *hctrl, u16 qid);
+bool nvme_mdev_hctrl_hq_check_op(struct nvme_mdev_hctrl *hctrl, u8 optcode);
+
+int nvme_mdev_hctrl_hq_submit(struct nvme_mdev_hctrl *hctrl,
+			      u16 qid, u32 tag,
+			      struct nvme_command *cmd,
+			      struct nvme_ext_data_iter *datait);
+
+int nvme_mdev_hctrl_hq_poll(struct nvme_mdev_hctrl *hctrl,
+			    u32 qid,
+			    struct nvme_ext_cmd_result *results,
+			    unsigned int max_len);
+
+void nvme_mdev_hctrl_destroy_all(void);
+
+/* io.c */
+int nvme_mdev_io_create(struct nvme_mdev_vctrl *vctrl, unsigned int cpu);
+void nvme_mdev_io_free(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_io_pause(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_io_resume(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_assert_io_not_running(struct nvme_mdev_vctrl *vctrl);
+
+/* mmio.c*/
+int nvme_mdev_mmio_create(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_open(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset);
+void nvme_mdev_mmio_free(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_mmio_enable_dbs(struct nvme_mdev_vctrl *vctrl);
+int nvme_mdev_mmio_enable_dbs_shadow(struct nvme_mdev_vctrl *vctrl,
+				     dma_addr_t sdb_iova, dma_addr_t eidx_iova);
+
+void nvme_mdev_mmio_viommu_update(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_disable_dbs(struct nvme_mdev_vctrl *vctrl);
+bool nvme_mdev_mmio_db_check(struct nvme_mdev_vctrl *vctrl,
+			     u16 qid, u16 size, u16 db);
+
+/* pci.c*/
+int nvme_mdev_pci_create(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_pci_free(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_pci_setup_bar(struct nvme_mdev_vctrl *vctrl,
+			     u8 bar, unsigned int size,
+			     region_access_fn access_fn);
+/* adm.c*/
+void nvme_mdev_adm_process_sq(struct nvme_mdev_vctrl *vctrl);
+
+/* events.c */
+void nvme_mdev_events_init(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_events_reset(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_event_request_receive(struct nvme_mdev_vctrl *vctrl, u16 cid);
+void nvme_mdev_event_process_ack(struct nvme_mdev_vctrl *vctrl, u8 log_page);
+
+void nvme_mdev_event_send(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_async_event_type type,
+			  enum nvme_async_event info);
+
+u32 nvme_mdev_event_read_aen_config(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_event_set_aen_config(struct nvme_mdev_vctrl *vctrl, u32 value);
+
+/* irq.c*/
+void nvme_mdev_irqs_setup(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_irqs_reset(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_mdev_irq_mode mode);
+void nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+			    enum nvme_mdev_irq_mode mode);
+
+int nvme_mdev_irqs_set_triggers(struct nvme_mdev_vctrl *vctrl,
+				int start, int count, int32_t *fds);
+int nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+				      int32_t fd);
+
+void nvme_mdev_irq_raise_unplug_event(struct nvme_mdev_vctrl *vctrl,
+				      unsigned int count);
+void nvme_mdev_irq_raise(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index);
+void nvme_mdev_irq_trigger(struct nvme_mdev_vctrl *vctrl,
+			   unsigned int index);
+void nvme_mdev_irq_cond_trigger(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index);
+void nvme_mdev_irq_clear(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index);
+
+/* ns.c*/
+int nvme_mdev_vns_open(struct nvme_mdev_vctrl *vctrl,
+		       u32 host_nsid, unsigned int host_partid);
+int nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl,
+			  u32 user_nsid);
+void nvme_mdev_vns_destroy_all(struct nvme_mdev_vctrl *vctrl);
+
+struct nvme_mdev_vns *nvme_mdev_vns_from_vnsid(struct nvme_mdev_vctrl *vctrl,
+					       u32 user_ns_id);
+
+int nvme_mdev_vns_print_description(struct nvme_mdev_vctrl *vctrl,
+				    char *buf, unsigned int size);
+void nvme_mdev_vns_host_ns_update(struct nvme_mdev_vctrl *vctrl,
+				  u32 host_nsid, bool removed);
+
+void nvme_mdev_vns_log_reset(struct nvme_mdev_vctrl *vctrl);
+
+/* vcq.c */
+int nvme_mdev_vcq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, int irq);
+
+int nvme_mdev_vcq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vcq *q);
+
+void nvme_mdev_vcq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid);
+void nvme_mdev_vcq_process(struct nvme_mdev_vctrl *vctrl, u16 qid,
+			   bool trigger_irqs);
+
+bool nvme_mdev_vcq_flush(struct nvme_mdev_vctrl *vctrl, u16 qid);
+bool nvme_mdev_vcq_reserve_space(struct nvme_vcq *q);
+
+void nvme_mdev_vcq_write_io(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vcq *q, u16 sq_head,
+			    u16 sqid, u16 cid, u16 status);
+
+void nvme_mdev_vcq_write_adm(struct nvme_mdev_vctrl *vctrl,
+			     struct nvme_vcq *q, u32 dw0,
+			     u16 sq_head, u16 cid, u16 status);
+/* vsq.c*/
+int nvme_mdev_vsq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, u16 cqid);
+
+int nvme_mdev_vsq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vsq *q);
+
+void nvme_mdev_vsq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid);
+
+bool nvme_mdev_vsq_has_data(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vsq *q);
+
+const struct nvme_command *nvme_mdev_vsq_get_cmd(struct nvme_mdev_vctrl *vctrl,
+						 struct nvme_vsq *q);
+
+void nvme_mdev_vsq_cmd_done_io(struct nvme_mdev_vctrl *vctrl,
+			       u16 sqid, u16 cid, u16 status);
+void nvme_mdev_vsq_cmd_done_adm(struct nvme_mdev_vctrl *vctrl,
+				u32 dw0, u16 cid, u16 status);
+bool nvme_mdev_vsq_suspend_io(struct nvme_mdev_vctrl *vctrl, u16 sqid);
+
+/* udata.c*/
+void nvme_mdev_udata_iter_setup(struct nvme_mdev_viommu *viommu,
+				struct nvme_ext_data_iter *iter);
+
+int nvme_mdev_udata_iter_set_dptr(struct nvme_ext_data_iter *it,
+				  const union nvme_data_ptr *dptr, u64 size);
+
+struct nvme_ext_data_iter *
+nvme_mdev_kdata_iter_alloc(struct nvme_mdev_viommu *viommu, unsigned int size);
+
+int nvme_mdev_read_from_udata(void *dst, struct nvme_ext_data_iter *srcit,
+			      u64 size);
+
+int nvme_mdev_write_to_udata(struct nvme_ext_data_iter *dstit, void *src,
+			     u64 size);
+
+void *nvme_mdev_udata_queue_vmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova,
+				 unsigned int size, bool cont);
+/* viommu.c */
+void nvme_mdev_viommu_init(struct nvme_mdev_viommu *viommu,
+			   struct device *sw_dev,
+			   struct device *hw_dev);
+
+int nvme_mdev_viommu_add(struct nvme_mdev_viommu *viommu, u32 flags,
+			 dma_addr_t iova, u64 size);
+
+int nvme_mdev_viommu_remove(struct nvme_mdev_viommu *viommu,
+			    dma_addr_t iova, u64 size);
+
+int nvme_mdev_viommu_translate(struct nvme_mdev_viommu *viommu,
+			       dma_addr_t iova,
+			       dma_addr_t *physical,
+			       dma_addr_t *host_iova);
+
+int nvme_mdev_viommu_create_kmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova, struct page_map *page);
+
+void nvme_mdev_viommu_free_kmap(struct nvme_mdev_viommu *viommu,
+				struct page_map *page);
+
+void nvme_mdev_viommu_update_kmap(struct nvme_mdev_viommu *viommu,
+				  struct page_map *page);
+
+void nvme_mdev_viommu_reset(struct nvme_mdev_viommu *viommu);
+
+/* some utilities*/
+
+#define store_le64(address, value) (*((__le64 *)(address)) = cpu_to_le64(value))
+#define store_le32(address, value) (*((__le32 *)(address)) = cpu_to_le32(value))
+#define store_le16(address, value) (*((__le16 *)(address)) = cpu_to_le16(value))
+#define store_le8(address, value)  (*((u8 *)(address)) = (value))
+
+#define load_le16(address) le16_to_cpu(*(__le16 *)(address))
+#define load_le32(address) le32_to_cpu(*(__le32 *)(address))
+
+#define store_strsp(dst, src) \
+	memcpy_and_pad(dst, sizeof(dst), src, sizeof(src) - 1, ' ')
+
+#define DNR(e) ((e) | NVME_SC_DNR)
+
+#define PAGE_ADDRESS(address) ((address) & PAGE_MASK)
+#define OFFSET_IN_PAGE(address) ((address) & ~(PAGE_MASK))
+
+#define _DBG(vctrl, fmt, ...) \
+	dev_dbg(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define _INFO(vctrl, fmt, ...) \
+	dev_info(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define _WARN(vctrl, fmt, ...) \
+	dev_warn(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define mdev_to_vctrl(mdev) \
+	((struct nvme_mdev_vctrl *)mdev_get_drvdata(mdev))
+
+#define dev_to_vctrl(mdev) \
+	mdev_to_vctrl(mdev_from_dev(dev))
+
+#define RSRV_NSID (BIT(1))
+#define RSRV_DW23 (BIT(2) | BIT(3))
+#define RSRV_MPTR (BIT(4) | BIT(5))
+
+#define RSRV_DPTR (BIT(6) | BIT(7) | BIT(8) | BIT(9))
+#define RSRV_DPTR_PRP2 (BIT(8) | BIT(9))
+
+#define RSRV_DW10_15 (BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW11_15 (BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW12_15 (BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW13_15 (BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW14_15 (BIT(14) | BIT(15))
+
+static inline bool check_reserved_dwords(const u32 *dwords,
+					 int count, unsigned long bitmask)
+{
+	int bit;
+
+	if (WARN_ON(count > BITS_PER_TYPE(long)))
+		return false;
+
+	for_each_set_bit(bit, &bitmask, count)
+		if (dwords[bit])
+			return false;
+	return true;
+}
+
+static inline bool check_range(u64 start, u64 size, u64 end)
+{
+	u64 test = start + size;
+
+	/* check for overflow */
+	if (test < start || test < size)
+		return false;
+	return test <= end;
+}
+
+/* Rough translation of internal errors to the NVME errors */
+static inline int nvme_mdev_translate_error(int error)
+{
+	// nvme status, including no error (NVME_SC_SUCCESS)
+	if (error >= 0)
+		return error;
+
+	switch (error) {
+	case -ENOMEM:
+		/*no memory - truly an internal error*/
+		return NVME_SC_INTERNAL;
+	case -ENOSPC:
+		/* Happens when user sends to large PRP list
+		 * User shoudn't do this since the maximum transfer size
+		 * is specified in the controller caps
+		 */
+		return DNR(NVME_SC_DATA_XFER_ERROR);
+	case -EFAULT:
+		/* Bad memory pointers in the prp lists*/
+		return DNR(NVME_SC_DATA_XFER_ERROR);
+	case -EINVAL:
+		/* Bad prp offsets in the prp lists/command*/
+		return DNR(NVME_SC_PRP_OFFSET_INVALID);
+	default:
+		/*Shouldn't happen */
+		WARN_ON_ONCE(true);
+		return NVME_SC_INTERNAL;
+	}
+}
+
+static inline bool timeout(ktime_t event, ktime_t now, unsigned long timeout_ms)
+{
+	return ktime_ms_delta(now, event) > (long)timeout_ms;
+}
+
+extern struct mdev_parent_ops mdev_fops;
+extern struct list_head nvme_mdev_vctrl_list;
+extern struct mutex nvme_mdev_vctrl_list_mutex;
+
+#endif // _MDEV_NVME_H
diff --git a/drivers/nvme/mdev/udata.c b/drivers/nvme/mdev/udata.c
new file mode 100644
index 000000000000..7af6b3f6d6aa
--- /dev/null
+++ b/drivers/nvme/mdev/udata.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * User (guest) data access routines
+ * Implementation of PRP iterator in user memory
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+#define MAX_PRP ((PAGE_SIZE / sizeof(__le64)) - 1)
+
+/* Setup up a new PRP iterator */
+void nvme_mdev_udata_iter_setup(struct nvme_mdev_viommu *viommu,
+				struct nvme_ext_data_iter *iter)
+{
+	iter->viommu = viommu;
+	iter->count = 0;
+	iter->next = NULL;
+	iter->release = NULL;
+}
+
+/* Load a new prp list into the iterator. Internal*/
+static int nvme_mdev_udata_iter_load_prplist(struct nvme_ext_data_iter *iter,
+					     dma_addr_t iova)
+{
+	dma_addr_t  data_iova;
+	int ret;
+	__le64 *map;
+
+	/* map the prp list*/
+	ret = nvme_mdev_viommu_create_kmap(iter->viommu,
+					   PAGE_ADDRESS(iova),
+					   &iter->uprp.page);
+	if (ret)
+		return ret;
+
+	iter->uprp.index = OFFSET_IN_PAGE(iova) / (sizeof(__le64));
+
+	/* read its first entry and check its alignment */
+	map = iter->uprp.page.kmap;
+	data_iova = le64_to_cpu(map[iter->uprp.index]);
+
+	if (OFFSET_IN_PAGE(data_iova) != 0) {
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+		return -EINVAL;
+	}
+
+	/* translate the entry to complete the setup*/
+	ret =  nvme_mdev_viommu_translate(iter->viommu, data_iova,
+					  &iter->physical, &iter->host_iova);
+	if (ret)
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+
+	return ret;
+}
+
+/* ->next function when iterator points to prp list*/
+static int nvme_mdev_udata_iter_next_prplist(struct nvme_ext_data_iter *iter)
+{
+	dma_addr_t iova;
+	int ret;
+	__le64 *map = iter->uprp.page.kmap;
+
+	if (WARN_ON(iter->count <= 0))
+		return 0;
+
+	if (--iter->count == 0) {
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+		return 0;
+	}
+
+	iter->uprp.index++;
+
+	if (iter->uprp.index < MAX_PRP || iter->count == 1) {
+		// advance over next pointer in current prp list
+		// these pointers must be page aligned
+		iova = le64_to_cpu(map[iter->uprp.index]);
+		if (OFFSET_IN_PAGE(iova) != 0)
+			return -EINVAL;
+
+		ret  = nvme_mdev_viommu_translate(iter->viommu, iova,
+						  &iter->physical,
+						  &iter->host_iova);
+		if (ret)
+			nvme_mdev_viommu_free_kmap(iter->viommu,
+						   &iter->uprp.page);
+		return ret;
+	}
+
+	/* switch to next prp list. it must be page aligned as well*/
+	iova = le64_to_cpu(map[MAX_PRP]);
+
+	if (OFFSET_IN_PAGE(iova) != 0)
+		return -EINVAL;
+
+	nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+	return nvme_mdev_udata_iter_load_prplist(iter, iova);
+}
+
+/* ->next function when iterator points to user data pointer*/
+static int nvme_mdev_udata_iter_next_dptr(struct nvme_ext_data_iter *iter)
+{
+	dma_addr_t  iova;
+
+	if (WARN_ON(iter->count <= 0))
+		return 0;
+
+	if (--iter->count == 0)
+		return 0;
+
+	/* we will be called only once to deal with the second
+	 * pointer in the data pointer
+	 */
+	iova = le64_to_cpu(iter->dptr->prp2);
+
+	if (iter->count == 1) {
+		/* only need to read one more entry, meaning
+		 * the 2nd entry of the dptr.
+		 * It must be page aligned
+		 */
+		if (OFFSET_IN_PAGE(iova) != 0)
+			return -EINVAL;
+		return nvme_mdev_viommu_translate(iter->viommu, iova,
+						  &iter->physical,
+						  &iter->host_iova);
+	} else {
+		/*
+		 * Second dptr entry is prp pointer, and it might not
+		 * be page aligned (but QWORD aligned at least)
+		 */
+		if (iova & 0x7ULL)
+			return -EINVAL;
+		iter->next = nvme_mdev_udata_iter_next_prplist;
+		return nvme_mdev_udata_iter_load_prplist(iter, iova);
+	}
+}
+
+/* Set prp list iterator to point to data pointer found in NVME command */
+int nvme_mdev_udata_iter_set_dptr(struct nvme_ext_data_iter *it,
+				  const union nvme_data_ptr *dptr, u64 size)
+{
+	int ret;
+	u64 prp1 = le64_to_cpu(dptr->prp1);
+	dma_addr_t iova = PAGE_ADDRESS(prp1);
+	unsigned int page_offset = OFFSET_IN_PAGE(prp1);
+
+	/* first dptr pointer must be at least DWORD aligned*/
+	if (page_offset & 0x3)
+		return -EINVAL;
+
+	it->dptr = dptr;
+	it->next = nvme_mdev_udata_iter_next_dptr;
+	it->count = DIV_ROUND_UP_ULL(size + page_offset, PAGE_SIZE);
+
+	ret = nvme_mdev_viommu_translate(it->viommu, iova,
+					 &it->physical, &it->host_iova);
+	if (ret)
+		return ret;
+
+	it->physical += page_offset;
+	it->host_iova += page_offset;
+	return 0;
+}
+
+/* ->next function when iterator points to kernel memory buffer */
+static int nvme_mdev_kdata_iter_next(struct nvme_ext_data_iter *it)
+{
+	if (WARN_ON(it->count <= 0))
+		return 0;
+
+	if (--it->count == 0)
+		return 0;
+
+	it->physical = PAGE_ADDRESS(it->physical) + PAGE_SIZE;
+	it->host_iova = PAGE_ADDRESS(it->host_iova) + PAGE_SIZE;
+	return 0;
+}
+
+/* ->release function for kdata iterator to free it after use */
+static void nvme_mdev_kdata_iter_free(struct nvme_ext_data_iter *it)
+{
+	struct device *dma_dev = it->viommu->hw_dev;
+
+	if (dma_dev)
+		dma_free_coherent(dma_dev, it->kmem.size,
+				  it->kmem.data, it->kmem.dma_addr);
+	else
+		kfree(it->kmem.data);
+	kfree(it);
+}
+
+/* allocate a kernel data buffer with read iterator for nvme host device */
+struct nvme_ext_data_iter *
+nvme_mdev_kdata_iter_alloc(struct nvme_mdev_viommu *viommu, unsigned int size)
+{
+	struct nvme_ext_data_iter *it;
+
+	it = kzalloc(sizeof(*it), GFP_KERNEL);
+	if (!it)
+		return NULL;
+
+	it->viommu = viommu;
+	it->kmem.size = size;
+	if (viommu->hw_dev) {
+		it->kmem.data = dma_alloc_coherent(viommu->hw_dev, size,
+						   &it->kmem.dma_addr,
+						   GFP_KERNEL);
+	} else {
+		it->kmem.data = kzalloc(size, GFP_KERNEL);
+		it->kmem.dma_addr = 0;
+	}
+
+	if (!it->kmem.data) {
+		kfree(it);
+		return NULL;
+	}
+
+	it->physical = virt_to_phys(it->kmem.data);
+	it->host_iova = it->kmem.dma_addr;
+
+	it->count = DIV_ROUND_UP(size + OFFSET_IN_PAGE(it->physical),
+				 PAGE_SIZE);
+
+	it->next = nvme_mdev_kdata_iter_next;
+	it->release = nvme_mdev_kdata_iter_free;
+	return it;
+}
+
+/* copy data from user data iterator to a kernel buffer */
+int nvme_mdev_read_from_udata(void *dst, struct nvme_ext_data_iter *srcit,
+			      u64 size)
+{
+	int ret;
+	unsigned int srcoffset, chunk_size;
+
+	while (srcit->count && size > 0) {
+		struct page *page = pfn_to_page(PHYS_PFN(srcit->physical));
+		void *src = kmap(page);
+
+		if (!src)
+			return -ENOMEM;
+
+		srcoffset = OFFSET_IN_PAGE(srcit->physical);
+		chunk_size = min(size, (u64)PAGE_SIZE - srcoffset);
+
+		memcpy(dst, src + srcoffset, chunk_size);
+		dst += chunk_size;
+		size -= chunk_size;
+		kunmap(page);
+
+		ret = srcit->next(srcit);
+		if (ret)
+			return ret;
+	}
+	WARN_ON(size > 0);
+	return 0;
+}
+
+/* copy data from kernel buffer to user data iterator */
+int nvme_mdev_write_to_udata(struct nvme_ext_data_iter *dstit, void *src,
+			     u64 size)
+{
+	int ret, dstoffset, chunk_size;
+
+	while (dstit->count && size > 0) {
+		struct page *page = pfn_to_page(PHYS_PFN(dstit->physical));
+		void *dst = kmap(page);
+
+		if (!dst)
+			return -ENOMEM;
+
+		dstoffset = OFFSET_IN_PAGE(dstit->physical);
+		chunk_size = min(size, (u64)PAGE_SIZE - dstoffset);
+
+		memcpy(dst + dstoffset, src, chunk_size);
+		src += chunk_size;
+		size -= chunk_size;
+		kunmap(page);
+
+		ret = dstit->next(dstit);
+		if (ret)
+			return ret;
+	}
+	WARN_ON(size > 0);
+	return 0;
+}
+
+/* Set prp list iterator to point to prp list found in create queue command */
+static int
+nvme_mdev_udata_iter_set_queue_prplist(struct nvme_mdev_viommu *viommu,
+				       struct nvme_ext_data_iter *iter,
+				       dma_addr_t iova, unsigned int size)
+{
+	if (iova & ~PAGE_MASK)
+		return -EINVAL;
+
+	nvme_mdev_udata_iter_setup(viommu, iter);
+	iter->count = DIV_ROUND_UP(size, PAGE_SIZE);
+	iter->next = nvme_mdev_udata_iter_next_prplist;
+	return nvme_mdev_udata_iter_load_prplist(iter, iova);
+}
+
+/* Map an SQ/CQ queue (contiguous in guest physical memory) */
+static int nvme_mdev_queue_getpages_contiguous(struct nvme_mdev_viommu *viommu,
+					       dma_addr_t iova,
+					       struct page **pages,
+					       unsigned int npages)
+{
+	int ret;
+	unsigned int i;
+
+	dma_addr_t host_page_iova;
+	phys_addr_t physical;
+
+	for (i = 0 ; i < npages; i++) {
+		ret = nvme_mdev_viommu_translate(viommu, iova + (PAGE_SIZE * i),
+						 &physical,
+						 &host_page_iova);
+		if (ret)
+			return ret;
+		pages[i] = pfn_to_page(PHYS_PFN(physical));
+	}
+	return 0;
+}
+
+/* Map an SQ/CQ queue (non contiguous in guest physical memory) */
+static int nvme_mdev_queue_getpages_prplist(struct nvme_mdev_viommu *viommu,
+					    dma_addr_t iova,
+					    struct page **pages,
+					    unsigned int npages)
+{
+	int ret, i = 0;
+	struct nvme_ext_data_iter uprpit;
+
+	ret = nvme_mdev_udata_iter_set_queue_prplist(viommu,
+						     &uprpit, iova,
+						     npages * PAGE_SIZE);
+	if (ret)
+		return ret;
+
+	while (uprpit.count && i < npages) {
+		pages[i++] = pfn_to_page(PHYS_PFN(uprpit.physical));
+		ret = uprpit.next(&uprpit);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+/* map a SQ/CQ queue to host physical memory */
+void *nvme_mdev_udata_queue_vmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova,
+				 unsigned int size,
+				 bool cont)
+{
+	int ret;
+	unsigned int npages;
+	void *map;
+	struct page **pages;
+
+	// queue must be page aligned
+	if (OFFSET_IN_PAGE(iova) != 0)
+		return ERR_PTR(-EINVAL);
+
+	npages = DIV_ROUND_UP(size, PAGE_SIZE);
+	pages = kcalloc(npages, sizeof(struct page *), GFP_KERNEL);
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+
+	ret = cont ?
+		nvme_mdev_queue_getpages_contiguous(viommu, iova, pages, npages)
+		: nvme_mdev_queue_getpages_prplist(viommu, iova, pages, npages);
+
+	if (ret) {
+		map = ERR_PTR(ret);
+		goto out;
+	}
+
+	map =  vmap(pages, npages, VM_MAP, PAGE_KERNEL);
+	if (!map)
+		map = ERR_PTR(-ENOMEM);
+out:
+	kfree(pages);
+	return map;
+}
diff --git a/drivers/nvme/mdev/vcq.c b/drivers/nvme/mdev/vcq.c
new file mode 100644
index 000000000000..7702137eb8bc
--- /dev/null
+++ b/drivers/nvme/mdev/vcq.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe completion queue implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* Create new virtual completion queue */
+int nvme_mdev_vcq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, int irq)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	int ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	q->iova = iova;
+	q->cont = cont;
+	q->data = NULL;
+	q->qid = qid;
+	q->size = size;
+	q->tail = 0;
+	q->phase = true;
+	q->irq = irq;
+	q->pending = 0;
+	q->head = 0;
+
+	ret = nvme_mdev_vcq_viommu_update(&vctrl->viommu, q);
+	if (ret && (ret != -EFAULT))
+		return ret;
+
+	_DBG(vctrl, "VCQ: create qid=%d contig=%d depth=%d irq=%d\n",
+	     qid, cont, size, irq);
+
+	set_bit(qid, vctrl->vcq_en);
+
+	vctrl->mmio.dbs[q->qid].cqh = 0;
+	vctrl->mmio.eidxs[q->qid].cqh = 0;
+	return 0;
+}
+
+/* Update the kernel mapping of the queue */
+int nvme_mdev_vcq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vcq *q)
+{
+	void *data;
+
+	if (q->data)
+		vunmap((void *)q->data);
+
+	data = nvme_mdev_udata_queue_vmap(viommu, q->iova,
+					  (unsigned int)q->size *
+					  sizeof(struct nvme_completion),
+					  q->cont);
+
+	q->data = IS_ERR(data) ? NULL : data;
+	return IS_ERR(data) ? PTR_ERR(data) : 0;
+}
+
+/* Delete a virtual completion queue */
+void nvme_mdev_vcq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (q->data)
+		vunmap((void *)q->data);
+	q->data = NULL;
+
+	_DBG(vctrl, "VCQ: delete qid=%d\n", q->qid);
+	clear_bit(qid, vctrl->vcq_en);
+}
+
+/* Move queue tail one item forward */
+static void nvme_mdev_vcq_advance_tail(struct nvme_vcq *q)
+{
+	if (++q->tail == q->size) {
+		q->tail = 0;
+		q->phase = !q->phase;
+	}
+}
+
+/* Move queue head one item forward */
+static void nvme_mdev_vcq_advance_head(struct nvme_vcq *q)
+{
+	q->head++;
+	if (q->head == q->size)
+		q->head = 0;
+}
+
+/* Process a virtual completion queue*/
+void nvme_mdev_vcq_process(struct nvme_mdev_vctrl *vctrl, u16 qid,
+			   bool trigger_irqs)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	u16 new_head;
+	u32 eidx;
+
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs)
+		return;
+
+	new_head = le32_to_cpu(vctrl->mmio.dbs[qid].cqh);
+
+	if (new_head != q->head) {
+		/* bad tail - can't process*/
+		if (!nvme_mdev_mmio_db_check(vctrl, q->qid, q->size, new_head))
+			return;
+
+		while (q->head != new_head) {
+			nvme_mdev_vcq_advance_head(q);
+			WARN_ON_ONCE(q->pending == 0);
+			if (q->pending > 0)
+				q->pending--;
+		}
+
+		eidx = q->head + (q->size >> 1);
+		if (eidx >= q->size)
+			eidx -= q->size;
+		vctrl->mmio.eidxs[q->qid].cqh = cpu_to_le32(eidx);
+	}
+
+	if (q->irq != -1 && trigger_irqs) {
+		if (q->tail != new_head)
+			nvme_mdev_irq_cond_trigger(vctrl, q->irq);
+		else
+			nvme_mdev_irq_clear(vctrl, q->irq);
+	}
+}
+
+/* flush interrupts on a completion queue */
+bool nvme_mdev_vcq_flush(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	u16 new_head = le32_to_cpu(vctrl->mmio.dbs[qid].cqh);
+
+	if (new_head == q->tail || q->irq == -1)
+		return false;
+
+	nvme_mdev_irq_trigger(vctrl, q->irq);
+	nvme_mdev_irq_clear(vctrl, q->irq);
+	return true;
+}
+
+/* Reserve space for one completion entry, that will be added later */
+bool nvme_mdev_vcq_reserve_space(struct nvme_vcq *q)
+{
+	/* TODOLATER: track passed through commmands
+	 * If we pass through a command to host and never receive a response
+	 * we will keep space for response in CQ forever, eventually stalling
+	 * the CQ forever.
+	 * In this case, the guest is still expected to recover by resetting
+	 * our controller
+	 * This can be fixed by tracking all the commands that we send
+	 * to the host
+	 */
+
+	if (q->pending == q->size - 1)
+		return false;
+	q->pending++;
+	return true;
+}
+
+/* Write a new item into the completion queue (IO version) */
+void nvme_mdev_vcq_write_io(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vcq *q, u16 sq_head,
+			    u16 sqid, u16 cid, u16 status)
+{
+	volatile u64 *qw = (__le64 *)(&q->data[q->tail]);
+
+	u64 phase = q->phase ? (0x1ULL << 48) : 0;
+	u64 qw1 =
+		((u64)sq_head) |
+		((u64)sqid << 16) |
+		((u64)cid << 32) |
+		((u64)status << 49) | phase;
+
+	WRITE_ONCE(qw[1], cpu_to_le64(qw1));
+
+	nvme_mdev_vcq_advance_tail(q);
+	if (q->irq != -1)
+		nvme_mdev_irq_raise(vctrl, q->irq);
+}
+
+/* Write a new item into the completion queue (ADMIN version) */
+void nvme_mdev_vcq_write_adm(struct nvme_mdev_vctrl *vctrl,
+			     struct nvme_vcq *q, u32 dw0,
+			     u16 sq_head, u16 cid, u16 status)
+{
+	volatile u64 *qw = (__le64 *)(&q->data[q->tail]);
+
+	u64 phase = q->phase ? (0x1ULL << 48) : 0;
+	u64 qw1 =
+		((u64)sq_head) |
+		((u64)cid << 32) |
+		((u64)status << 49) | phase;
+
+	WRITE_ONCE(qw[0], cpu_to_le64(dw0));
+	/* ensure that hardware sees the phase bit flip last */
+	wmb();
+	WRITE_ONCE(qw[1], cpu_to_le64(qw1));
+
+	nvme_mdev_vcq_advance_tail(q);
+	if (q->irq != -1)
+		nvme_mdev_irq_trigger(vctrl, q->irq);
+}
diff --git a/drivers/nvme/mdev/vctrl.c b/drivers/nvme/mdev/vctrl.c
new file mode 100644
index 000000000000..6f087b8fb2fc
--- /dev/null
+++ b/drivers/nvme/mdev/vctrl.c
@@ -0,0 +1,515 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe controller implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+bool nvme_mdev_vctrl_is_dead(struct nvme_mdev_vctrl *vctrl)
+{
+	return (vctrl->mmio.csts & (NVME_CSTS_CFS | NVME_CSTS_SHST_MASK)) != 0;
+}
+
+/* Setup the controller guid and serial */
+static void nvme_mdev_vctrl_init_id(struct nvme_mdev_vctrl *vctrl)
+{
+	guid_t guid = mdev_uuid(vctrl->mdev);
+
+	snprintf(vctrl->subnqn, sizeof(vctrl->subnqn),
+		 "nqn.2014-08.org.nvmexpress:uuid:%pUl", guid.b);
+
+	snprintf(vctrl->serial, sizeof(vctrl->serial), "%pUl", guid.b);
+}
+
+/* Change the IO thread CPU pinning */
+void nvme_mdev_vctrl_bind_iothread(struct nvme_mdev_vctrl *vctrl,
+				   unsigned int cpu)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (cpu == vctrl->iothread_cpu)
+		goto out;
+
+	nvme_mdev_io_free(vctrl);
+	nvme_mdev_io_create(vctrl, cpu);
+out:
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Change the status of support for shadow doorbell */
+int nvme_mdev_vctrl_set_shadow_doorbell_supported(struct nvme_mdev_vctrl *vctrl,
+						  bool enable)
+{
+	if (vctrl->inuse)
+		return -EBUSY;
+	vctrl->mmio.shadow_db_supported = enable;
+	return 0;
+}
+
+/* Called when memory mapping are changed. Propagate this to all kmap users */
+static void nvme_mdev_vctrl_viommu_update(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 qid;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+		return;
+
+	/* update mappings for submission and completion queues */
+	for_each_set_bit(qid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vsq_viommu_update(&vctrl->viommu, &vctrl->vsqs[qid]);
+
+	for_each_set_bit(qid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vcq_viommu_update(&vctrl->viommu, &vctrl->vcqs[qid]);
+
+	/* update mapping for the shadow doorbells */
+	nvme_mdev_mmio_viommu_update(vctrl);
+}
+
+/* Create a new virtual controller */
+struct nvme_mdev_vctrl *nvme_mdev_vctrl_create(struct mdev_device *mdev,
+					       struct nvme_mdev_hctrl *hctrl,
+					       unsigned int max_host_queues)
+{
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = kzalloc_node(sizeof(*vctrl),
+						     GFP_KERNEL, hctrl->node);
+	if (!vctrl)
+		return ERR_PTR(-ENOMEM);
+
+	/* Basic init */
+	vctrl->hctrl = hctrl;
+	vctrl->mdev = mdev;
+	vctrl->max_host_hw_queues = max_host_queues;
+	vctrl->viommu.vctrl = vctrl;
+
+	kref_init(&vctrl->ref);
+	mutex_init(&vctrl->lock);
+	nvme_mdev_vctrl_init_id(vctrl);
+	INIT_LIST_HEAD(&vctrl->host_hw_queues);
+
+	get_device(mdev_dev(mdev));
+	mdev_set_drvdata(mdev, vctrl);
+
+	/* reserve host IO queues */
+	if (!nvme_mdev_hctrl_hqs_reserve(hctrl, max_host_queues)) {
+		ret = -ENOSPC;
+		goto error1;
+	}
+
+	/* default feature values*/
+	vctrl->arb_burst_shift = 3;
+	vctrl->mmio.shadow_db_supported = use_shadow_doorbell;
+
+	ret = nvme_mdev_pci_create(vctrl);
+	if (ret)
+		goto error2;
+
+	ret = nvme_mdev_mmio_create(vctrl);
+	if (ret)
+		goto error3;
+
+	nvme_mdev_irqs_setup(vctrl);
+
+	/* Create the IO thread */
+	/*TODOLATER: IO: smp_processor_id() is not an ideal pinning choice */
+	ret = nvme_mdev_io_create(vctrl, smp_processor_id());
+	if (ret)
+		goto error4;
+
+	_INFO(vctrl, "device created using %d host queues\n", max_host_queues);
+	return vctrl;
+error4:
+	nvme_mdev_mmio_free(vctrl);
+error3:
+	nvme_mdev_pci_free(vctrl);
+error2:
+	nvme_mdev_hctrl_hqs_unreserve(hctrl, max_host_queues);
+error1:
+	put_device(mdev_dev(mdev));
+	kfree(vctrl);
+	return ERR_PTR(ret);
+}
+
+/*Try to destroy an vctrl */
+int nvme_mdev_vctrl_destroy(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->inuse) {
+		/* vctrl has mdev users */
+		mutex_unlock(&vctrl->lock);
+		return -EBUSY;
+	}
+
+	_INFO(vctrl, "device is destroying\n");
+
+	mdev_set_drvdata(vctrl->mdev, NULL);
+	mutex_unlock(&vctrl->lock);
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_del_init(&vctrl->link);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+
+	mutex_lock(&vctrl->lock); /*only for lockdep checks */
+	nvme_mdev_io_free(vctrl);
+	nvme_mdev_vns_destroy_all(vctrl);
+	__nvme_mdev_vctrl_reset(vctrl, true);
+
+	nvme_mdev_hctrl_hqs_unreserve(vctrl->hctrl, vctrl->max_host_hw_queues);
+
+	nvme_mdev_pci_free(vctrl);
+	nvme_mdev_mmio_free(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+
+	put_device(mdev_dev(vctrl->mdev));
+	_INFO(vctrl, "device is destroyed\n");
+	kfree(vctrl);
+	return 0;
+}
+
+/* Suspends a running virtual controller
+ * Called when host needs to regain full control of the device
+ */
+void nvme_mdev_vctrl_pause(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	if (!vctrl->vctrl_paused) {
+		_INFO(vctrl, "pausing the virtual controller\n");
+		if (vctrl->mmio.csts & NVME_CSTS_RDY)
+			nvme_mdev_io_pause(vctrl);
+		vctrl->vctrl_paused = true;
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Resumes a virtual controller
+ * Called when host done with exclusive access and allows us
+ * again to attach to the controller
+ */
+void nvme_mdev_vctrl_resume(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	if (vctrl->vctrl_paused) {
+		_INFO(vctrl, "resuming the virtual controller\n");
+
+		if (vctrl->mmio.csts & NVME_CSTS_RDY) {
+			/* handle all pending admin commands*/
+			nvme_mdev_adm_process_sq(vctrl);
+			/* start the IO thread again if it was stopped or
+			 * if we had doorbell writes during the pause
+			 */
+			nvme_mdev_io_resume(vctrl);
+		}
+		vctrl->vctrl_paused = false;
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Called when emulator opens the virtual device */
+int nvme_mdev_vctrl_open(struct nvme_mdev_vctrl *vctrl)
+{
+	struct device *dma_dev = NULL;
+	int ret = 0;
+
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->hctrl->removing) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (vctrl->inuse) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	_INFO(vctrl, "device is opened\n");
+
+	if (vctrl->hctrl->nvme_ctrl->ops->flags & NVME_F_MDEV_DMA_SUPPORTED)
+		dma_dev = vctrl->hctrl->nvme_ctrl->dev;
+
+	nvme_mdev_viommu_init(&vctrl->viommu, mdev_dev(vctrl->mdev), dma_dev);
+
+	nvme_mdev_mmio_open(vctrl);
+	vctrl->inuse = true;
+out:
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Called when emulator closes the virtual device */
+void nvme_mdev_vctrl_release(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+
+	/* Remove the guest DMA mappings - new user that will open the
+	 * device might be a different guest
+	 */
+	nvme_mdev_viommu_reset(&vctrl->viommu);
+
+	/* Reset the controller to a clean state for a new user */
+	__nvme_mdev_vctrl_reset(vctrl, false);
+	nvme_mdev_irqs_reset(vctrl);
+	vctrl->inuse = false;
+	mutex_unlock(&vctrl->lock);
+
+	WARN_ON(!list_empty(&vctrl->host_hw_queues));
+
+	_INFO(vctrl, "device is released\n");
+
+	/* If we are released after request to remove the host controller
+	 * we are dead, won't be opened again ever, so remove ourselves
+	 */
+	if (vctrl->hctrl->removing)
+		nvme_mdev_vctrl_destroy(vctrl);
+}
+
+/* Called each time the controller is reset (CC.EN <= 0 or VM level reset) */
+void __nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if ((vctrl->mmio.csts & NVME_CSTS_RDY) &&
+	    !(vctrl->mmio.csts & NVME_CSTS_SHST_MASK)) {
+		_DBG(vctrl, "unsafe reset (CSTS.RDY==1)\n");
+		nvme_mdev_io_pause(vctrl);
+		nvme_mdev_vctrl_disable(vctrl);
+	}
+	nvme_mdev_mmio_reset(vctrl, pci_reset);
+}
+
+/* setups initial admin queues and doorbells */
+bool nvme_mdev_vctrl_enable(struct nvme_mdev_vctrl *vctrl,
+			    dma_addr_t cqiova, dma_addr_t sqiova, u32 sizes)
+{
+	int ret;
+	u16 cqentries, sqentries;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	lockdep_assert_held(&vctrl->lock);
+
+	sqentries = (sizes & 0xFFFF) + 1;
+	cqentries = (sizes >> 16) + 1;
+
+	if (cqentries > 4096 || cqentries < 2)
+		return false;
+	if (sqentries > 4096 || sqentries < 2)
+		return false;
+
+	ret = nvme_mdev_mmio_enable_dbs(vctrl);
+	if (ret)
+		goto error0;
+
+	ret = nvme_mdev_vcq_init(vctrl, 0, cqiova, true, cqentries, 0);
+	if (ret)
+		goto error1;
+
+	ret = nvme_mdev_vsq_init(vctrl, 0, sqiova, true, sqentries, 0);
+	if (ret)
+		goto error2;
+
+	nvme_mdev_events_init(vctrl);
+
+	if (!vctrl->mmio.shadow_db_supported) {
+		/* start polling right away to support admin queue */
+		vctrl->io_idle = false;
+		nvme_mdev_io_resume(vctrl);
+	}
+
+	return true;
+error2:
+	nvme_mdev_mmio_disable_dbs(vctrl);
+error1:
+	nvme_mdev_vcq_delete(vctrl, 0);
+error0:
+	return false;
+}
+
+/* destroy all io/admin queues on the controller  */
+void nvme_mdev_vctrl_disable(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 sqid, cqid;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	lockdep_assert_held(&vctrl->lock);
+
+	nvme_mdev_events_reset(vctrl);
+	nvme_mdev_vns_log_reset(vctrl);
+
+	sqid = 1;
+	for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vsq_delete(vctrl, sqid);
+
+	cqid = 1;
+	for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vcq_delete(vctrl, cqid);
+
+	nvme_mdev_vsq_delete(vctrl, 0);
+	nvme_mdev_vcq_delete(vctrl, 0);
+
+	nvme_mdev_mmio_disable_dbs(vctrl);
+	vctrl->io_idle = true;
+}
+
+/* External reset */
+void nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	_INFO(vctrl, "reset\n");
+	__nvme_mdev_vctrl_reset(vctrl, true);
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Add IO region*/
+void nvme_mdev_vctrl_add_region(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index, unsigned int size,
+				region_access_fn access_fn)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->size = size;
+	region->rw = access_fn;
+	region->mmap_ops = NULL;
+}
+
+/* Enable mmap window on an IO region */
+void nvme_mdev_vctrl_region_set_mmap(struct nvme_mdev_vctrl *vctrl,
+				     unsigned int index,
+				     unsigned int offset,
+				     unsigned int size,
+				     const struct vm_operations_struct *ops)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->mmap_area_start = offset;
+	region->mmap_area_size = size;
+	region->mmap_ops = ops;
+}
+
+/* Disable mmap window on an IO region */
+void nvme_mdev_vctrl_region_disable_mmap(struct nvme_mdev_vctrl *vctrl,
+					 unsigned int index)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->mmap_area_start = 0;
+	region->mmap_area_size = 0;
+	region->mmap_ops = NULL;
+}
+
+/* Allocate a host IO queue */
+int nvme_mdev_vctrl_hq_alloc(struct nvme_mdev_vctrl *vctrl)
+{
+	struct nvme_mdev_hq *hq = NULL, *tmp;
+	int hwqcount = 0, ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	list_for_each_entry(tmp, &vctrl->host_hw_queues, link) {
+		if (!hq || tmp->usecount < hq->usecount)
+			hq = tmp;
+		hwqcount++;
+	}
+
+	if (hwqcount < vctrl->max_host_hw_queues) {
+		ret = nvme_mdev_hctrl_hq_alloc(vctrl->hctrl);
+		if (ret < 0)
+			return ret;
+
+		hq = kzalloc_node(sizeof(*hq), GFP_KERNEL, vctrl->hctrl->node);
+		if (!hq) {
+			nvme_mdev_hctrl_hq_free(vctrl->hctrl, ret);
+			return -ENOMEM;
+		}
+
+		hq->hqid = ret;
+		hq->usecount = 1;
+		list_add_tail(&hq->link, &vctrl->host_hw_queues);
+	} else {
+		hq->usecount++;
+	}
+	return hq->hqid;
+}
+
+/* Free a host IO queue */
+void nvme_mdev_vctrl_hq_free(struct nvme_mdev_vctrl *vctrl, u16 hqid)
+{
+	struct nvme_mdev_hq *hq;
+
+	lockdep_assert_held(&vctrl->lock);
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	list_for_each_entry(hq, &vctrl->host_hw_queues, link)
+		if (hq->hqid == hqid) {
+			if (--hq->usecount > 0)
+				return;
+			nvme_mdev_hctrl_hq_free(vctrl->hctrl, hq->hqid);
+			list_del(&hq->link);
+			kfree(hq);
+			return;
+		}
+	WARN_ON(1);
+}
+
+/* get current list of host queues */
+unsigned int nvme_mdev_vctrl_hqs_list(struct nvme_mdev_vctrl *vctrl, u16 *out)
+{
+	struct nvme_mdev_hq *q;
+	unsigned int i = 0;
+
+	list_for_each_entry(q, &vctrl->host_hw_queues, link) {
+		out[i++] = q->hqid;
+		if (WARN_ON(i > MAX_HOST_QUEUES))
+			break;
+	}
+	return i;
+}
+
+/* add a user memory mapping */
+int nvme_mdev_vctrl_viommu_map(struct nvme_mdev_vctrl *vctrl, u32 flags,
+			       dma_addr_t iova, u64 size)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+
+	nvme_mdev_io_pause(vctrl);
+	ret = nvme_mdev_viommu_add(&vctrl->viommu, flags, iova, size);
+	nvme_mdev_vctrl_viommu_update(vctrl);
+	nvme_mdev_io_resume(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* remove a user memory mapping */
+int nvme_mdev_vctrl_viommu_unmap(struct nvme_mdev_vctrl *vctrl,
+				 dma_addr_t iova, u64 size)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+
+	nvme_mdev_io_pause(vctrl);
+	ret = nvme_mdev_viommu_remove(&vctrl->viommu, iova, size);
+	nvme_mdev_vctrl_viommu_update(vctrl);
+	nvme_mdev_io_resume(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
diff --git a/drivers/nvme/mdev/viommu.c b/drivers/nvme/mdev/viommu.c
new file mode 100644
index 000000000000..31b86e8f5768
--- /dev/null
+++ b/drivers/nvme/mdev/viommu.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual IOMMU - mapping user memory to the real device
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/vmalloc.h>
+#include <linux/nvme.h>
+#include <linux/iommu.h>
+#include <linux/interval_tree_generic.h>
+#include "priv.h"
+
+struct mem_mapping {
+	struct rb_node rb;
+	struct list_head link;
+
+	dma_addr_t __subtree_last;
+	dma_addr_t iova_start; /* first iova in this mapping*/
+	dma_addr_t iova_last;  /* last iova in this mapping*/
+
+	unsigned long pfn;  /* physical address of this mapping */
+	dma_addr_t host_iova;  /* dma mapping to the real device*/
+};
+
+#define map_len(m) (((m)->iova_last - (m)->iova_start) + 1ULL)
+#define map_pages(m) (map_len(m) >> PAGE_SHIFT)
+#define START(node) ((node)->iova_start)
+#define LAST(node) ((node)->iova_last)
+
+INTERVAL_TREE_DEFINE(struct mem_mapping, rb, dma_addr_t, __subtree_last,
+		     START, LAST, static inline, viommu_int_tree);
+
+static void nvme_mdev_viommu_dbg_dma_range(struct nvme_mdev_viommu *viommu,
+					   struct mem_mapping *map,
+					   const char *action)
+{
+	dma_addr_t iova_start  = map->iova_start;
+	dma_addr_t iova_end    = map->iova_start + map_len(map) - 1;
+	dma_addr_t hiova_start = map->host_iova;
+	dma_addr_t hiova_end   = map->host_iova  + map_len(map) - 1;
+
+	_DBG(viommu->vctrl,
+	     "vIOMMU: %s RW IOVA %pad-%pad -> DMA %pad-%pad\n",
+	     action, &iova_start, &iova_end, &hiova_start, &hiova_end);
+}
+
+/* unpin N pages starting at given IOVA*/
+static void nvme_mdev_viommu_unpin_pages(struct nvme_mdev_viommu *viommu,
+					 dma_addr_t iova, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		unsigned long  user_pfn = (iova >> PAGE_SHIFT) + i;
+		int ret = vfio_unpin_pages(viommu->sw_dev, &user_pfn, 1);
+
+		WARN_ON(ret != 1);
+	}
+}
+
+/* User memory init code*/
+void nvme_mdev_viommu_init(struct nvme_mdev_viommu *viommu,
+			   struct device *sw_dev,
+			   struct device *hw_dev)
+{
+	viommu->sw_dev = sw_dev;
+	viommu->hw_dev = hw_dev;
+	viommu->maps_tree = RB_ROOT_CACHED;
+	INIT_LIST_HEAD(&viommu->maps_list);
+}
+
+/* User memory end code*/
+void nvme_mdev_viommu_reset(struct nvme_mdev_viommu *viommu)
+{
+	nvme_mdev_viommu_remove(viommu, 0, 0xFFFFFFFFFFFFFFFFULL);
+	WARN_ON(!list_empty(&viommu->maps_list));
+}
+
+/* Adds a new range of user memory*/
+int nvme_mdev_viommu_add(struct nvme_mdev_viommu *viommu,
+			 u32 flags,
+			 dma_addr_t iova,
+			 u64 size)
+{
+	u64 offset;
+	dma_addr_t iova_end = iova + size - 1;
+	struct mem_mapping *map = NULL, *tmp;
+	LIST_HEAD(new_mappings_list);
+	int ret;
+
+	if (!(flags & VFIO_DMA_MAP_FLAG_READ) ||
+	    !(flags & VFIO_DMA_MAP_FLAG_WRITE)) {
+		const char *type = "none";
+
+		if (flags & VFIO_DMA_MAP_FLAG_READ)
+			type = "RO";
+		else if (flags & VFIO_DMA_MAP_FLAG_WRITE)
+			type = "WO";
+
+		_DBG(viommu->vctrl, "vIOMMU: IGN %s IOVA %pad-%pad\n",
+		     type, &iova, &iova_end);
+		return 0;
+	}
+
+	WARN_ON_ONCE(nvme_mdev_viommu_remove(viommu, iova, size) != 0);
+
+	if (WARN_ON_ONCE(size & ~PAGE_MASK))
+		return -EINVAL;
+
+	// VFIO pinning all the pages
+	for (offset = 0; offset < size; offset += PAGE_SIZE) {
+		unsigned long vapfn = ((iova + offset) >> PAGE_SHIFT), pa_pfn;
+
+		ret = vfio_pin_pages(viommu->sw_dev,
+				     &vapfn, 1,
+				     VFIO_DMA_MAP_FLAG_READ |
+				     VFIO_DMA_MAP_FLAG_WRITE,
+				     &pa_pfn);
+
+		if (ret != 1) {
+			/*sadly mdev api doesn't return an error*/
+			ret = -EFAULT;
+
+			_DBG(viommu->vctrl,
+			     "vIOMMU: ADD RW IOVA %pad - pin failed\n",
+			     &iova);
+			goto unwind;
+		}
+
+		// new mapping needed
+		if (!map || map->pfn + map_pages(map) != pa_pfn) {
+			int node = viommu->hw_dev ?
+				dev_to_node(viommu->hw_dev) : NUMA_NO_NODE;
+
+			map = kzalloc_node(sizeof(*map), GFP_KERNEL, node);
+
+			if (WARN_ON(!map)) {
+				vfio_unpin_pages(viommu->sw_dev, &vapfn, 1);
+				ret = -ENOMEM;
+				goto unwind;
+			}
+			map->iova_start = iova + offset;
+			map->iova_last = iova + offset + PAGE_SIZE - 1ULL;
+			map->pfn = pa_pfn;
+			map->host_iova = 0;
+			list_add_tail(&map->link, &new_mappings_list);
+		} else {
+			// current map can be extended
+			map->iova_last += PAGE_SIZE;
+		}
+	}
+
+	// DMA mapping the pages
+	list_for_each_entry_safe(map, tmp, &new_mappings_list, link) {
+		if (viommu->hw_dev) {
+			map->host_iova =
+				dma_map_page(viommu->hw_dev,
+					     pfn_to_page(map->pfn),
+					     0,
+					     map_len(map),
+					     DMA_BIDIRECTIONAL);
+
+			ret = dma_mapping_error(viommu->hw_dev, map->host_iova);
+			if (ret) {
+				_DBG(viommu->vctrl,
+				     "vIOMMU: ADD RW IOVA %pad-%pad - DMA map failed\n",
+				     &iova, &iova_end);
+				goto unwind;
+			}
+		}
+
+		nvme_mdev_viommu_dbg_dma_range(viommu, map, "ADD");
+		list_del(&map->link);
+		list_add_tail(&map->link, &viommu->maps_list);
+		viommu_int_tree_insert(map, &viommu->maps_tree);
+	}
+	return 0;
+unwind:
+	list_for_each_entry_safe(map, tmp, &new_mappings_list, link) {
+		nvme_mdev_viommu_unpin_pages(viommu, map->iova_start,
+					     map_pages(map));
+
+		list_del(&map->link);
+		kfree(map);
+	}
+	nvme_mdev_viommu_remove(viommu, iova, size);
+	return ret;
+}
+
+/* Removes a  range of user memory*/
+int nvme_mdev_viommu_remove(struct nvme_mdev_viommu *viommu,
+			    dma_addr_t iova,
+			    u64 size)
+{
+	struct mem_mapping *map = NULL, *tmp;
+	dma_addr_t last_iova = iova + (size) - 1ULL;
+	LIST_HEAD(remove_list);
+	int count = 0;
+
+	/* find out all the relevant ranges */
+	map = viommu_int_tree_iter_first(&viommu->maps_tree, iova, last_iova);
+	while (map) {
+		list_del(&map->link);
+		list_add_tail(&map->link, &remove_list);
+		map = viommu_int_tree_iter_next(map, iova, last_iova);
+	}
+
+	/* remove them */
+	list_for_each_entry_safe(map, tmp, &remove_list, link) {
+		count++;
+
+		nvme_mdev_viommu_dbg_dma_range(viommu, map, "DEL");
+		if (viommu->hw_dev)
+			dma_unmap_page(viommu->hw_dev, map->host_iova,
+				       map_len(map), DMA_BIDIRECTIONAL);
+
+		nvme_mdev_viommu_unpin_pages(viommu, map->iova_start,
+					     map_pages(map));
+
+		viommu_int_tree_remove(map, &viommu->maps_tree);
+		kfree(map);
+	}
+	return count;
+}
+
+/* Translate an IOVA to a physical address and read device bus address */
+int nvme_mdev_viommu_translate(struct nvme_mdev_viommu *viommu,
+			       dma_addr_t iova,
+			       dma_addr_t *physical,
+			       dma_addr_t *host_iova)
+{
+	struct mem_mapping *mapping;
+	u64 offset;
+
+	if (WARN_ON_ONCE(OFFSET_IN_PAGE(iova) != 0))
+		return -EINVAL;
+
+	mapping = viommu_int_tree_iter_first(&viommu->maps_tree,
+					     iova, iova + PAGE_SIZE - 1);
+	if (!mapping) {
+		_DBG(viommu->vctrl,
+		     "vIOMMU: translation of IOVA %pad failed\n", &iova);
+		return -EFAULT;
+	}
+
+	WARN_ON(iova > mapping->iova_last);
+	WARN_ON(OFFSET_IN_PAGE(mapping->iova_start) != 0);
+
+	offset = iova - mapping->iova_start;
+	*physical = PFN_PHYS(mapping->pfn) + offset;
+	*host_iova = mapping->host_iova + offset;
+	return 0;
+}
+
+/* map an IOVA to kernel address space  */
+int nvme_mdev_viommu_create_kmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova, struct page_map *page)
+{
+	dma_addr_t host_iova;
+	phys_addr_t physical;
+	struct page *new_page;
+	int ret;
+
+	page->iova = iova;
+
+	ret = nvme_mdev_viommu_translate(viommu, iova, &physical, &host_iova);
+	if (ret)
+		return ret;
+
+	new_page = pfn_to_page(PHYS_PFN(physical));
+
+	page->kmap = kmap(new_page);
+	if (!page->kmap)
+		return -ENOMEM;
+
+	page->page = new_page;
+	return 0;
+}
+
+/* update IOVA <-> kernel mapping. If fails, removes the previous mapping */
+void nvme_mdev_viommu_update_kmap(struct nvme_mdev_viommu *viommu,
+				  struct page_map *page)
+{
+	dma_addr_t host_iova;
+	phys_addr_t physical;
+	struct page *new_page;
+	int ret;
+
+	ret = nvme_mdev_viommu_translate(viommu, page->iova,
+					 &physical, &host_iova);
+	if (ret) {
+		nvme_mdev_viommu_free_kmap(viommu, page);
+		return;
+	}
+
+	new_page = pfn_to_page(PHYS_PFN(physical));
+	if (new_page == page->page)
+		return;
+
+	nvme_mdev_viommu_free_kmap(viommu, page);
+
+	page->kmap = kmap(new_page);
+	if (!page->kmap)
+		return;
+	page->page = new_page;
+}
+
+/* unmap an IOVA to kernel address space  */
+void nvme_mdev_viommu_free_kmap(struct nvme_mdev_viommu *viommu,
+				struct page_map *page)
+{
+	if (page->page) {
+		kunmap(page->page);
+		page->page = NULL;
+		page->kmap = NULL;
+	}
+}
diff --git a/drivers/nvme/mdev/vns.c b/drivers/nvme/mdev/vns.c
new file mode 100644
index 000000000000..42d4f8d7423b
--- /dev/null
+++ b/drivers/nvme/mdev/vns.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe namespace implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+/* Reset the changed namespace log */
+void nvme_mdev_vns_log_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	vctrl->ns_log_size = 0;
+}
+
+/* This adds entry to NS changed log and sends to the user a notification */
+static void nvme_mdev_vns_send_event(struct nvme_mdev_vctrl *vctrl, u32 ns)
+{
+	unsigned int i;
+	unsigned int log_size = vctrl->ns_log_size;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	_INFO(vctrl, "host namespace list rescanned\n");
+
+	if (WARN_ON(ns == 0 || ns > MAX_VIRTUAL_NAMESPACES))
+		return;
+
+	// check if the namespace ID is alredy in the log
+	if (log_size == MAX_VIRTUAL_NAMESPACES)
+		return;
+
+	for (i = 0; i < log_size; i++)
+		if (vctrl->ns_log[i] == cpu_to_le32(ns))
+			return;
+
+	vctrl->ns_log[log_size++] = cpu_to_le32(ns);
+	vctrl->ns_log_size++;
+	nvme_mdev_event_send(vctrl, NVME_AER_TYPE_NOTICE,
+			     NVME_AER_NOTICE_NS_CHANGED);
+}
+
+/* Read host NS/partition parameters to update our virtual NS */
+static void nvme_mdev_vns_read_host_properties(struct nvme_mdev_vctrl *vctrl,
+					       struct nvme_mdev_vns *vns,
+					       struct nvme_ns *host_ns)
+{
+	unsigned int sector_to_lba_shift;
+	u64 host_ns_size, start, nr, align_mask;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	/* read the namespace block size */
+	vns->blksize_shift = host_ns->lba_shift;
+
+	if (WARN_ON(vns->blksize_shift < 9)) {
+		_WARN(vctrl, "NS/create: device block size is bad\n");
+		goto error;
+	}
+
+	sector_to_lba_shift = vns->blksize_shift - 9;
+	align_mask = (1ULL << sector_to_lba_shift) - 1;
+
+	/* read the partition start and size*/
+	start = get_start_sect(vns->host_part);
+	nr = part_nr_sects_read(vns->host_part->bd_part);
+
+	/* check that partition is aligned on LBA size*/
+	if (sector_to_lba_shift != 0) {
+		if ((start & align_mask) || (nr & align_mask)) {
+			_WARN(vctrl, "NS/create: partition not aligned\n");
+			goto error;
+		}
+	}
+
+	vns->host_lba_offset = start >> sector_to_lba_shift;
+	vns->ns_size = nr >> sector_to_lba_shift;
+	host_ns_size = get_capacity(host_ns->disk) >> sector_to_lba_shift;
+
+	/*TODOLATER: NS: support metadata on host namespace */
+	if (host_ns->ms) {
+		_WARN(vctrl, "NS/create: no support for namespace metadata\n");
+		goto error;
+	}
+
+	if (vns->ns_size == 0) {
+		_WARN(vctrl, "NS/create: host namespace has size 0\n");
+		goto error;
+	}
+
+	/* sanity check that partition doesn't extend beyond the namespace */
+	if (!check_range(vns->host_lba_offset, vns->ns_size, host_ns_size)) {
+		_WARN(vctrl, "NS/create: host namespace size mismatch\n");
+		goto error;
+	}
+
+	/* check if namespace is readonly*/
+	if (!vns->readonly)
+		vns->readonly = get_disk_ro(host_ns->disk);
+
+	vns->noiob = host_ns->noiob;
+	if (vns->noiob != 0) {
+		u64 tmp = vns->host_lba_offset;
+
+		if (do_div(tmp, vns->noiob)) {
+			_WARN(vctrl,
+			      "NS/create: host partition is not aligned on host optimum IO boundary, performance might suffer");
+			vns->noiob = 0;
+		}
+	}
+	return;
+error:
+	vns->ns_size = 0;
+}
+
+/* Open new reference to a host namespace */
+int nvme_mdev_vns_open(struct nvme_mdev_vctrl *vctrl,
+		       u32 host_nsid, unsigned int host_partid)
+{
+	struct nvme_mdev_vns *vns;
+	u32 user_nsid;
+	int ret;
+
+	_INFO(vctrl, "open host_namespace=%u, partition=%u\n",
+	      host_nsid, host_partid);
+
+	mutex_lock(&vctrl->lock);
+	ret = -ENODEV;
+	if (nvme_mdev_vctrl_is_dead(vctrl))
+		goto out;
+
+	/* create the namespace object */
+	ret = -ENOMEM;
+	vns = kzalloc_node(sizeof(*vns), GFP_KERNEL, vctrl->hctrl->node);
+	if (!vns)
+		goto out;
+
+	uuid_gen(&vns->uuid); // TODOLATER: NS: non random NS UUID
+	vns->host_nsid = host_nsid;
+	vns->host_partid = host_partid;
+
+	/* find the host namespace */
+	vns->host_ns = nvme_find_get_ns(vctrl->hctrl->nvme_ctrl, host_nsid);
+	if (!vns->host_ns) {
+		ret = -ENODEV;
+		goto error1;
+	}
+
+	if (test_bit(NVME_NS_DEAD, &vns->host_ns->flags) ||
+	    test_bit(NVME_NS_REMOVING, &vns->host_ns->flags) ||
+	    !vns->host_ns->disk) {
+		ret = -ENODEV;
+		goto error2;
+	}
+
+	/* get the block device for the partition that we will use */
+	vns->host_part = bdget_disk(vns->host_ns->disk, host_partid);
+	if (!vns->host_part) {
+		ret = -ENODEV;
+		goto error2;
+	}
+
+	/* get exclusive access to the block device (partition) */
+	vns->fmode = FMODE_READ | FMODE_EXCL;
+	if (!vns->readonly)
+		vns->fmode |= FMODE_WRITE;
+
+	ret = blkdev_get(vns->host_part, vns->fmode, vns);
+	if (ret)
+		goto error2;
+
+	/* read properties of the host namespace */
+	nvme_mdev_vns_read_host_properties(vctrl, vns, vns->host_ns);
+
+	/* Allocate a user namespace ID for this namespace */
+	ret = -ENOSPC;
+	for (user_nsid = 1; user_nsid <= MAX_VIRTUAL_NAMESPACES; user_nsid++)
+		if (!nvme_mdev_vns_from_vnsid(vctrl, user_nsid))
+			break;
+
+	if (user_nsid > MAX_VIRTUAL_NAMESPACES)
+		goto error3;
+
+	nvme_mdev_io_pause(vctrl);
+
+	vctrl->namespaces[user_nsid - 1] = vns;
+	vns->nsid = user_nsid;
+
+	/* Announce the new namespace to the user */
+	nvme_mdev_vns_send_event(vctrl, user_nsid);
+	nvme_mdev_io_resume(vctrl);
+	ret = 0;
+	goto out;
+error3:
+	blkdev_put(vns->host_part, vns->fmode);
+error2:
+	nvme_put_ns(vns->host_ns);
+error1:
+	kfree(vns);
+out:
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Re-open new reference to a host namespace, after notification
+ * of change in the host namespace
+ */
+static bool nvme_mdev_vns_reopen(struct nvme_mdev_vctrl *vctrl,
+				 struct nvme_mdev_vns *vns)
+{
+	struct nvme_ns *host_ns;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	_INFO(vctrl, "reopen host namespace %u, partition=%u\n",
+	      vns->host_nsid, vns->host_partid);
+
+	/* namespace disappeared on the host - invalid*/
+	host_ns = nvme_find_get_ns(vctrl->hctrl->nvme_ctrl, vns->host_nsid);
+	if (!host_ns)
+		return false;
+
+	/* different namespace with same ID on the host - invalid*/
+	if (vns->host_ns != host_ns)
+		goto error1;
+
+	// basic checks on the namespace
+	if (test_bit(NVME_NS_DEAD, &host_ns->flags) ||
+	    test_bit(NVME_NS_REMOVING, &host_ns->flags) ||
+	    !host_ns->disk)
+		goto error1;
+
+	/* read properties of the host namespace */
+	nvme_mdev_io_pause(vctrl);
+	nvme_mdev_vns_read_host_properties(vctrl, vns, host_ns);
+	nvme_mdev_io_resume(vctrl);
+
+	nvme_put_ns(host_ns);
+	return true;
+error1:
+	nvme_put_ns(host_ns);
+	return false;
+}
+
+/* Destroy a virtual namespace*/
+static int __nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl, u32 user_nsid)
+{
+	struct nvme_mdev_vns *vns;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	vns = nvme_mdev_vns_from_vnsid(vctrl, user_nsid);
+	if (!vns)
+		return -ENODEV;
+
+	nvme_mdev_vns_send_event(vctrl, user_nsid);
+	nvme_mdev_io_pause(vctrl);
+
+	vctrl->namespaces[user_nsid - 1] = NULL;
+	blkdev_put(vns->host_part, vns->fmode);
+	nvme_put_ns(vns->host_ns);
+	kfree(vns);
+	nvme_mdev_io_resume(vctrl);
+	return 0;
+}
+
+/* Destroy a virtual namespace (external interface) */
+int nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl, u32 user_nsid)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+	ret = __nvme_mdev_vns_destroy(vctrl, user_nsid);
+	nvme_mdev_io_resume(vctrl);
+	mutex_unlock(&vctrl->lock);
+
+	return ret;
+}
+
+/* Destroy all virtual namespaces */
+void nvme_mdev_vns_destroy_all(struct nvme_mdev_vctrl *vctrl)
+{
+	u32 user_nsid;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	for (user_nsid = 1 ; user_nsid <= MAX_VIRTUAL_NAMESPACES ; user_nsid++)
+		__nvme_mdev_vns_destroy(vctrl, user_nsid);
+}
+
+/* Get a virtual namespace */
+struct nvme_mdev_vns *nvme_mdev_vns_from_vnsid(struct nvme_mdev_vctrl *vctrl,
+					       u32 user_ns_id)
+{
+	if (user_ns_id == 0 || user_ns_id > MAX_VIRTUAL_NAMESPACES)
+		return NULL;
+	return vctrl->namespaces[user_ns_id - 1];
+}
+
+/* Print description off all virtual namespaces */
+int nvme_mdev_vns_print_description(struct nvme_mdev_vctrl *vctrl,
+				    char *buf, unsigned int size)
+{
+	int nsid, ret = 0;
+
+	mutex_lock(&vctrl->lock);
+
+	for (nsid = 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++) {
+		int n;
+		struct nvme_mdev_vns *vns = nvme_mdev_vns_from_vnsid(vctrl,
+				nsid);
+		if (!vns)
+			continue;
+
+		else if (vns->host_partid == 0)
+			n = snprintf(buf, size, "VNS%d: nvme%dn%d\n",
+				     nsid, vctrl->hctrl->id,
+				     (int)vns->host_nsid);
+		else
+			n = snprintf(buf, size, "VNS%d: nvme%dn%dp%d\n",
+				     nsid, vctrl->hctrl->id,
+				     (int)vns->host_nsid,
+				     (int)vns->host_partid);
+		if (n > size)
+			return -ENOMEM;
+		buf += n;
+		size -= n;
+		ret += n;
+	}
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Processes an update on the host namespace */
+void nvme_mdev_vns_host_ns_update(struct nvme_mdev_vctrl *vctrl,
+				  u32 host_nsid, bool removed)
+{
+	int nsid;
+
+	mutex_lock(&vctrl->lock);
+
+	for (nsid = 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++) {
+		struct nvme_mdev_vns *vns = nvme_mdev_vns_from_vnsid(vctrl,
+								     nsid);
+		if (!vns || vns->host_nsid != host_nsid)
+			continue;
+
+		if (removed || !nvme_mdev_vns_reopen(vctrl, vns))
+			__nvme_mdev_vns_destroy(vctrl, nsid);
+		else
+			nvme_mdev_vns_send_event(vctrl, nsid);
+	}
+	mutex_unlock(&vctrl->lock);
+}
diff --git a/drivers/nvme/mdev/vsq.c b/drivers/nvme/mdev/vsq.c
new file mode 100644
index 000000000000..5b63081c144d
--- /dev/null
+++ b/drivers/nvme/mdev/vsq.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe submission queue implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include "priv.h"
+
+/* Create new virtual completion queue */
+int nvme_mdev_vsq_init(struct nvme_mdev_vctrl *vctrl,
+		       u16 qid, dma_addr_t iova, bool cont, u16 size, u16 cqid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[qid];
+	int ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	q->iova = iova;
+	q->cont = cont;
+	q->qid = qid;
+	q->size = size;
+	q->head = 0;
+	q->vcq = &vctrl->vcqs[cqid];
+	q->data = NULL;
+	q->hsq = 0;
+
+	ret = nvme_mdev_vsq_viommu_update(&vctrl->viommu, q);
+	if (ret && (ret != -EFAULT))
+		return ret;
+
+	if (qid > 0) {
+		ret = nvme_mdev_vctrl_hq_alloc(vctrl);
+		if (ret < 0) {
+			vunmap(q->data);
+			return ret;
+		}
+		q->hsq = ret;
+	}
+
+	_DBG(vctrl, "VSQ: create qid=%d contig=%d, depth=%d cqid=%d\n",
+	     qid, cont, size, cqid);
+
+	set_bit(qid, vctrl->vsq_en);
+
+	vctrl->mmio.dbs[q->qid].sqt = 0;
+	vctrl->mmio.eidxs[q->qid].sqt = 0;
+
+	return 0;
+}
+
+/* Update the kernel mapping of the queue */
+int nvme_mdev_vsq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vsq *q)
+{
+	void *data;
+
+	if (q->data)
+		vunmap((void *)q->data);
+
+	data = nvme_mdev_udata_queue_vmap(viommu, q->iova,
+					  (unsigned int)q->size *
+					  sizeof(struct nvme_command),
+					  q->cont);
+
+	q->data = IS_ERR(data) ? NULL : data;
+	return IS_ERR(data) ? PTR_ERR(data) : 0;
+}
+
+/* Delete an virtual completion queue */
+void nvme_mdev_vsq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[qid];
+
+	lockdep_assert_held(&vctrl->lock);
+	_DBG(vctrl, "VSQ: delete qid=%d\n", q->qid);
+
+	if (q->data)
+		vunmap(q->data);
+	q->data = NULL;
+
+	if (q->hsq) {
+		nvme_mdev_vctrl_hq_free(vctrl, q->hsq);
+		q->hsq = 0;
+	}
+
+	clear_bit(qid, vctrl->vsq_en);
+}
+
+/* Move queue head one item forward */
+static void nvme_mdev_vsq_advance_head(struct nvme_vsq *q)
+{
+	q->head++;
+	if (q->head == q->size)
+		q->head = 0;
+}
+
+bool nvme_mdev_vsq_has_data(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vsq *q)
+{
+	u16 tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data)
+		return false;
+
+	if  (tail == q->head)
+		return false;
+
+	if (!nvme_mdev_mmio_db_check(vctrl, q->qid, q->size, tail))
+		return false;
+	return true;
+}
+
+/* get one command from a virtual submission queue */
+const struct nvme_command *nvme_mdev_vsq_get_cmd(struct nvme_mdev_vctrl *vctrl,
+						 struct nvme_vsq *q)
+{
+	u16 oldhead = q->head;
+	u32 eidx;
+
+	if (!nvme_mdev_vsq_has_data(vctrl, q))
+		return NULL;
+	if (!nvme_mdev_vcq_reserve_space(q->vcq))
+		return NULL;
+	nvme_mdev_vsq_advance_head(q);
+
+	eidx = q->head + (q->size >> 1);
+	if (eidx >= q->size)
+		eidx -= q->size;
+
+	vctrl->mmio.eidxs[q->qid].sqt = cpu_to_le32(eidx);
+
+	return &q->data[oldhead];
+}
+
+bool nvme_mdev_vsq_suspend_io(struct nvme_mdev_vctrl *vctrl, u16 sqid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[sqid];
+	u16 tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+
+	/* If the queue is not in working state don't allow the idle code
+	 * to kick in
+	 */
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data)
+		return false;
+
+	/* queue has data - refuse idle*/
+	if (tail != q->head)
+		return false;
+
+	/* Write eventid to tell the user to ring normal doorbell*/
+	vctrl->mmio.eidxs[q->qid].sqt = cpu_to_le32(q->head);
+
+	/* memory barrier to ensure that the user have seen the eidx */
+	mb();
+
+	/* Check that doorbell diddn't move meanwhile */
+	tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+	return (tail == q->head);
+}
+
+/* complete a command (IO version)*/
+void nvme_mdev_vsq_cmd_done_io(struct nvme_mdev_vctrl *vctrl,
+			       u16 sqid, u16 cid, u16 status)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[sqid];
+
+	nvme_mdev_vcq_write_io(vctrl, q->vcq, q->head, q->qid, cid, status);
+}
+
+/* complete a command (ADMIN version)*/
+void nvme_mdev_vsq_cmd_done_adm(struct nvme_mdev_vctrl *vctrl,
+				u32 dw0, u16 cid, u16 status)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[0];
+
+	nvme_mdev_vcq_write_adm(vctrl, q->vcq, dw0, q->head, cid, status);
+}
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 8/9] nvme/core: add nvme-mdev core driver
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

This is main commit in the series, adding the mediated nvme
driver.

The idea behind this driver is based on paper you can find at
https://www.usenix.org/conference/atc18/presentation/peng
But this is an independent implementation.

This mdev device exposes a NVME 1.3 virtual device to any VFIO user
which represents an partition (or whole namespace) of a host NVME device.

Unlike the paper, the driver/device uses
one polling thread per mediated device,
and only needs one hw queue per it to achieve near native performance
(but can use more that one hw queue, in which case it splits the queues
between virtual nvme queues thus supporting n:m mapping between
host hw queues and the guest virtual queues).

The nvme-mdev can't yet be used after this commit, as no nvme device
drivers support mediation (support is added in the next commit to
nvme-pci)

The driver can use the shadow doorbell nvme optional feature,
to stop polling after a timeout.

Currently the device has redhat	pci vendor ID, and 0x1234 pci device id,
which is only a	placeholder till a real	device id is allocated.

Use example:

# load the nvme-mdev driver
$ modprobe nvme-mdev

# load the nvme pci driver with 4 polling queues reserved
# (will work with the next patch)
$ modprobe nvme mdev_queues=4


# generate random UUID for the mediated device
$ UUID=$(uuidgen)
$ MDEV_DEVICE=/sys/bus/mdev/devices/$UUID

# the location of the real nvme device (replace with yours)
$ PCI_DEVICE=/sys/bus/pci/devices/0000:44:00.0

# create the mediated device using 2 host polling queues
$ echo $UUID > $PCI_DEVICE/mdev_supported_types/nvme-2Q_V1/create

# attach partition 1 of namespace 1 to a free virtual namespace
# (use n1 to attach whole namespace)
# you can attach up to 16 virtual namespaces for now
$ echo n1p1 > $MDEV_DEVICE/namespaces/add_namespace

# move the polling thread to cpu 11
$ echo 11 > $MDEV_DEVICE/settings/iothread_cpu

# now you can boot qemu with
#  -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID

Note that you can attach and detach virtual namespaces
even while the guest is running which will make the
device sent namespace changed AEN notifications to the guest
prior to attach/detach action.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 MAINTAINERS                  |   5 +
 drivers/nvme/Kconfig         |   1 +
 drivers/nvme/Makefile        |   1 +
 drivers/nvme/host/core.c     |   5 +-
 drivers/nvme/mdev/Kconfig    |  16 +
 drivers/nvme/mdev/Makefile   |   5 +
 drivers/nvme/mdev/adm.c      | 873 +++++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/events.c   | 142 ++++++
 drivers/nvme/mdev/host.c     | 491 ++++++++++++++++++++
 drivers/nvme/mdev/instance.c | 802 ++++++++++++++++++++++++++++++++
 drivers/nvme/mdev/io.c       | 563 ++++++++++++++++++++++
 drivers/nvme/mdev/irq.c      | 264 +++++++++++
 drivers/nvme/mdev/mdev.h     |  56 +++
 drivers/nvme/mdev/mmio.c     | 591 ++++++++++++++++++++++++
 drivers/nvme/mdev/pci.c      | 247 ++++++++++
 drivers/nvme/mdev/priv.h     | 700 ++++++++++++++++++++++++++++
 drivers/nvme/mdev/udata.c    | 390 ++++++++++++++++
 drivers/nvme/mdev/vcq.c      | 209 +++++++++
 drivers/nvme/mdev/vctrl.c    | 515 +++++++++++++++++++++
 drivers/nvme/mdev/viommu.c   | 322 +++++++++++++
 drivers/nvme/mdev/vns.c      | 356 ++++++++++++++
 drivers/nvme/mdev/vsq.c      | 181 ++++++++
 22 files changed, 6733 insertions(+), 2 deletions(-)
 create mode 100644 drivers/nvme/mdev/Kconfig
 create mode 100644 drivers/nvme/mdev/Makefile
 create mode 100644 drivers/nvme/mdev/adm.c
 create mode 100644 drivers/nvme/mdev/events.c
 create mode 100644 drivers/nvme/mdev/host.c
 create mode 100644 drivers/nvme/mdev/instance.c
 create mode 100644 drivers/nvme/mdev/io.c
 create mode 100644 drivers/nvme/mdev/irq.c
 create mode 100644 drivers/nvme/mdev/mdev.h
 create mode 100644 drivers/nvme/mdev/mmio.c
 create mode 100644 drivers/nvme/mdev/pci.c
 create mode 100644 drivers/nvme/mdev/priv.h
 create mode 100644 drivers/nvme/mdev/udata.c
 create mode 100644 drivers/nvme/mdev/vcq.c
 create mode 100644 drivers/nvme/mdev/vctrl.c
 create mode 100644 drivers/nvme/mdev/viommu.c
 create mode 100644 drivers/nvme/mdev/vns.c
 create mode 100644 drivers/nvme/mdev/vsq.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dce5c099f43c..d143e929d7ed 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10896,6 +10896,11 @@ W:	http://git.infradead.org/nvme.git
 S:	Supported
 F:	drivers/nvme/target/
 
+NVM EXPRESS MDEV DRIVER
+M:	Maxim Levitsky <mlevitsk@redhat.com>
+S:	Supported
+F:	drivers/nvme/mdev/
+
 NVMEM FRAMEWORK
 M:	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 S:	Maintained
diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig
index 04008e0bbe81..cbf867e6ac1e 100644
--- a/drivers/nvme/Kconfig
+++ b/drivers/nvme/Kconfig
@@ -2,5 +2,6 @@ menu "NVME Support"
 
 source "drivers/nvme/host/Kconfig"
 source "drivers/nvme/target/Kconfig"
+source "drivers/nvme/mdev/Kconfig"
 
 endmenu
diff --git a/drivers/nvme/Makefile b/drivers/nvme/Makefile
index 0096a7fd1431..0458efc57aee 100644
--- a/drivers/nvme/Makefile
+++ b/drivers/nvme/Makefile
@@ -1,3 +1,4 @@
 
 obj-y		+= host/
 obj-y		+= target/
+obj-y		+= mdev/
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 90561973bce9..a835884fcbcd 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1687,6 +1687,7 @@ static void nvme_update_disk_info(struct gendisk *disk,
 	if (ns->ms && !ns->ext &&
 	    (ns->ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
 		nvme_init_integrity(disk, ns->ms, ns->pi_type);
+
 	if (ns->ms && !nvme_ns_has_pi(ns) && !blk_get_integrity(disk))
 		capacity = 0;
 
@@ -2302,7 +2303,7 @@ static void nvme_init_subnqn(struct nvme_subsystem *subsys, struct nvme_ctrl *ct
 	size_t nqnlen;
 	int off;
 
-	if(!(ctrl->quirks & NVME_QUIRK_IGNORE_DEV_SUBNQN)) {
+	if (!(ctrl->quirks & NVME_QUIRK_IGNORE_DEV_SUBNQN)) {
 		nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
 		if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
 			strlcpy(subsys->subnqn, id->subnqn, NVMF_NQN_SIZE);
@@ -3361,8 +3362,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 
 	nvme_mpath_add_disk(ns, id);
 	nvme_fault_inject_init(ns);
-	kfree(id);
 
+	kfree(id);
 	return;
  out_put_disk:
 	put_disk(ns->disk);
diff --git a/drivers/nvme/mdev/Kconfig b/drivers/nvme/mdev/Kconfig
new file mode 100644
index 000000000000..7ebc66cdeac0
--- /dev/null
+++ b/drivers/nvme/mdev/Kconfig
@@ -0,0 +1,16 @@
+
+config NVME_MDEV
+	bool
+
+config NVME_MDEV_VFIO
+	tristate "NVME Mediated VFIO virtual device"
+	select NVME_MDEV
+	depends on BLOCK
+	depends on VFIO_MDEV
+	depends on NVME_CORE
+	help
+	  This provides EXPEREMENTAL support for lightweight software
+	  passthrough of an partition on a NVME storage device to
+	  guest, also as a NVME namespace, attached to a virtual NVME
+	  controller
+	  If unsure, say N.
diff --git a/drivers/nvme/mdev/Makefile b/drivers/nvme/mdev/Makefile
new file mode 100644
index 000000000000..114016c48476
--- /dev/null
+++ b/drivers/nvme/mdev/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_NVME_MDEV_VFIO) 	+=	nvme-mdev.o
+
+nvme-mdev-y += adm.o events.o instance.o host.o io.o irq.o \
+	       udata.o viommu.o vns.o vsq.o vcq.o vctrl.o mmio.o pci.o
diff --git a/drivers/nvme/mdev/adm.c b/drivers/nvme/mdev/adm.c
new file mode 100644
index 000000000000..39a7ad252c69
--- /dev/null
+++ b/drivers/nvme/mdev/adm.c
@@ -0,0 +1,873 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe admin command implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+struct adm_ctx {
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl;
+	const struct nvme_command *in;
+	struct nvme_mdev_vns *ns;
+	struct nvme_ext_data_iter udatait;
+	unsigned int datalen;
+};
+
+/*Identify Controller */
+static int nvme_mdev_adm_handle_id_cntrl(struct adm_ctx *ctx)
+{
+	int ret;
+	const struct nvme_identify *in = &ctx->in->identify;
+	struct nvme_id_ctrl *id;
+
+	if (in->nsid != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	id =  kzalloc(sizeof(*id), GFP_KERNEL);
+	if (!id)
+		return NVME_SC_INTERNAL;
+
+	/** Controller Capabilities and Features ************************/
+	// PCI vendor ID
+	store_le16(&id->vid, NVME_MDEV_PCI_VENDOR_ID);
+	// PCI Subsystem Vendor ID
+	store_le16(&id->ssvid, NVME_MDEV_PCI_SUBVENDOR_ID);
+	// Serial Number
+	store_strsp(id->sn, ctx->vctrl->serial);
+	// Model Number
+	store_strsp(id->mn, "NVMe MDEV virtual device");
+	// Firmware Revision
+	store_strsp(id->fr, NVME_MDEV_FIRMWARE_VERSION);
+	// Recommended Arbitration Burst
+	id->rab = 6;
+	// IEEE OUI Identifier for the controller vendor
+	id->ieee[0] = 0;
+	// Controller Multi-Path I/O and Namespace Sharing Capabilities
+	id->cmic = 0;
+	// Maximum Data Transfer Size (power of two, in page size units)
+	id->mdts = ctx->hctrl->mdts;
+	// controller ID
+	id->cntlid = 0;
+	// NVME supported version
+	store_le32(&id->ver, NVME_MDEV_NVME_VER);
+	// RTD3 Resume Latency
+	id->rtd3r = 0;
+	//RTD3 Entry Latency
+	id->rtd3e = 0;
+	// Optional Asynchronous Events Supported
+	store_le32(&id->oaes, NVME_AEN_CFG_NS_ATTR);
+	// Controller Attributes (misc junk)
+	id->ctratt = 0;
+
+	/*Admin Command Set Attributes & Optional Controller Capabilities */
+	// Optional Admin Command Support
+	id->oacs = ctx->vctrl->mmio.shadow_db_supported ?
+			NVME_CTRL_OACS_DBBUF_SUPP : 0;
+	// Abort Command Limit (dummy, zero based)
+	id->acl = 3;
+	 // Asynchronous Event Request Limit (zero based)
+	id->aerl = MAX_AER_COMMANDS - 1;
+	// Firmware Updates (dummy)
+	id->frmw = 3;
+	// Log Page Attributes
+	// (IMPLEMENT: bit for commands supported and effects)
+	id->lpa = 0;
+	// Error Log Page Entries
+	// (zero based, IMPLEMENT: dummy for now)
+	id->elpe = 0;
+	// Number of Power States Support
+	// (zero based, IMPLEMENT: dummy for now)
+	id->npss = 0;
+	// Admin Vendor Specific Command Configuration (junk)
+	id->avscc = 0;
+	// Autonomous Power State Transition Attributes
+	id->apsta = 0;
+	// Warning Composite Temperature Threshold (dummy)
+	id->wctemp = 0x157;
+	// Critical Composite Temperature Threshold (dummy)
+	id->cctemp = 0x175;
+	// Maximum Time for Firmware Activation (dummy)
+	id->mtfa = 0;
+	// Host Memory Buffer Preferred Size (dummy)
+	id->hmpre = 0;
+	// Host Memory Buffer Minimum Size (dummy)
+	id->hmmin = 0;
+	// Total NVM Capacity (not supported)
+	id->tnvmcap[0] = 0;
+	// Unallocated NVM Capacity (not supported for now)
+	id->unvmcap[0] = 0;
+	// Replay Protected Memory Block Support
+	id->rpmbs = 0;
+	// Extended Device Self-test Time (dummy)
+	id->edstt = 0;
+	// Device Self-test Options (dummy)
+	id->dsto = 0;
+	// Firmware Update Granularity (dummy)
+	id->fwug = 0;
+	// Keep Alive Support (not supported)
+	id->kas = 0;
+	// Host Controlled Thermal Management Attributes (not supported)
+	id->hctma = 0;
+	// Minimum Thermal Management Temperature (not supported)
+	id->mntmt = 0;
+	// Maximum Thermal Management Temperature (not supported)
+	id->mxtmt = 0;
+	// Sanitize capabilities (not supported)
+	id->sanicap = 0;
+
+	/****************** NVM Command Set Attributes ********************/
+	// Submission Queue Entry Size
+	id->sqes = (0x6 << 4) | 0x6;
+	// Completion Queue Entry Size
+	id->cqes = (0x4 << 4) | 0x4;
+	// Maximum Outstanding Commands
+	id->maxcmd = 0;
+	// Number of Namespaces
+	id->nn = MAX_VIRTUAL_NAMESPACES;
+	// Optional NVM Command Support
+	// (we add dsm and write zeros if host supports them)
+	id->oncs = ctx->hctrl->oncs;
+	// TODOLATER: IO: Fused Operation Support
+	id->fuses = 0;
+	// Format NVM Attributes (don't support)
+	id->fna = 0;
+	// Volatile Write Cache (tell that always exist)
+	id->vwc = 1;
+	// Atomic Write Unit Normal (zero based value in blocks)
+	id->awun = 0;
+	// Atomic Write Unit Power Fail (ditto)
+	id->awupf = 0;
+	// NVM Vendor Specific Command Configuration
+	id->nvscc = 0;
+	// Atomic Compare & Write Unit  (zero based value in blocks)
+	id->acwu = 0;
+	// SGL Support
+	id->sgls = 0;
+	// NVM Subsystem NVMe Qualified Name
+	strncpy(id->subnqn, ctx->vctrl->subnqn, sizeof(id->subnqn));
+
+	/******************Power state descriptors ***********************/
+	store_le16(&id->psd[0].max_power, 0x9c4); // dummy
+	store_le32(&id->psd[0].entry_lat, 0x10);
+	store_le32(&id->psd[0].exit_lat, 0x4);
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, id, sizeof(*id));
+	kfree(id);
+	return nvme_mdev_translate_error(ret);
+}
+
+/*Identify Namespace data structure for the specified NSID or common one */
+static int nvme_mdev_adm_handle_id_ns(struct adm_ctx *ctx)
+{
+	int ret;
+	struct nvme_id_ns *idns;
+	u32 nsid = le32_to_cpu(ctx->in->identify.nsid);
+
+	if (nsid == 0xffffffff || nsid == 0 || nsid > MAX_VIRTUAL_NAMESPACES)
+		return DNR(NVME_SC_INVALID_NS);
+
+	/* Allocate return structure*/
+	idns =  kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+	if (!idns)
+		return NVME_SC_INTERNAL;
+
+	if (ctx->ns) {
+		//Namespace Size
+		store_le64(&idns->nsze, ctx->ns->ns_size);
+		// Namespace Capacity
+		store_le64(&idns->ncap, ctx->ns->ns_size);
+		// Namespace Utilization
+		store_le64(&idns->nuse, ctx->ns->ns_size);
+		// Namespace Features (nothing to set here yet)
+		idns->nsfeat = 0;
+		// Number of LBA Formats (dummy, zero based)
+		idns->nlbaf = 0;
+		// Formatted LBA Size (current LBA format in use)
+		// + external metadata bit
+		idns->flbas = 0;
+		// Metadata Capabilities
+		idns->mc = 0;
+		// End-to-end Data Protection Capabilities
+		idns->dpc = 0;
+		// End-to-end Data Protection Type Settings
+		idns->dps = 0;
+		// Namespace Multi-path I/O and Namespace Sharing Capabilities
+		idns->nmic = 0;
+		// Reservation Capabilities
+		idns->rescap = 0;
+		// Format Progress Indicator (dummy)
+		idns->fpi = 0;
+		// Namespace Atomic Write Unit Normal
+		idns->nawun = 0;
+		// Namespace Atomic Write Unit Power Fail
+		idns->nawupf = 0;
+		// Namespace Atomic Compare & Write Unit
+		idns->nacwu = 0;
+		// Namespace Atomic Boundary Size Normal
+		idns->nabsn = 0;
+		// Namespace Atomic Boundary Offset
+		idns->nabo = 0;
+		// Namespace Atomic Boundary Size Power Fail
+		idns->nabspf = 0;
+		// Namespace Optimal IO Boundary
+		idns->noiob = ctx->ns->noiob;
+		// NVM Capacity (another capacity but in bytes)
+		idns->nvmcap[0]  = 0;
+
+		// TODOLATER: NS: support NGUID/EUI64
+		idns->nguid[0] = 0;
+		idns->eui64[0] = 0;
+		// format 0 metadata size
+		idns->lbaf[0].ms = 0;
+		// format 0 block size (in power of two)
+		idns->lbaf[0].ds = ctx->ns->blksize_shift;
+		// format 0 relative performance
+		idns->lbaf[0].rp = 0;
+	}
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, idns,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(idns);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Namespace Identification Descriptor list for the specified NSID.*/
+static int nvme_mdev_adm_handle_id_ns_desc(struct adm_ctx *ctx)
+{
+	struct ns_desc {
+		struct nvme_ns_id_desc uuid_desc;
+		uuid_t uuid;
+		struct nvme_ns_id_desc null_desc;
+	};
+
+	int ret;
+	struct ns_desc *id;
+
+	if (!ctx->ns)
+		return DNR(NVME_SC_INVALID_NS);
+
+	/* Allocate return structure */
+	id = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+	if (!id)
+		return NVME_SC_INTERNAL;
+
+	id->uuid_desc.nidt = NVME_NIDT_UUID;
+	id->uuid_desc.nidl = NVME_NIDT_UUID_LEN;
+	memcpy(&id->uuid, &ctx->ns->uuid, sizeof(id->uuid));
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, id,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(id);
+	return nvme_mdev_translate_error(ret);
+}
+
+/*Active Namespace ID list */
+static int nvme_mdev_adm_handle_id_active_ns_list(struct adm_ctx *ctx)
+{
+	u32 nsid, start_nsid = le32_to_cpu(ctx->in->identify.nsid);
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	int i = 0, ret;
+
+	__le32 *nslist = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
+
+	if (start_nsid >= 0xfffffffe)
+		return DNR(NVME_SC_INVALID_NS);
+
+	for (nsid = start_nsid + 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++)
+		if (nvme_mdev_vns_from_vnsid(vctrl, nsid))
+			nslist[i++] = nsid;
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, nslist,
+				       NVME_IDENTIFY_DATA_SIZE);
+	kfree(nslist);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Handle Identify command*/
+static int nvme_mdev_adm_handle_id(struct adm_ctx *ctx)
+{
+	const struct nvme_identify *in = &ctx->in->identify;
+
+	int ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait,
+						&ctx->in->common.dptr,
+						NVME_IDENTIFY_DATA_SIZE);
+
+	u32 nsid = le32_to_cpu(in->nsid);
+
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (in->ctrlid)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->ns = nvme_mdev_vns_from_vnsid(ctx->vctrl, nsid);
+
+	switch (ctx->in->identify.cns) {
+	case NVME_ID_CNS_CTRL:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY CTRL\n");
+		return nvme_mdev_adm_handle_id_cntrl(ctx);
+	case NVME_ID_CNS_NS_ACTIVE_LIST:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY ACTIVE_NS_LIST\n");
+		return nvme_mdev_adm_handle_id_active_ns_list(ctx);
+	case NVME_ID_CNS_NS:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY NS=0x%08x\n", nsid);
+		return nvme_mdev_adm_handle_id_ns(ctx);
+	case NVME_ID_CNS_NS_DESC_LIST:
+		_DBG(ctx->vctrl, "ADMINQ: IDENTIFY NS_DESC NS=0x%08x\n", nsid);
+		return nvme_mdev_adm_handle_id_ns_desc(ctx);
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Error log for AER */
+static int nvme_mdev_adm_handle_get_log_page_err(struct adm_ctx *ctx)
+{
+	struct nvme_err_log_entry dummy_entry;
+	int ret;
+
+	// write one dummy entry with 0 error count
+	memset(&dummy_entry, 0, sizeof(dummy_entry));
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait,
+				       &dummy_entry,
+				       min((unsigned int)sizeof(dummy_entry),
+					   ctx->datalen));
+
+	return nvme_mdev_translate_error(ret);
+}
+
+/* This log page allows to tell user about connected/disconnected namespaces */
+static int nvme_mdev_adm_handle_get_log_page_changed_ns(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min(ctx->vctrl->ns_log_size * 4, ctx->datalen);
+
+	int ret = nvme_mdev_write_to_udata(&ctx->udatait,
+					   &ctx->vctrl->ns_log, datasize);
+
+	nvme_mdev_vns_log_reset(ctx->vctrl);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* S.M.A.R.T. log*/
+static int nvme_mdev_adm_handle_get_log_page_smart(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min_t(unsigned int,
+			sizeof(struct nvme_smart_log), ctx->datalen);
+	int ret;
+	struct nvme_smart_log *log = kzalloc(sizeof(*log), GFP_KERNEL);
+
+	if (!log)
+		return NVME_SC_INTERNAL;
+
+	/* Some dummy values */
+	log->avail_spare = 100;
+	log->spare_thresh = 10;
+	store_le16(&log->temperature, 0x140);
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, log, datasize);
+	kfree(log);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* FW slot log - useless */
+static int nvme_mdev_adm_handle_get_log_page_fw_slot(struct adm_ctx *ctx)
+{
+	unsigned int datasize = min_t(unsigned int,
+				      sizeof(struct nvme_fw_slot_info_log),
+				      ctx->datalen);
+	int ret;
+	struct nvme_fw_slot_info_log *log = kzalloc(sizeof(*log), GFP_KERNEL);
+
+	if (!log)
+		return NVME_SC_INTERNAL;
+
+	ret = nvme_mdev_write_to_udata(&ctx->udatait, log, datasize);
+	kfree(log);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to GET LOG PAGE command */
+static int nvme_mdev_adm_handle_get_log_page(struct adm_ctx *ctx)
+{
+	const struct nvme_get_log_page_command *in = &ctx->in->get_log_page;
+	u8 log_page_id = ctx->in->get_log_page.lid;
+	int ret;
+
+	ctx->datalen = (le16_to_cpu(in->numdl) + 1) * 4;
+
+	/*  We don't support extensions (NUMDU,LPOL,LPOU) */
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* Currently ignore the NSID in the command */
+
+	/* ACK the AER */
+	if ((in->lsp & 0x80) == 0)
+		nvme_mdev_event_process_ack(ctx->vctrl, log_page_id);
+
+	/* map data pointer */
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait,
+					    &in->dptr, ctx->datalen);
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	switch (log_page_id) {
+	case NVME_LOG_ERROR:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : ERRLOG\n");
+		return nvme_mdev_adm_handle_get_log_page_err(ctx);
+	case NVME_LOG_CHANGED_NS:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : CHANGED_NS\n");
+		return nvme_mdev_adm_handle_get_log_page_changed_ns(ctx);
+	case NVME_LOG_SMART:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : SMART\n");
+		return nvme_mdev_adm_handle_get_log_page_smart(ctx);
+	case NVME_LOG_FW_SLOT:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : FWSLOT\n");
+		return nvme_mdev_adm_handle_get_log_page_fw_slot(ctx);
+	default:
+		_DBG(ctx->vctrl, "ADMINQ: GET_LOG_PAGE : log page 0x%02x\n",
+		     log_page_id);
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Response to CREATE CQ command */
+static int nvme_mdev_adm_handle_create_cq(struct adm_ctx *ctx)
+{
+	int irq = -1, ret;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_create_cq *in = &ctx->in->create_cq;
+	u16 cqid = le16_to_cpu(in->cqid);
+	u16 qsize = le16_to_cpu(in->qsize);
+	u16 cq_flags = le16_to_cpu(in->cq_flags);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR_PRP2 |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* QID checks*/
+	if (!cqid ||
+	    cqid >= MAX_VIRTUAL_QUEUES || test_bit(cqid, vctrl->vcq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	/* Queue size checks*/
+	if (qsize > (MAX_VIRTUAL_QUEUE_DEPTH - 1) || qsize < 1)
+		return DNR(NVME_SC_QUEUE_SIZE);
+
+	/* Queue flags checks */
+	if (cq_flags & ~(NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (cq_flags & NVME_CQ_IRQ_ENABLED) {
+		irq = le16_to_cpu(in->irq_vector);
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_VECTOR);
+	}
+
+	ret = nvme_mdev_vcq_init(ctx->vctrl, cqid,
+				 le64_to_cpu(in->prp1),
+				 cq_flags & NVME_QUEUE_PHYS_CONTIG,
+				 qsize + 1, irq);
+
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to DELETE CQ command */
+static int nvme_mdev_adm_handle_delete_cq(struct adm_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_delete_queue *in =  &ctx->in->delete_queue;
+	u16 qid = le16_to_cpu(in->qid), sqid;
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!qid || qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vcq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	for_each_set_bit(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		if (vctrl->vsqs[sqid].vcq == &vctrl->vcqs[qid])
+			return DNR(NVME_SC_INVALID_QUEUE);
+
+	nvme_mdev_vcq_delete(vctrl, qid);
+	return NVME_SC_SUCCESS;
+}
+
+/* Response to CREATE SQ command */
+static int nvme_mdev_adm_handle_create_sq(struct adm_ctx *ctx)
+{
+	const struct nvme_create_sq *in = &ctx->in->create_sq;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	int ret;
+
+	u16 sqid = le16_to_cpu(in->sqid);
+	u16 cqid = le16_to_cpu(in->cqid);
+	u16 qsize = le16_to_cpu(in->qsize);
+	u16 sq_flags = le16_to_cpu(in->sq_flags);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR_PRP2 |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!sqid ||
+	    sqid >= MAX_VIRTUAL_QUEUES || test_bit(sqid, vctrl->vsq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	if (!cqid || cqid  >= MAX_VIRTUAL_QUEUES)
+		return DNR(NVME_SC_QID_INVALID);
+
+	if (!test_bit(cqid, vctrl->vcq_en))
+		return DNR(NVME_SC_CQ_INVALID);
+
+	/* Queue size checks */
+	if (qsize > (MAX_VIRTUAL_QUEUE_DEPTH - 1) || qsize < 1)
+		return DNR(NVME_SC_QUEUE_SIZE);
+
+	/* Queue flags checks */
+	if (sq_flags & ~(NVME_QUEUE_PHYS_CONTIG | NVME_SQ_PRIO_MASK))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ret = nvme_mdev_vsq_init(ctx->vctrl, sqid,
+				 le64_to_cpu(in->prp1),
+				 sq_flags & NVME_QUEUE_PHYS_CONTIG,
+				 qsize + 1, cqid);
+	if (ret)
+		goto error;
+
+	return NVME_SC_SUCCESS;
+error:
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to DELETE SQ command */
+static int nvme_mdev_adm_handle_delete_sq(struct adm_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	const struct nvme_delete_queue *in =  &ctx->in->delete_queue;
+	u16 qid = le16_to_cpu(in->qid);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW11_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!qid || qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vsq_en))
+		return DNR(NVME_SC_QID_INVALID);
+
+	nvme_mdev_vsq_delete(ctx->vctrl, qid);
+	return NVME_SC_SUCCESS;
+}
+
+/* Set the shadow doorbell */
+static int nvme_mdev_adm_handle_dbbuf(struct adm_ctx *ctx)
+{
+	const struct nvme_dbbuf *in = &ctx->in->dbbuf;
+	int ret;
+
+	dma_addr_t sdb_iova = le64_to_cpu(in->prp1);
+	dma_addr_t eidx_iova = le64_to_cpu(in->prp2);
+
+	/* Check if we support the shadow doorbell */
+	if (!ctx->vctrl->mmio.shadow_db_supported)
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	/* Don't allow to enable the shadow doorbell more that once */
+	if (ctx->vctrl->mmio.shadow_db_en)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* check input buffers */
+	if ((OFFSET_IN_PAGE(sdb_iova) != 0) || (OFFSET_IN_PAGE(eidx_iova) != 0))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* switch to the new doorbell buffer */
+	ret = nvme_mdev_mmio_enable_dbs_shadow(ctx->vctrl, sdb_iova, eidx_iova);
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Response to GET_FEATURES command */
+static int nvme_mdev_adm_handle_get_features(struct adm_ctx *ctx)
+{
+	u32 value = 0;
+	u32 irq;
+	const struct nvme_features *in = &ctx->in->features;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	unsigned int tmp;
+
+	u32 fid = le32_to_cpu(in->fid);
+	u16 cid = le16_to_cpu(in->command_id);
+
+	_DBG(ctx->vctrl, "ADMINQ: GET_FEATURES FID=0x%x\n", fid);
+
+	/* common reserved bits*/
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* reserved bits in dword10*/
+	if (fid > 0xFF)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* reserved bits in dword11*/
+	if (fid != NVME_FEAT_IRQ_CONFIG && in->dword11 != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (fid) {
+	/* Number of queues */
+	case NVME_FEAT_NUM_QUEUES:
+		value = (MAX_VIRTUAL_QUEUES - 1) |
+			((MAX_VIRTUAL_QUEUES - 1) << 16);
+		goto out;
+
+	/* Arbitration */
+	case NVME_FEAT_ARBITRATION:
+		value = vctrl->arb_burst_shift & 0x7;
+		goto out;
+
+	/* Interrupt coalescing settings*/
+	case NVME_FEAT_IRQ_COALESCE:
+		tmp = vctrl->irqs.irq_coalesc_time_us;
+		do_div(tmp, 100);
+		value = (vctrl->irqs.irq_coalesc_max - 1) | (tmp << 8);
+		goto out;
+
+	/* Interrupt coalescing disable for a specific interrupt */
+	case NVME_FEAT_IRQ_CONFIG:
+		irq = le32_to_cpu(in->dword11);
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_FIELD);
+
+		value = irq;
+		if (vctrl->irqs.vecs[irq].irq_coalesc_en)
+			value |= (1 << 16);
+		goto out;
+
+	/* Volatile write cache */
+	case NVME_FEAT_VOLATILE_WC:
+		/*we always report write cache due to mediation*/
+		value = 0x1;
+		goto out;
+
+	/* Limited error recovery */
+	case NVME_FEAT_ERR_RECOVERY:
+		value = 0;
+		break;
+
+	/* Workload hint + power state */
+	case NVME_FEAT_POWER_MGMT:
+		value = vctrl->worload_hint << 4;
+		break;
+
+	/* Temperature threshold */
+	case NVME_FEAT_TEMP_THRESH:
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* AEN permanent masking*/
+	case NVME_FEAT_ASYNC_EVENT:
+		value = nvme_mdev_event_read_aen_config(vctrl);
+		goto out;
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+out:
+	nvme_mdev_vsq_cmd_done_adm(ctx->vctrl, value, cid, NVME_SC_SUCCESS);
+	return -1;
+}
+
+/* Response to SET_FEATURES command */
+static int nvme_mdev_adm_handle_set_features(struct adm_ctx *ctx)
+{
+	const struct nvme_features *in = &ctx->in->features;
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+
+	u32 value = le32_to_cpu(in->dword11);
+	u8 fid = le32_to_cpu(in->fid) & 0xFF;
+	u16 cid = le16_to_cpu(in->command_id);
+	u32 nsid = le32_to_cpu(in->nsid);
+
+	_DBG(ctx->vctrl, "ADMINQ: SET_FEATURES cmd. FID=0x%x\n", fid);
+
+	if (nsid != 0xffffffff && nsid != 0)
+		return DNR(NVME_SC_FEATURE_NOT_PER_NS);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (fid) {
+	case NVME_FEAT_NUM_QUEUES:
+		/* need to return the value here as well */
+		value = (MAX_VIRTUAL_QUEUES - 1) |
+			((MAX_VIRTUAL_QUEUES - 1) << 16);
+
+		nvme_mdev_vsq_cmd_done_adm(ctx->vctrl, value,
+					   cid, NVME_SC_SUCCESS);
+		return -1;
+
+	case NVME_FEAT_ARBITRATION:
+		vctrl->arb_burst_shift = value & 0x7;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_IRQ_COALESCE:
+		vctrl->irqs.irq_coalesc_max = (value & 0xFF) + 1;
+		vctrl->irqs.irq_coalesc_time_us = ((value >> 8) & 0xFF) * 100;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_IRQ_CONFIG: {
+		u16 irq = value & 0xFFFF;
+
+		if (irq >= MAX_VIRTUAL_IRQS)
+			return DNR(NVME_SC_INVALID_FIELD);
+
+		vctrl->irqs.vecs[irq].irq_coalesc_en = (value & 0x10000) != 0;
+		return NVME_SC_SUCCESS;
+	}
+	case NVME_FEAT_VOLATILE_WC:
+		return (value != 0x1) ? DNR(NVME_SC_FEATURE_NOT_CHANGEABLE) :
+							NVME_SC_SUCCESS;
+
+	case NVME_FEAT_ERR_RECOVERY:
+		return (value != 0) ? DNR(NVME_SC_FEATURE_NOT_CHANGEABLE) :
+							NVME_SC_SUCCESS;
+	case NVME_FEAT_POWER_MGMT:
+		if (value & 0xFFFFFF0F)
+			return DNR(NVME_SC_INVALID_FIELD);
+		vctrl->worload_hint = value >> 4;
+		return NVME_SC_SUCCESS;
+
+	case NVME_FEAT_TEMP_THRESH:
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	case NVME_FEAT_ASYNC_EVENT:
+		nvme_mdev_event_set_aen_config(vctrl, value);
+		return NVME_SC_SUCCESS;
+	default:
+		return DNR(NVME_SC_INVALID_FIELD);
+	}
+}
+
+/* Response to AER command */
+static int nvme_mdev_adm_handle_async_event(struct adm_ctx *ctx)
+{
+	u16 cid = le16_to_cpu(ctx->in->common.command_id);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	return nvme_mdev_event_request_receive(ctx->vctrl, cid);
+}
+
+/* (Dummy) response to ABORT command*/
+static int nvme_mdev_adm_handle_abort(struct adm_ctx *ctx)
+{
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_NSID | RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	return DNR(NVME_SC_ABORT_MISSING);
+}
+
+/* Process one new command in the admin queue*/
+static int nvme_mdev_adm_handle_cmd(struct adm_ctx *ctx)
+{
+	u8 optcode = ctx->in->common.opcode;
+
+	ctx->ns = NULL;
+	ctx->datalen = 0;
+
+	if (ctx->in->common.flags != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	switch (optcode) {
+	case nvme_admin_identify:
+		return nvme_mdev_adm_handle_id(ctx);
+	case nvme_admin_create_cq:
+		_DBG(ctx->vctrl, "ADMINQ: CREATE_CQ\n");
+		return nvme_mdev_adm_handle_create_cq(ctx);
+	case nvme_admin_create_sq:
+		_DBG(ctx->vctrl, "ADMINQ: CREATE_SQ\n");
+		return nvme_mdev_adm_handle_create_sq(ctx);
+	case nvme_admin_delete_sq:
+		_DBG(ctx->vctrl, "ADMINQ: DELETE_SQ\n");
+		return nvme_mdev_adm_handle_delete_sq(ctx);
+	case nvme_admin_delete_cq:
+		_DBG(ctx->vctrl, "ADMINQ: DELETE_CQ\n");
+		return nvme_mdev_adm_handle_delete_cq(ctx);
+	case nvme_admin_dbbuf:
+		_DBG(ctx->vctrl, "ADMINQ: DBBUF_CONFIG\n");
+		return nvme_mdev_adm_handle_dbbuf(ctx);
+	case nvme_admin_get_log_page:
+		return nvme_mdev_adm_handle_get_log_page(ctx);
+	case nvme_admin_get_features:
+		return nvme_mdev_adm_handle_get_features(ctx);
+	case nvme_admin_set_features:
+		return nvme_mdev_adm_handle_set_features(ctx);
+	case nvme_admin_async_event:
+		_DBG(ctx->vctrl, "ADMINQ: ASYNC_EVENT_REQ\n");
+		return nvme_mdev_adm_handle_async_event(ctx);
+	case nvme_admin_abort_cmd:
+		_DBG(ctx->vctrl, "ADMINQ: ABORT\n");
+		return nvme_mdev_adm_handle_abort(ctx);
+	default:
+		_DBG(ctx->vctrl, "ADMINQ: optcode 0x%04x\n", optcode);
+		return DNR(NVME_SC_INVALID_OPCODE);
+	}
+}
+
+/* Process all pending admin commands */
+void nvme_mdev_adm_process_sq(struct nvme_mdev_vctrl *vctrl)
+{
+	struct adm_ctx ctx;
+
+	lockdep_assert_held(&vctrl->lock);
+	memset(&ctx, 0, sizeof(struct adm_ctx));
+	ctx.vctrl = vctrl;
+	ctx.hctrl = vctrl->hctrl;
+	nvme_mdev_udata_iter_setup(&vctrl->viommu, &ctx.udatait);
+
+	nvme_mdev_io_pause(ctx.vctrl);
+
+	while (!(nvme_mdev_vctrl_is_dead(vctrl))) {
+		int ret;
+		u16 cid;
+
+		ctx.in = nvme_mdev_vsq_get_cmd(vctrl, &vctrl->vsqs[0]);
+		if (!ctx.in)
+			break;
+
+		cid = le16_to_cpu(ctx.in->common.command_id);
+		ret = nvme_mdev_adm_handle_cmd(&ctx);
+
+		if (ret == -1)
+			continue;
+
+		if (ret != 0)
+			_DBG(vctrl, "ADMINQ: CID 0x%x FAILED: status 0x%x\n",
+			     cid, ret);
+		nvme_mdev_vsq_cmd_done_adm(vctrl, 0, cid, ret);
+	}
+	nvme_mdev_io_resume(ctx.vctrl);
+}
diff --git a/drivers/nvme/mdev/events.c b/drivers/nvme/mdev/events.c
new file mode 100644
index 000000000000..9854c1cabdcb
--- /dev/null
+++ b/drivers/nvme/mdev/events.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe async events implementation (AER, changed namespace log)
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* complete an AER event on the admin queue if it is pending*/
+static void nvme_mdev_event_complete(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 lid, cid;
+	u32 dw0;
+
+	for_each_set_bit(lid, vctrl->events.events_pending, MAX_LOG_PAGES) {
+		/* we have pending aer requests, but no requests*/
+		if (vctrl->events.aer_cid_count == 0)
+			break;
+
+		if (!test_bit(lid, vctrl->events.events_enabled))
+			continue;
+
+		cid = vctrl->events.aer_cids[--vctrl->events.aer_cid_count];
+		dw0 = vctrl->events.event_values[lid];
+		clear_bit(lid, vctrl->events.events_pending);
+
+		_DBG(vctrl,
+		     "AEN: replying to AER (CID=%d) with status 0x%08x\n",
+		     cid, dw0);
+
+		nvme_mdev_vsq_cmd_done_adm(vctrl, dw0, cid, NVME_SC_SUCCESS);
+	}
+}
+
+/* deal with received async event request from the user*/
+int nvme_mdev_event_request_receive(struct nvme_mdev_vctrl *vctrl,
+				    u16 cid)
+{
+	int cnt = vctrl->events.aer_cid_count;
+
+	if (cnt >= MAX_AER_COMMANDS)
+		return DNR(NVME_SC_ASYNC_LIMIT);
+
+	/* don't allow AER to be pending if there is no space left in the
+	 * completion queue permanently
+	 */
+	if ((cnt + 1) >= vctrl->vcqs[0].size - 1)
+		return DNR(NVME_SC_ASYNC_LIMIT);
+
+	vctrl->events.aer_cids[cnt++] = cid;
+	vctrl->events.aer_cid_count = cnt;
+
+	_DBG(vctrl, "AEN: received new request (cid=%d)\n", cid);
+	nvme_mdev_event_complete(vctrl);
+	return -1;
+}
+
+/* Send an async event request */
+void nvme_mdev_event_send(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_async_event_type type,
+			  enum nvme_async_event info)
+{
+	u8 log_page;
+	u32 event;
+
+	// determine the log page for event types that we support
+	switch (type) {
+	case NVME_AER_TYPE_ERROR:
+		log_page = NVME_LOG_ERROR;
+		break;
+	case NVME_AER_TYPE_SMART:
+		log_page = NVME_LOG_SMART;
+		break;
+	case NVME_AER_TYPE_NOTICE:
+		WARN_ON(info != NVME_AER_NOTICE_NS_CHANGED);
+		log_page = NVME_LOG_CHANGED_NS;
+		break;
+	default:
+		WARN_ON(1);
+		return;
+	}
+
+	if (test_and_set_bit(log_page, vctrl->events.events_masked))
+		return;
+
+	event = (u32)type | ((u32)info << 8) | ((u32)log_page << 16);
+	vctrl->events.event_values[log_page] = event;
+	set_bit(log_page, vctrl->events.events_masked);
+	set_bit(log_page, vctrl->events.events_pending);
+	nvme_mdev_event_complete(vctrl);
+}
+
+u32 nvme_mdev_event_read_aen_config(struct nvme_mdev_vctrl *vctrl)
+{
+	u32 value = 0;
+
+	if (test_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled))
+		value |= NVME_AEN_CFG_NS_ATTR;
+	return value;
+}
+
+void nvme_mdev_event_set_aen_config(struct nvme_mdev_vctrl *vctrl, u32 value)
+{
+	_DBG(vctrl, "AEN: set config: 0x%04x\n", value);
+
+	if (value & NVME_AEN_CFG_NS_ATTR)
+		set_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+	else
+		clear_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+
+	nvme_mdev_event_complete(vctrl);
+}
+
+/* called when user acks an log page which causes an AER event to be unmasked*/
+void nvme_mdev_event_process_ack(struct nvme_mdev_vctrl *vctrl, u8 log_page)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	_DBG(vctrl, "AEN: log page %d ACK\n", log_page);
+
+	if (log_page >= MAX_LOG_PAGES)
+		return;
+
+	clear_bit(log_page, vctrl->events.events_masked);
+	nvme_mdev_event_complete(vctrl);
+}
+
+/* reset event state*/
+void nvme_mdev_events_init(struct nvme_mdev_vctrl *vctrl)
+{
+	memset(&vctrl->events, 0, sizeof(vctrl->events));
+	set_bit(NVME_LOG_CHANGED_NS, vctrl->events.events_enabled);
+	set_bit(NVME_LOG_ERROR, vctrl->events.events_enabled);
+}
+
+/* reset event state*/
+void nvme_mdev_events_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	memset(&vctrl->events, 0, sizeof(vctrl->events));
+}
+
diff --git a/drivers/nvme/mdev/host.c b/drivers/nvme/mdev/host.c
new file mode 100644
index 000000000000..d90275baf5f8
--- /dev/null
+++ b/drivers/nvme/mdev/host.c
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe parent (host) device abstraction
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include <linux/mdev.h>
+#include <linux/module.h>
+#include "priv.h"
+
+static LIST_HEAD(nvme_mdev_hctrl_list);
+static DEFINE_MUTEX(nvme_mdev_hctrl_list_mutex);
+static struct nvme_mdev_inst_type **instance_types;
+
+unsigned int io_timeout_ms = 30000;
+module_param_named(io_timeout, io_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(io_timeout,
+		 "Maximum I/O command completion timeout (in msec)");
+
+unsigned int poll_timeout_ms = 500;
+module_param_named(poll_timeout, poll_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(poll_timeout,
+		 "Maximum idle time to keep polling (in msec) (0 - poll forever)");
+
+unsigned int admin_poll_rate_ms = 100;
+module_param_named(admin_poll_rate, poll_timeout_ms, uint, 0644);
+MODULE_PARM_DESC(admin_poll_rate,
+		 "Admin queue polling rate (in msec) (used only when shadow doorbell is disabled)");
+
+bool use_shadow_doorbell = true;
+module_param(use_shadow_doorbell, bool, 0644);
+MODULE_PARM_DESC(use_shadow_doorbell,
+		 "Enable the shadow doorbell NVMe extension");
+
+/* Create a new host controller */
+static struct nvme_mdev_hctrl *nvme_mdev_hctrl_create(struct nvme_ctrl *ctrl)
+{
+	struct nvme_mdev_hctrl *hctrl;
+	u32 max_lba_transfer;
+
+	/* TODOLATER: IO: support more page size configurations*/
+	if (ctrl->page_size != PAGE_SIZE)
+		return NULL;
+
+	hctrl = kzalloc_node(sizeof(*hctrl), GFP_KERNEL,
+			     dev_to_node(ctrl->dev));
+	if (!hctrl)
+		return NULL;
+
+	kref_init(&hctrl->ref);
+	mutex_init(&hctrl->lock);
+
+	hctrl->nvme_ctrl = ctrl;
+	nvme_get_ctrl(ctrl);
+
+	hctrl->oncs = ctrl->oncs &
+		(NVME_CTRL_ONCS_DSM | NVME_CTRL_ONCS_WRITE_ZEROES);
+
+	hctrl->id = ctrl->instance;
+	hctrl->node = dev_to_node(ctrl->dev);
+
+	max_lba_transfer = ctrl->max_hw_sectors >> (PAGE_SHIFT - 9);
+	hctrl->mdts = ilog2(__rounddown_pow_of_two(max_lba_transfer));
+
+	hctrl->nr_host_queues = ctrl->ops->ext_queues_available(ctrl);
+
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+
+	dev_info(ctrl->dev,
+		 "mediated nvme support enabled, using up to %d host queues\n",
+		 hctrl->nr_host_queues);
+
+	list_add_tail(&hctrl->link, &nvme_mdev_hctrl_list);
+
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+
+	if (mdev_register_device(ctrl->dev, &mdev_fops) < 0) {
+		nvme_put_ctrl(ctrl);
+		kfree(hctrl);
+		return NULL;
+	}
+	return hctrl;
+}
+
+/* Release an unused host controller*/
+static void nvme_mdev_hctrl_free(struct kref *ref)
+{
+	struct nvme_mdev_hctrl *hctrl =
+		container_of(ref, struct nvme_mdev_hctrl, ref);
+
+	dev_info(hctrl->nvme_ctrl->dev, "mediated nvme support disabled");
+
+	nvme_put_ctrl(hctrl->nvme_ctrl);
+	hctrl->nvme_ctrl = NULL;
+	kfree(hctrl);
+}
+
+/* Lookup a host controller based on mdev parent device*/
+struct nvme_mdev_hctrl *nvme_mdev_hctrl_lookup_get(struct device *parent)
+{
+	struct nvme_mdev_hctrl *hctrl = NULL, *tmp;
+
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+	list_for_each_entry(tmp, &nvme_mdev_hctrl_list, link) {
+		if (tmp->nvme_ctrl->dev == parent) {
+			hctrl = tmp;
+			kref_get(&hctrl->ref);
+			break;
+		}
+	}
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+	return hctrl;
+}
+
+/* Release a held reference to a host controller*/
+void nvme_mdev_hctrl_put(struct nvme_mdev_hctrl *hctrl)
+{
+	kref_put(&hctrl->ref, nvme_mdev_hctrl_free);
+}
+
+/* Destroy a host controller. It might still be kept in zombie state
+ * if someone uses a reference to it
+ */
+static void nvme_mdev_hctrl_destroy(struct nvme_mdev_hctrl *hctrl)
+{
+	mutex_lock(&nvme_mdev_hctrl_list_mutex);
+	list_del(&hctrl->link);
+	mutex_unlock(&nvme_mdev_hctrl_list_mutex);
+
+	hctrl->removing = true;
+	mdev_unregister_device(hctrl->nvme_ctrl->dev);
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+/* Check how many host queues are still available */
+int nvme_mdev_hctrl_hqs_available(struct nvme_mdev_hctrl *hctrl)
+{
+	int ret;
+
+	mutex_lock(&hctrl->lock);
+	ret =  hctrl->nr_host_queues;
+	mutex_unlock(&hctrl->lock);
+	return ret;
+}
+
+/* Reserve N host IO queues, for later allocation to a specific user*/
+bool nvme_mdev_hctrl_hqs_reserve(struct nvme_mdev_hctrl *hctrl,
+				 unsigned int n)
+{
+	mutex_lock(&hctrl->lock);
+
+	if (n > hctrl->nr_host_queues) {
+		mutex_unlock(&hctrl->lock);
+		return false;
+	}
+
+	hctrl->nr_host_queues -= n;
+	mutex_unlock(&hctrl->lock);
+	return true;
+}
+
+/* Free N host IO queues, for allocation for other users*/
+void nvme_mdev_hctrl_hqs_unreserve(struct nvme_mdev_hctrl *hctrl,
+				   unsigned int n)
+{
+	mutex_lock(&hctrl->lock);
+	hctrl->nr_host_queues += n;
+	mutex_unlock(&hctrl->lock);
+}
+
+/* Allocate a host IO queue */
+int nvme_mdev_hctrl_hq_alloc(struct nvme_mdev_hctrl *hctrl)
+{
+	u16 qid = 0;
+	int ret = hctrl->nvme_ctrl->ops->ext_queue_alloc(hctrl->nvme_ctrl,
+			&qid);
+
+	if (ret)
+		return ret;
+	return qid;
+}
+
+/* Free an host IO queue */
+void nvme_mdev_hctrl_hq_free(struct nvme_mdev_hctrl *hctrl, u16 qid)
+{
+	hctrl->nvme_ctrl->ops->ext_queue_free(hctrl->nvme_ctrl, qid);
+}
+
+/* Check if we can submit another IO passthrough command */
+bool nvme_mdev_hctrl_hq_can_submit(struct nvme_mdev_hctrl *hctrl, u16 qid)
+{
+	return hctrl->nvme_ctrl->ops->ext_queue_full(hctrl->nvme_ctrl, qid);
+}
+
+/* Check if IO passthrough is supported for given IO optcode */
+bool nvme_mdev_hctrl_hq_check_op(struct nvme_mdev_hctrl *hctrl, u8 optcode)
+{
+	switch (optcode) {
+	case nvme_cmd_flush:
+	case nvme_cmd_read:
+	case nvme_cmd_write:
+		/* these are mandatory*/
+		return true;
+	case nvme_cmd_write_zeroes:
+		return (hctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES);
+	case nvme_cmd_dsm:
+		return (hctrl->oncs & NVME_CTRL_ONCS_DSM);
+	default:
+		return false;
+	}
+}
+
+/* Submit a IO passthrough command */
+int nvme_mdev_hctrl_hq_submit(struct nvme_mdev_hctrl *hctrl,
+			      u16 qid, u32 tag,
+			      struct nvme_command *cmd,
+			      struct nvme_ext_data_iter *datait)
+{
+	struct nvme_ctrl *ctrl = hctrl->nvme_ctrl;
+
+	return ctrl->ops->ext_queue_submit(ctrl, qid, tag, cmd, datait);
+}
+
+/* Poll for completion of IO passthrough commands */
+int nvme_mdev_hctrl_hq_poll(struct nvme_mdev_hctrl *hctrl,
+			    u32 qid,
+			    struct nvme_ext_cmd_result *results,
+			    unsigned int max_len)
+{
+	struct nvme_ctrl *ctrl = hctrl->nvme_ctrl;
+
+	return ctrl->ops->ext_queue_poll(ctrl, qid, results, max_len);
+}
+
+/* Destroy all host controllers */
+void nvme_mdev_hctrl_destroy_all(void)
+{
+	struct nvme_mdev_hctrl *hctrl = NULL, *tmp;
+
+	list_for_each_entry_safe(hctrl, tmp, &nvme_mdev_hctrl_list, link) {
+		list_del(&hctrl->link);
+		hctrl->removing = true;
+		mdev_unregister_device(hctrl->nvme_ctrl->dev);
+		nvme_mdev_hctrl_put(hctrl);
+	}
+}
+
+/* Get the mdev instance given it sysfs name */
+struct nvme_mdev_inst_type *nvme_mdev_inst_type_get(const char *name)
+{
+	int i;
+
+	for (i = 0; instance_types[i]; i++) {
+		const char *test =
+			name + strlen(name) - strlen(instance_types[i]->name);
+
+		if (strcmp(instance_types[i]->name, test) == 0)
+			return instance_types[i];
+	}
+	return NULL;
+}
+
+/* This shows name of the instance type */
+static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)
+{
+	return sprintf(buf, "%s\n", kobj->name);
+}
+static MDEV_TYPE_ATTR_RO(name);
+
+/* This shows description of the instance type */
+static ssize_t description_show(struct kobject *kobj,
+				struct device *dev, char *buf)
+{
+	struct nvme_mdev_inst_type *type = nvme_mdev_inst_type_get(kobj->name);
+
+	return sprintf(buf,
+		       "MDEV nvme device, using maximum %d hw submission queues\n",
+		       type->max_hw_queues);
+}
+static MDEV_TYPE_ATTR_RO(description);
+
+/* This shows the device API of the instance type */
+static ssize_t device_api_show(struct kobject *kobj,
+			       struct device *dev, char *buf)
+{
+	return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
+}
+static MDEV_TYPE_ATTR_RO(device_api);
+
+/* This shows how many instances of this instance type can be created  */
+static ssize_t available_instances_show(struct kobject *kobj,
+					struct device *dev, char *buf)
+{
+	struct nvme_mdev_inst_type *type = nvme_mdev_inst_type_get(kobj->name);
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(dev);
+	int count;
+
+	if (!hctrl)
+		return -ENODEV;
+
+	count = nvme_mdev_hctrl_hqs_available(hctrl);
+	do_div(count, type->max_hw_queues);
+
+	nvme_mdev_hctrl_put(hctrl);
+	return sprintf(buf, "%d\n", count);
+}
+static MDEV_TYPE_ATTR_RO(available_instances);
+
+static struct attribute *nvme_mdev_types_attrs[] = {
+	&mdev_type_attr_name.attr,
+	&mdev_type_attr_description.attr,
+	&mdev_type_attr_device_api.attr,
+	&mdev_type_attr_available_instances.attr,
+	NULL,
+};
+
+/* Undo the creation of mdev array of instance types */
+static void nvme_mdev_instance_types_fini(struct mdev_parent_ops *ops)
+{
+	int i;
+
+	for (i = 0; instance_types[i]; i++) {
+		struct nvme_mdev_inst_type *type = instance_types[i];
+
+		kfree(type->attrgroup);
+		kfree(type);
+	}
+
+	kfree(instance_types);
+	instance_types = NULL;
+
+	kfree(ops->supported_type_groups);
+	ops->supported_type_groups = NULL;
+}
+
+/* Create the array of mdev instance types from our array of them */
+static int nvme_mdev_instance_types_init(struct mdev_parent_ops *ops)
+{
+	unsigned int i;
+	struct nvme_mdev_inst_type *type;
+	struct attribute_group *attrgroup;
+
+	ops->supported_type_groups = kzalloc(sizeof(struct attribute_group *)
+			* (MAX_HOST_QUEUES + 1), GFP_KERNEL);
+
+	if (!ops->supported_type_groups)
+		return -ENOMEM;
+
+	instance_types = kzalloc(sizeof(struct nvme_mdev_inst_type *)
+			* MAX_HOST_QUEUES + 1, GFP_KERNEL);
+
+	if (!instance_types) {
+		kfree(ops->supported_type_groups);
+		ops->supported_type_groups = NULL;
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_HOST_QUEUES; i++) {
+		type = kzalloc(sizeof(*type), GFP_KERNEL);
+		if (!type) {
+			nvme_mdev_instance_types_fini(ops);
+			return -ENOMEM;
+		}
+		snprintf(type->name, sizeof(type->name), "%dQ_V1", i + 1);
+		type->max_hw_queues = i + 1;
+
+		attrgroup = kzalloc(sizeof(*attrgroup), GFP_KERNEL);
+		if (!attrgroup) {
+			kfree(type);
+			nvme_mdev_instance_types_fini(ops);
+			return -ENOMEM;
+		}
+
+		attrgroup->attrs = nvme_mdev_types_attrs;
+		attrgroup->name = type->name;
+		type->attrgroup = attrgroup;
+		instance_types[i] = type;
+		ops->supported_type_groups[i] = attrgroup;
+	}
+	return 0;
+}
+
+/* Updates in host controller state*/
+static void nvme_mdev_nvme_ctrl_state_changed(struct nvme_ctrl *ctrl)
+{
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(ctrl->dev);
+	struct nvme_mdev_vctrl *vctrl;
+
+	switch (ctrl->state) {
+	case NVME_CTRL_NEW:
+		/* do nothing as new controller is not yet initialized*/
+		break;
+
+	case NVME_CTRL_LIVE:
+		/* new controller is live, create a mdev for it*/
+		if (!hctrl) {
+			hctrl = nvme_mdev_hctrl_create(ctrl);
+			return;
+		/* a controller is live again after reset/reconnect/suspend*/
+		} else {
+			mutex_lock(&nvme_mdev_vctrl_list_mutex);
+			list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+				if (vctrl->hctrl == hctrl)
+					nvme_mdev_vctrl_resume(vctrl);
+			mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+		}
+		break;
+
+	case NVME_CTRL_RESETTING:
+	case NVME_CTRL_CONNECTING:
+	case NVME_CTRL_SUSPENDED:
+		/* controller is temporarily not usable, stop using its queues*/
+		if (!hctrl)
+			return;
+
+		mutex_lock(&nvme_mdev_vctrl_list_mutex);
+		list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+			if (vctrl->hctrl == hctrl)
+				nvme_mdev_vctrl_pause(vctrl);
+		mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+		break;
+
+	case NVME_CTRL_DELETING:
+	case NVME_CTRL_DEAD:
+	case NVME_CTRL_ADMIN_ONLY:
+		/* host nvme controller is dead, remove it*/
+		if (!hctrl)
+			return;
+		nvme_mdev_hctrl_destroy(hctrl);
+		break;
+	}
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+/* A host namespace might have its properties changed/removed.*/
+static void nvme_mdev_nvme_ctrl_ns_updated(struct nvme_ctrl *ctrl,
+					   u32 nsid, bool removed)
+{
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl = nvme_mdev_hctrl_lookup_get(ctrl->dev);
+
+	if (!hctrl)
+		return;
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_for_each_entry(vctrl, &nvme_mdev_vctrl_list, link)
+		if (vctrl->hctrl == hctrl)
+			nvme_mdev_vns_host_ns_update(vctrl, nsid, removed);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+	nvme_mdev_hctrl_put(hctrl);
+}
+
+static struct nvme_mdev_driver nvme_mdev_driver = {
+	.owner = THIS_MODULE,
+	.nvme_ctrl_state_changed = nvme_mdev_nvme_ctrl_state_changed,
+	.nvme_ns_state_changed = nvme_mdev_nvme_ctrl_ns_updated,
+};
+
+static int __init nvme_mdev_init(void)
+{
+	int ret;
+
+	nvme_mdev_instance_types_init(&mdev_fops);
+	ret = nvme_core_register_mdev_driver(&nvme_mdev_driver);
+	if (ret) {
+		nvme_mdev_instance_types_fini(&mdev_fops);
+		return ret;
+	}
+
+	pr_info("nvme_mdev " NVME_MDEV_FIRMWARE_VERSION " loaded\n");
+	return 0;
+}
+
+static void __exit nvme_mdev_exit(void)
+{
+	nvme_core_unregister_mdev_driver(&nvme_mdev_driver);
+	nvme_mdev_hctrl_destroy_all();
+	nvme_mdev_instance_types_fini(&mdev_fops);
+	pr_info("nvme_mdev unloaded\n");
+}
+
+MODULE_AUTHOR("Maxim Levitsky <mlevitsk@redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(NVME_MDEV_FIRMWARE_VERSION);
+
+module_init(nvme_mdev_init)
+module_exit(nvme_mdev_exit)
+
diff --git a/drivers/nvme/mdev/instance.c b/drivers/nvme/mdev/instance.c
new file mode 100644
index 000000000000..da523006aeda
--- /dev/null
+++ b/drivers/nvme/mdev/instance.c
@@ -0,0 +1,802 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Mediated NVMe instance VFIO code
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/vfio.h>
+#include <linux/sysfs.h>
+#include <linux/mdev.h>
+#include "priv.h"
+
+#define OFFSET_TO_REGION(offset) ((offset) >> 20)
+#define REGION_TO_OFFSET(nr) (((u64)nr) << 20)
+
+LIST_HEAD(nvme_mdev_vctrl_list);
+/*protects the list */
+DEFINE_MUTEX(nvme_mdev_vctrl_list_mutex);
+
+struct mdev_nvme_vfio_region_info {
+	struct vfio_region_info base;
+	struct vfio_region_info_cap_sparse_mmap mmap_cap;
+};
+
+/* User memory added*/
+static int nvme_mdev_map_notifier(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	struct vfio_iommu_type1_dma_map *map = data;
+	struct nvme_mdev_vctrl *vctrl =
+		container_of(nb, struct nvme_mdev_vctrl, vfio_map_notifier);
+
+	int ret = nvme_mdev_vctrl_viommu_map(vctrl, map->flags,
+			map->iova, map->size);
+	return ret ? NOTIFY_OK : notifier_from_errno(ret);
+}
+
+/* User memory removed*/
+static int nvme_mdev_unmap_notifier(struct notifier_block *nb,
+				    unsigned long action, void *data)
+{
+	struct nvme_mdev_vctrl *vctrl =
+		container_of(nb, struct nvme_mdev_vctrl, vfio_unmap_notifier);
+	struct vfio_iommu_type1_dma_unmap *unmap = data;
+
+	int ret = nvme_mdev_vctrl_viommu_unmap(vctrl, unmap->iova, unmap->size);
+
+	WARN_ON(ret <= 0);
+	return NOTIFY_OK;
+}
+
+/* Called when new mediated device is created */
+static int nvme_mdev_ops_create(struct kobject *kobj, struct mdev_device *mdev)
+{
+	int ret = 0;
+	const struct nvme_mdev_inst_type *type = NULL;
+	struct nvme_mdev_vctrl *vctrl;
+	struct nvme_mdev_hctrl *hctrl = NULL;
+
+	hctrl = nvme_mdev_hctrl_lookup_get(mdev_parent_dev(mdev));
+	if (!hctrl)
+		return -ENODEV;
+
+	type = nvme_mdev_inst_type_get(kobj->name);
+	vctrl = nvme_mdev_vctrl_create(mdev, hctrl, type->max_hw_queues);
+
+	if (IS_ERR(vctrl))
+		ret = PTR_ERR(vctrl);
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_add_tail(&vctrl->link, &nvme_mdev_vctrl_list);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+
+	nvme_mdev_hctrl_put(hctrl);
+	return ret;
+}
+
+/* Called when a mediated device is removed */
+static int nvme_mdev_ops_remove(struct mdev_device *mdev)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return nvme_mdev_vctrl_destroy(vctrl);
+}
+
+/* Called when new mediated device is opened by a user */
+static int nvme_mdev_ops_open(struct mdev_device *mdev)
+{
+	int ret;
+	unsigned long events;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	ret =  nvme_mdev_vctrl_open(vctrl);
+	if (ret)
+		return ret;
+
+	/* register unmap IOMMU notifier*/
+	vctrl->vfio_unmap_notifier.notifier_call = nvme_mdev_unmap_notifier;
+	events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
+
+	ret = vfio_register_notifier(mdev_dev(vctrl->mdev),
+				     VFIO_IOMMU_NOTIFY, &events,
+				     &vctrl->vfio_unmap_notifier);
+
+	if (ret != 0) {
+		nvme_mdev_vctrl_release(vctrl);
+		return ret;
+	}
+
+	/* register map IOMMU notifier*/
+	vctrl->vfio_map_notifier.notifier_call = nvme_mdev_map_notifier;
+	events = VFIO_IOMMU_NOTIFY_DMA_MAP;
+
+	ret = vfio_register_notifier(mdev_dev(vctrl->mdev),
+				     VFIO_IOMMU_NOTIFY, &events,
+				     &vctrl->vfio_map_notifier);
+
+	if (ret != 0) {
+		vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+					 VFIO_IOMMU_NOTIFY,
+					 &vctrl->vfio_unmap_notifier);
+		nvme_mdev_vctrl_release(vctrl);
+		return ret;
+	}
+	return ret;
+}
+
+/* Called when new mediated device is closed (last close of the user) */
+static void nvme_mdev_ops_release(struct mdev_device *mdev)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+	int ret;
+
+	ret = vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+				       VFIO_IOMMU_NOTIFY,
+				       &vctrl->vfio_unmap_notifier);
+	WARN_ON(ret);
+
+	ret = vfio_unregister_notifier(mdev_dev(vctrl->mdev),
+				       VFIO_IOMMU_NOTIFY,
+				       &vctrl->vfio_map_notifier);
+	WARN_ON(ret);
+
+	nvme_mdev_vctrl_release(vctrl);
+}
+
+/* Helper function for bar/pci config read/write access */
+static ssize_t nvme_mdev_access(struct nvme_mdev_vctrl *vctrl,
+				char *buf, size_t count,
+				loff_t pos, bool is_write)
+{
+	int index = OFFSET_TO_REGION(pos);
+	int ret = -EINVAL;
+	unsigned int offset;
+
+	if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].rw)
+		goto out;
+
+	offset = pos - REGION_TO_OFFSET(index);
+	if (offset + count > vctrl->regions[index].size)
+		goto out;
+
+	ret = vctrl->regions[index].rw(vctrl, offset, buf, count, is_write);
+out:
+	return ret;
+}
+
+/* Called when read() is done on the device */
+static ssize_t nvme_mdev_ops_read(struct mdev_device *mdev, char __user *buf,
+				  size_t count, loff_t *ppos)
+{
+	unsigned int done = 0;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	while (count) {
+		size_t filled;
+
+		if (count >= 4 && !(*ppos % 4)) {
+			u32 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		} else if (count >= 2 && !(*ppos % 2)) {
+			u16 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		} else {
+			u8 val;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, false);
+			if (ret <= 0)
+				goto read_err;
+			if (copy_to_user(buf, &val, sizeof(val)))
+				goto read_err;
+			filled = sizeof(val);
+		}
+
+		count -= filled;
+		done += filled;
+		*ppos += filled;
+		buf += filled;
+	}
+	return done;
+read_err:
+	return -EFAULT;
+}
+
+/* Called when write() is done on the device */
+static ssize_t nvme_mdev_ops_write(struct mdev_device *mdev,
+				   const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	unsigned int done = 0;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = mdev_to_vctrl(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	while (count) {
+		size_t filled;
+
+		if (count >= 4 && !(*ppos % 4)) {
+			u32 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		} else if (count >= 2 && !(*ppos % 2)) {
+			u16 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		} else {
+			u8 val;
+
+			if (copy_from_user(&val, buf, sizeof(val)))
+				goto write_err;
+			ret = nvme_mdev_access(vctrl, (char *)&val,
+					       sizeof(val), *ppos, true);
+			if (ret <= 0)
+				goto write_err;
+			filled = sizeof(val);
+		}
+		count -= filled;
+		done += filled;
+		*ppos += filled;
+		buf += filled;
+	}
+	return done;
+write_err:
+	return -EFAULT;
+}
+
+/*Helper for IRQ number VFIO query */
+static int nvme_mdev_irq_counts(struct nvme_mdev_vctrl *vctrl,
+				unsigned int irq_type)
+{
+	switch (irq_type) {
+	case VFIO_PCI_INTX_IRQ_INDEX:
+		return 1;
+	case VFIO_PCI_MSIX_IRQ_INDEX:
+		return MAX_VIRTUAL_IRQS;
+	case VFIO_PCI_REQ_IRQ_INDEX:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/* VFIO VFIO_IRQ_SET_ACTION_TRIGGER implementation */
+static int nvme_mdev_ioctl_set_irqs_trigger(struct nvme_mdev_vctrl *vctrl,
+					    u32 flags,
+					    unsigned int irq_type,
+					    unsigned int start,
+					    unsigned int count,
+					    void *data)
+{
+	u32 data_type = flags & VFIO_IRQ_SET_DATA_TYPE_MASK;
+	u8 *bools = NULL;
+	unsigned int i;
+	int ret = -EINVAL;
+
+	/* Asked to disable the current interrupt mode*/
+	if (data_type == VFIO_IRQ_SET_DATA_NONE && count == 0) {
+		switch (irq_type) {
+		case VFIO_PCI_REQ_IRQ_INDEX:
+			nvme_mdev_irqs_set_unplug_trigger(vctrl, -1);
+			return 0;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			nvme_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_INTX);
+			return 0;
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			nvme_mdev_irqs_disable(vctrl, NVME_MDEV_IMODE_MSIX);
+			return 0;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	if (start + count > nvme_mdev_irq_counts(vctrl, irq_type))
+		return -EINVAL;
+
+	switch (data_type) {
+	case VFIO_IRQ_SET_DATA_BOOL:
+		bools = (u8 *)data;
+		/*fallthrough*/
+	case VFIO_IRQ_SET_DATA_NONE:
+		if (irq_type == VFIO_PCI_REQ_IRQ_INDEX)
+			return -EINVAL;
+
+		for (i = 0 ; i < count ; i++) {
+			int index = start + i;
+
+			if (!bools || bools[i])
+				nvme_mdev_irq_trigger(vctrl, index);
+		}
+		return 0;
+
+	case VFIO_IRQ_SET_DATA_EVENTFD:
+		switch (irq_type) {
+		case VFIO_PCI_REQ_IRQ_INDEX:
+			return nvme_mdev_irqs_set_unplug_trigger(vctrl,
+							*(int32_t *)data);
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			ret = nvme_mdev_irqs_enable(vctrl,
+						    NVME_MDEV_IMODE_INTX);
+			break;
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			ret = nvme_mdev_irqs_enable(vctrl,
+						    NVME_MDEV_IMODE_MSIX);
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (ret)
+			return ret;
+
+		return nvme_mdev_irqs_set_triggers(vctrl, start,
+						   count, (int32_t *)data);
+	default:
+		return -EINVAL;
+	}
+}
+
+/* VFIO_DEVICE_GET_INFO ioctl implementation */
+static int nvme_mdev_ioctl_get_info(struct nvme_mdev_vctrl *vctrl,
+				    void __user *arg)
+{
+	struct vfio_device_info info;
+	unsigned int minsz = offsetofend(struct vfio_device_info, num_irqs);
+
+	if (copy_from_user(&info, (void __user *)arg, minsz))
+		return -EFAULT;
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	info.flags = VFIO_DEVICE_FLAGS_PCI | VFIO_DEVICE_FLAGS_RESET;
+	info.num_regions = VFIO_PCI_NUM_REGIONS;
+	info.num_irqs = VFIO_PCI_NUM_IRQS;
+
+	if (copy_to_user(arg, &info, minsz))
+		return -EFAULT;
+	return 0;
+}
+
+/* VFIO_DEVICE_GET_REGION_INFO ioctl implementation*/
+static int nvme_mdev_ioctl_get_reg_info(struct nvme_mdev_vctrl *vctrl,
+					void __user *arg)
+{
+	struct nvme_mdev_io_region *region;
+	struct mdev_nvme_vfio_region_info *info;
+	unsigned long minsz, outsz, maxsz;
+	int ret = 0;
+
+	minsz = offsetofend(struct vfio_region_info, offset);
+	maxsz = sizeof(struct mdev_nvme_vfio_region_info) +
+				sizeof(struct vfio_region_sparse_mmap_area);
+
+	info = kzalloc(maxsz, GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	if (copy_from_user(info, arg, minsz)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	outsz = info->base.argsz;
+	if (outsz < minsz || outsz > maxsz) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (info->base.index >= VFIO_PCI_NUM_REGIONS) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	region = &vctrl->regions[info->base.index];
+	info->base.offset = REGION_TO_OFFSET(info->base.index);
+	info->base.argsz = maxsz;
+	info->base.size = region->size;
+
+	info->base.flags = VFIO_REGION_INFO_FLAG_READ |
+				VFIO_REGION_INFO_FLAG_WRITE;
+
+	if (region->mmap_ops) {
+		info->base.flags |= (VFIO_REGION_INFO_FLAG_MMAP |
+						VFIO_REGION_INFO_FLAG_CAPS);
+
+		info->base.cap_offset =
+			offsetof(struct mdev_nvme_vfio_region_info, mmap_cap);
+
+		info->mmap_cap.header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
+		info->mmap_cap.header.version = 1;
+		info->mmap_cap.header.next = 0;
+		info->mmap_cap.nr_areas = 1;
+		info->mmap_cap.areas[0].offset = region->mmap_area_start;
+		info->mmap_cap.areas[0].size = region->mmap_area_size;
+	}
+
+	if (copy_to_user(arg, info, outsz))
+		ret = -EFAULT;
+out:
+	kfree(info);
+	return ret;
+}
+
+/* VFIO_DEVICE_GET_IRQ_INFO ioctl implementation */
+static int nvme_mdev_ioctl_get_irq_info(struct nvme_mdev_vctrl *vctrl,
+					void __user *arg)
+{
+	struct vfio_irq_info info;
+	unsigned int minsz = offsetofend(struct vfio_irq_info, count);
+
+	if (copy_from_user(&info, arg, minsz))
+		return -EFAULT;
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	info.count = nvme_mdev_irq_counts(vctrl, info.index);
+	info.flags = VFIO_IRQ_INFO_EVENTFD;
+
+	if (info.index == VFIO_PCI_INTX_IRQ_INDEX)
+		info.flags |= VFIO_IRQ_INFO_MASKABLE | VFIO_IRQ_INFO_AUTOMASKED;
+
+	if (copy_to_user(arg, &info, minsz))
+		return -EFAULT;
+	return 0;
+}
+
+/* VFIO VFIO_DEVICE_SET_IRQS ioctl implementation */
+static int nvme_mdev_ioctl_set_irqs(struct nvme_mdev_vctrl *vctrl,
+				    void __user *arg)
+{
+	int ret, irqcount;
+	struct vfio_irq_set hdr;
+	u8 *data = NULL;
+	size_t data_size = 0;
+	unsigned long minsz = offsetofend(struct vfio_irq_set, count);
+
+	if (copy_from_user(&hdr, arg, minsz))
+		return -EFAULT;
+
+	irqcount = nvme_mdev_irq_counts(vctrl, hdr.index);
+	ret = vfio_set_irqs_validate_and_prepare(&hdr,
+						 irqcount,
+						 VFIO_PCI_NUM_IRQS,
+						 &data_size);
+	if (ret)
+		return ret;
+
+	if (data_size) {
+		data = memdup_user((arg + minsz), data_size);
+		if (IS_ERR(data))
+			return PTR_ERR(data);
+	}
+
+	ret = -ENOTTY;
+	switch (hdr.index) {
+	case VFIO_PCI_INTX_IRQ_INDEX:
+	case VFIO_PCI_MSIX_IRQ_INDEX:
+	case VFIO_PCI_REQ_IRQ_INDEX:
+		switch (hdr.flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
+		case VFIO_IRQ_SET_ACTION_MASK:
+		case VFIO_IRQ_SET_ACTION_UNMASK:
+			// pretend to support this (even with eventfd)
+			ret = hdr.index == VFIO_PCI_INTX_IRQ_INDEX ?
+					0 : -EINVAL;
+			break;
+		case VFIO_IRQ_SET_ACTION_TRIGGER:
+			ret = nvme_mdev_ioctl_set_irqs_trigger(vctrl, hdr.flags,
+							       hdr.index,
+							       hdr.start,
+							       hdr.count,
+							       data);
+			break;
+		}
+		break;
+	}
+
+	kfree(data);
+	return ret;
+}
+
+/* ioctl() implementation */
+static long nvme_mdev_ops_ioctl(struct mdev_device *mdev, unsigned int cmd,
+				unsigned long arg)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	switch (cmd) {
+	case VFIO_DEVICE_GET_INFO:
+		return nvme_mdev_ioctl_get_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_GET_REGION_INFO:
+		return nvme_mdev_ioctl_get_reg_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_GET_IRQ_INFO:
+		return nvme_mdev_ioctl_get_irq_info(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_SET_IRQS:
+		return nvme_mdev_ioctl_set_irqs(vctrl, (void __user *)arg);
+	case VFIO_DEVICE_RESET:
+		nvme_mdev_vctrl_reset(vctrl);
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
+
+/* mmap() implementation (doorbell area) */
+static int nvme_mdev_ops_mmap(struct mdev_device *mdev,
+			      struct vm_area_struct *vma)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+	int index = OFFSET_TO_REGION((u64)vma->vm_pgoff << PAGE_SHIFT);
+	unsigned long size, start;
+
+	if (!vctrl)
+		return -EFAULT;
+
+	if (index >= VFIO_PCI_NUM_REGIONS || !vctrl->regions[index].mmap_ops)
+		return -EINVAL;
+
+	if (vma->vm_end < vma->vm_start)
+		return -EINVAL;
+
+	size = vma->vm_end - vma->vm_start;
+	start = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (start < vctrl->regions[index].mmap_area_start)
+		return -EINVAL;
+	if (size > vctrl->regions[index].mmap_area_size)
+		return -EINVAL;
+
+	if ((vma->vm_flags & VM_SHARED) == 0)
+		return -EINVAL;
+
+	vma->vm_ops = vctrl->regions[index].mmap_ops;
+	vma->vm_private_data = vctrl;
+	return 0;
+}
+
+/* Request removal of the device*/
+static void nvme_mdev_ops_request(struct mdev_device *mdev, unsigned int count)
+{
+	struct nvme_mdev_vctrl *vctrl = mdev_get_drvdata(mdev);
+
+	if (vctrl)
+		nvme_mdev_irq_raise_unplug_event(vctrl, count);
+}
+
+/* Adding a new namespace given host NS id and partition ID (e/g. n1p2 or n1) */
+static ssize_t add_namespace_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+	int ret;
+	unsigned long partno = 0, nsid;
+	char *buf_copy, *token, *tmp;
+
+	if (!vctrl)
+		return -ENODEV;
+
+	buf_copy = kstrdup(buf, GFP_KERNEL);
+	if (!buf_copy)
+		return -ENOMEM;
+
+	tmp = buf_copy;
+	if (tmp[0] != 'n') {
+		ret = -EINVAL;
+		goto out;
+	}
+	tmp++;
+
+	// read namespace ID (mandatory)
+	token = strsep(&tmp, "p");
+	if (!token) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = kstrtoul(token, 10, &nsid);
+	if (ret)
+		goto out;
+
+	// read partition ID (optional)
+	if (tmp) {
+		ret = kstrtoul(tmp, 10, &partno);
+		if (ret)
+			goto out;
+	}
+
+	// create the user namespace
+	ret = nvme_mdev_vns_open(vctrl, nsid, partno);
+	if (ret)
+		goto out;
+	ret = count;
+out:
+	kfree(buf_copy);
+	return ret;
+}
+static DEVICE_ATTR_WO(add_namespace);
+
+/* Remove a user namespace */
+static ssize_t remove_namespace_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	unsigned long user_nsid;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	ret = kstrtoul(buf, 10, &user_nsid);
+	if (ret)
+		return ret;
+
+	ret =  nvme_mdev_vns_destroy(vctrl, user_nsid);
+	if (ret)
+		return ret;
+	return count;
+}
+static DEVICE_ATTR_WO(remove_namespace);
+
+/* Show list of user namespaces */
+static ssize_t namespaces_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return nvme_mdev_vns_print_description(vctrl, buf, PAGE_SIZE - 1);
+}
+static DEVICE_ATTR_RO(namespaces);
+
+/* change the cpu binding of the IO threads*/
+static ssize_t iothread_cpu_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+	nvme_mdev_vctrl_bind_iothread(vctrl, val);
+	return count;
+}
+
+/* change the cpu binding of the IO threads*/
+static ssize_t
+iothread_cpu_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	return sprintf(buf, "%d\n", vctrl->iothread_cpu);
+}
+static DEVICE_ATTR_RW(iothread_cpu);
+
+/* change the cpu binding of the IO threads*/
+static ssize_t shadow_doorbell_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	bool val;
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+	ret = kstrtobool(buf, &val);
+	if (ret)
+		return ret;
+	ret = nvme_mdev_vctrl_set_shadow_doorbell_supported(vctrl, val);
+	if (ret)
+		return ret;
+	return count;
+}
+
+/* change the cpu binding of the IO threads*/
+static ssize_t shadow_doorbell_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct nvme_mdev_vctrl *vctrl = dev_to_vctrl(dev);
+
+	if (!vctrl)
+		return -ENODEV;
+
+	return sprintf(buf, "%d\n", vctrl->mmio.shadow_db_supported ? 1 : 0);
+}
+static DEVICE_ATTR_RW(shadow_doorbell);
+
+static struct attribute *nvme_mdev_dev_ns_atttributes[] = {
+	&dev_attr_add_namespace.attr,
+	&dev_attr_remove_namespace.attr,
+	&dev_attr_namespaces.attr,
+	NULL
+};
+
+static struct attribute *nvme_mdev_dev_settings_atttributes[] = {
+	&dev_attr_iothread_cpu.attr,
+	&dev_attr_shadow_doorbell.attr,
+	NULL
+};
+
+static const struct attribute_group nvme_mdev_ns_attr_group = {
+	.name = "namespaces",
+	.attrs = nvme_mdev_dev_ns_atttributes,
+};
+
+static const struct attribute_group nvme_mdev_setting_attr_group = {
+	.name = "settings",
+	.attrs = nvme_mdev_dev_settings_atttributes,
+};
+
+static const struct attribute_group *nvme_mdev_dev_attributte_groups[] = {
+	&nvme_mdev_ns_attr_group,
+	&nvme_mdev_setting_attr_group,
+	NULL,
+};
+
+struct mdev_parent_ops mdev_fops = {
+	.owner			= THIS_MODULE,
+	.create			= nvme_mdev_ops_create,
+	.remove			= nvme_mdev_ops_remove,
+	.open			= nvme_mdev_ops_open,
+	.release		= nvme_mdev_ops_release,
+	.read			= nvme_mdev_ops_read,
+	.write			= nvme_mdev_ops_write,
+	.mmap			= nvme_mdev_ops_mmap,
+	.ioctl			= nvme_mdev_ops_ioctl,
+	.request		= nvme_mdev_ops_request,
+	.mdev_attr_groups	= nvme_mdev_dev_attributte_groups,
+	.dev_attr_groups	= NULL,
+};
+
diff --git a/drivers/nvme/mdev/io.c b/drivers/nvme/mdev/io.c
new file mode 100644
index 000000000000..a731196d0365
--- /dev/null
+++ b/drivers/nvme/mdev/io.c
@@ -0,0 +1,563 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe IO command translation and polling IO thread
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include <linux/timekeeping.h>
+#include <linux/ktime.h>
+#include "priv.h"
+
+struct io_ctx {
+	struct nvme_mdev_hctrl *hctrl;
+	struct nvme_mdev_vctrl *vctrl;
+
+	const struct nvme_command *in;
+	struct nvme_command out;
+	struct nvme_mdev_vns *ns;
+	struct nvme_ext_data_iter udatait;
+	struct nvme_ext_data_iter *kdatait;
+
+	ktime_t last_io_t;
+	ktime_t last_admin_poll_time;
+	unsigned int idle_timeout_ms;
+	unsigned int admin_poll_rate_ms;
+	unsigned int arb_burst;
+};
+
+/* Handle read/write command.*/
+static int nvme_mdev_io_translate_rw(struct io_ctx *ctx)
+{
+	int ret;
+	const struct nvme_rw_command *in = &ctx->in->rw;
+
+	u64 slba = le64_to_cpu(in->slba);
+	u64 length = le16_to_cpu(in->length) + 1;
+	u16 control = le16_to_cpu(in->control);
+
+	_DBG(ctx->vctrl, "IOQ: READ/WRITE\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW14_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16, 0b1100000000111100))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (in->opcode == nvme_cmd_write && ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	if (!check_range(slba, length, ctx->ns->ns_size))
+		return DNR(NVME_SC_LBA_RANGE);
+
+	ctx->out.rw.slba = cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	ctx->out.rw.length = in->length;
+
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait, &in->dptr,
+					    length << ctx->ns->blksize_shift);
+	if (ret)
+		return nvme_mdev_translate_error(ret);
+
+	ctx->kdatait = &ctx->udatait;
+	if (control & ~(NVME_RW_LR | NVME_RW_FUA))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->out.rw.control = in->control;
+	return -1;
+}
+
+/*Handle flush command */
+static int nvme_mdev_io_translate_flush(struct io_ctx *ctx)
+{
+	ctx->kdatait = NULL;
+
+	_DBG(ctx->vctrl, "IOQ: FLUSH\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW10_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	return -1;
+}
+
+/* Handle write zeros command */
+static int nvme_mdev_io_translate_write_zeros(struct io_ctx *ctx)
+{
+	const struct nvme_write_zeroes_cmd *in = &ctx->in->write_zeroes;
+	u64 slba = le64_to_cpu(in->slba);
+	u64 length = le16_to_cpu(in->length) + 1;
+	u16 control = le16_to_cpu(in->control);
+
+	_DBG(ctx->vctrl, "IOQ: WRITE_ZEROS\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_DPTR |
+				   RSRV_MPTR | RSRV_DW13_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!nvme_mdev_hctrl_hq_check_op(ctx->hctrl, in->opcode))
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+	ctx->kdatait = NULL;
+
+	if (!check_range(slba, length, ctx->ns->ns_size))
+		return DNR(NVME_SC_LBA_RANGE);
+
+	ctx->out.write_zeroes.slba =
+		cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	ctx->out.write_zeroes.length = in->length;
+
+	if (control & ~(NVME_RW_LR | NVME_RW_FUA | NVME_WZ_DEAC))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	ctx->out.write_zeroes.control = in->control;
+	return -1;
+}
+
+/* Handle dataset management command */
+static int nvme_mdev_io_translate_dsm(struct io_ctx *ctx)
+{
+	unsigned int size, i, nr;
+	int ret;
+	const struct nvme_dsm_cmd *in = &ctx->in->dsm;
+	struct nvme_dsm_range *data_ptr;
+
+	_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT\n");
+
+	if (!check_reserved_dwords(ctx->in->dwords, 16,
+				   RSRV_DW23 | RSRV_MPTR | RSRV_DW12_15))
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (le32_to_cpu(in->nr) & 0xFFFFFF00)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	if (!nvme_mdev_hctrl_hq_check_op(ctx->hctrl, in->opcode))
+		return DNR(NVME_SC_INVALID_OPCODE);
+
+	if (ctx->ns->readonly)
+		return DNR(NVME_SC_READ_ONLY);
+
+	nr = le32_to_cpu(in->nr) + 1;
+	size = nr * sizeof(struct nvme_dsm_range);
+
+	ctx->out.dsm.nr = in->nr;
+	ret = nvme_mdev_udata_iter_set_dptr(&ctx->udatait, &in->dptr, size);
+	if (ret)
+		goto error;
+
+	ctx->kdatait = nvme_mdev_kdata_iter_alloc(&ctx->vctrl->viommu, size);
+	if (!ctx->kdatait)
+		return NVME_SC_INTERNAL;
+
+	_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT: NR=%d\n", nr);
+
+	ret = nvme_mdev_read_from_udata(ctx->kdatait->kmem.data, &ctx->udatait,
+					size);
+	if (ret)
+		goto error2;
+
+	data_ptr = (struct nvme_dsm_range *)ctx->kdatait->kmem.data;
+
+	for (i = 0 ; i < nr; i++) {
+		u64 slba = le64_to_cpu(data_ptr[i].slba);
+		/* looks like not zero based value*/
+		u32 nlb = le32_to_cpu(data_ptr[i].nlb);
+
+		if (!check_range(slba, nlb, ctx->ns->ns_size))
+			goto error2;
+
+		_DBG(ctx->vctrl, "IOQ: DSM_MANAGEMENT: RANGE 0x%llx-0x%x\n",
+		     slba, nlb);
+
+		data_ptr[i].slba = cpu_to_le64(slba + ctx->ns->host_lba_offset);
+	}
+
+	ctx->out.dsm.attributes = in->attributes;
+	return -1;
+error2:
+	ctx->kdatait->release(ctx->kdatait);
+error:
+	return nvme_mdev_translate_error(ret);
+}
+
+/* Process one new command in the io queue*/
+static int nvme_mdev_io_translate_cmd(struct io_ctx *ctx)
+{
+	memset(&ctx->out, 0, sizeof(ctx->out));
+	/* translate opcode */
+	ctx->out.common.opcode = ctx->in->common.opcode;
+
+	/* check flags */
+	if (ctx->in->common.flags != 0)
+		return DNR(NVME_SC_INVALID_FIELD);
+
+	/* namespace*/
+	ctx->ns = nvme_mdev_vns_from_vnsid(ctx->vctrl,
+					   le32_to_cpu(ctx->in->rw.nsid));
+	if (!ctx->ns) {
+		_DBG(ctx->vctrl, "IOQ: invalid NSID\n");
+		return DNR(NVME_SC_INVALID_NS);
+	}
+
+	if (!ctx->ns->readonly && bdev_read_only(ctx->ns->host_part))
+		ctx->ns->readonly = true;
+
+	ctx->out.common.nsid = cpu_to_le32(ctx->ns->host_nsid);
+
+	switch (ctx->in->common.opcode) {
+	case nvme_cmd_flush:
+		return nvme_mdev_io_translate_flush(ctx);
+	case nvme_cmd_read:
+		return nvme_mdev_io_translate_rw(ctx);
+	case nvme_cmd_write:
+		return nvme_mdev_io_translate_rw(ctx);
+	case nvme_cmd_write_zeroes:
+		return nvme_mdev_io_translate_write_zeros(ctx);
+	case nvme_cmd_dsm:
+		return nvme_mdev_io_translate_dsm(ctx);
+	default:
+		return DNR(NVME_SC_INVALID_OPCODE);
+	}
+}
+
+static bool nvme_mdev_io_process_sq(struct io_ctx *ctx, u16 sqid)
+{
+	struct nvme_vsq *vsq = &ctx->vctrl->vsqs[sqid];
+	u16 ucid;
+	int ret;
+
+	/* If host queue is full, we can't process a command
+	 * as a command will likely result in passthrough
+	 */
+	if (!nvme_mdev_hctrl_hq_can_submit(ctx->hctrl, vsq->hsq))
+		return false;
+
+	/* read the command */
+	ctx->in = nvme_mdev_vsq_get_cmd(ctx->vctrl, vsq);
+	if (!ctx->in)
+		return false;
+	ucid = le16_to_cpu(ctx->in->common.command_id);
+
+	/* translate the command */
+	ret = nvme_mdev_io_translate_cmd(ctx);
+	if (ret != -1) {
+		_DBG(ctx->vctrl,
+		     "IOQ: QID %d CID %d FAILED: status 0x%x (translate)\n",
+		     sqid, ucid, ret);
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, sqid, ucid, ret);
+		return true;
+	}
+
+	/*passthrough*/
+	ret = nvme_mdev_hctrl_hq_submit(ctx->hctrl,
+					vsq->hsq,
+					(((u32)vsq->qid) << 16) | ((u32)ucid),
+					&ctx->out,
+					ctx->kdatait);
+	if (ret) {
+		ret = nvme_mdev_translate_error(ret);
+
+		_DBG(ctx->vctrl,
+		     "IOQ: QID %d CID %d FAILED: status 0x%x (host submit)\n",
+		     sqid, ucid, ret);
+
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, sqid, ucid, ret);
+	}
+	return true;
+}
+
+/* process host replies to the passed through commands */
+static int nvme_mdev_io_process_hwq(struct io_ctx *ctx, u16 hwq)
+{
+	int n, i;
+	struct nvme_ext_cmd_result res[16];
+
+	/* process the completions from the hardware */
+	n = nvme_mdev_hctrl_hq_poll(ctx->hctrl, hwq, res, 16);
+	if (n == -1)
+		return -1;
+
+	for (i = 0; i < n; i++) {
+		u16 qid = res[i].tag >> 16;
+		u16 cid = res[i].tag & 0xFFFF;
+		u16 status = res[i].status;
+
+		if (status != 0)
+			_DBG(ctx->vctrl,
+			     "IOQ: QID %d CID %d FAILED: status 0x%x (host response)\n",
+			     qid, cid, status);
+
+		nvme_mdev_vsq_cmd_done_io(ctx->vctrl, qid, cid, status);
+	}
+	return n;
+}
+
+/* Check if we need to read a command from the admin queue */
+static bool nvme_mdev_adm_needs_processing(struct io_ctx *ctx)
+{
+	if (!timeout(ctx->last_admin_poll_time,
+		     ctx->vctrl->now, ctx->admin_poll_rate_ms))
+		return false;
+
+	if (nvme_mdev_vsq_has_data(ctx->vctrl, &ctx->vctrl->vsqs[0]))
+		return true;
+
+	ctx->last_admin_poll_time = ctx->vctrl->now;
+	return false;
+}
+
+/* do polling till one of events stops it */
+static void nvme_mdev_io_maintask(struct io_ctx *ctx)
+{
+	struct nvme_mdev_vctrl *vctrl = ctx->vctrl;
+	u16 i, cqid, sqid, hsqcnt;
+	u16 hsqs[MAX_HOST_QUEUES];
+	bool idle = false;
+
+	hsqcnt = nvme_mdev_vctrl_hqs_list(vctrl, hsqs);
+	ctx->arb_burst = 1 << ctx->vctrl->arb_burst_shift;
+
+	/* can't stop polling when shadow db not enabled */
+	ctx->idle_timeout_ms = vctrl->mmio.shadow_db_en ? poll_timeout_ms : 0;
+	ctx->admin_poll_rate_ms = admin_poll_rate_ms;
+
+	vctrl->now = ktime_get();
+	ctx->last_admin_poll_time = vctrl->now;
+	ctx->last_io_t = vctrl->now;
+
+	/* main loop */
+	while (!kthread_should_park()) {
+		vctrl->now = ktime_get();
+
+		/* check if we have to exit to support admin polling */
+		if (!vctrl->mmio.shadow_db_supported)
+			if (nvme_mdev_adm_needs_processing(ctx))
+				break;
+
+		/* process the submission queues*/
+		sqid = 1;
+		for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+			for (i = 0 ; i < ctx->arb_burst ; i++)
+				if (!nvme_mdev_io_process_sq(ctx, sqid))
+					break;
+
+		/* process the completions from the guest*/
+		cqid = 1;
+		for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+			nvme_mdev_vcq_process(vctrl, cqid, true);
+
+		/* process the completions from the hardware*/
+		for (i = 0 ; i < hsqcnt ; i++)
+			if (nvme_mdev_io_process_hwq(ctx, hsqs[i]) > 0)
+				ctx->last_io_t = vctrl->now;
+
+		/* Check if we need to stop polling*/
+		if (ctx->idle_timeout_ms) {
+			if (timeout(ctx->last_io_t,
+				    vctrl->now, ctx->idle_timeout_ms)) {
+				idle = true;
+				break;
+			}
+		}
+		cond_resched();
+	}
+
+	/* Drain the host IO */
+	for (;;) {
+		bool pending_io = false;
+
+		vctrl->now = ktime_get_coarse_boottime();
+
+		if (nvme_mdev_vctrl_is_dead(vctrl) || ctx->hctrl->removing) {
+			idle = false;
+			break;
+		}
+
+		for (i = 0; i < hsqcnt; i++) {
+			int n = nvme_mdev_io_process_hwq(ctx, hsqs[i]);
+
+			if (n != -1)
+				pending_io = true;
+			if (n > 0)
+				ctx->last_io_t = vctrl->now;
+		}
+
+		if (!pending_io)
+			break;
+
+		cond_resched();
+
+		if (!timeout(ctx->last_io_t, vctrl->now, io_timeout_ms))
+			continue;
+
+		_WARN(ctx->vctrl, "IO: skipping flush - host IO timeout\n");
+		idle = false;
+		break;
+	}
+
+	/* Drain all the pending completion interrupts to the guest*/
+	cqid = 1;
+	for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		if (nvme_mdev_vcq_flush(vctrl, cqid))
+			idle = false;
+
+	/* Park IO thread if IO is truly idle*/
+	if (idle) {
+		/* don't bother going idle if someone holds the vctrl
+		 * lock. It might try to park us, and thus
+		 * cause a deadlock
+		 */
+		if (!mutex_trylock(&vctrl->lock))
+			return;
+
+		sqid = 1;
+		for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+			if (!nvme_mdev_vsq_suspend_io(vctrl, sqid)) {
+				idle = false;
+				break;
+			}
+
+		if (idle) {
+			_DBG(ctx->vctrl, "IO: self-parking\n");
+			vctrl->io_idle = true;
+			nvme_mdev_io_pause(vctrl);
+		}
+
+		mutex_unlock(&vctrl->lock);
+	}
+
+	/* Admin poll for cases when shadow doorbell is not supported */
+	if (!vctrl->mmio.shadow_db_supported) {
+		if (mutex_trylock(&vctrl->lock)) {
+			nvme_mdev_vcq_process(vctrl, 0, false);
+			nvme_mdev_adm_process_sq(ctx->vctrl);
+			ctx->last_admin_poll_time = vctrl->now;
+			mutex_unlock(&ctx->vctrl->lock);
+		}
+	}
+}
+
+/* the main IO thread */
+static int nvme_mdev_io_polling_thread(void *data)
+{
+	struct io_ctx ctx;
+
+	if (kthread_should_stop())
+		return 0;
+
+	memset(&ctx, 0, sizeof(struct io_ctx));
+	ctx.vctrl = (struct nvme_mdev_vctrl *)data;
+	ctx.hctrl = ctx.vctrl->hctrl;
+	nvme_mdev_udata_iter_setup(&ctx.vctrl->viommu, &ctx.udatait);
+
+	_DBG(ctx.vctrl, "IO: iothread started\n");
+
+	for (;;) {
+		if (kthread_should_park()) {
+			_DBG(ctx.vctrl, "IO: iothread parked\n");
+			kthread_parkme();
+		}
+
+		if (kthread_should_stop())
+			break;
+
+		nvme_mdev_io_maintask(&ctx);
+	}
+
+	_DBG(ctx.vctrl, "IO: iothread stopped\n");
+	return 0;
+}
+
+/* Kick the IO thread into running state*/
+void nvme_mdev_io_resume(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!vctrl->iothread || !vctrl->iothread_parked)
+		return;
+	if (vctrl->io_idle || vctrl->vctrl_paused)
+		return;
+
+	vctrl->iothread_parked = false;
+	/* has memory barrier*/
+	kthread_unpark(vctrl->iothread);
+}
+
+/* Pause the IO thread */
+void nvme_mdev_io_pause(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!vctrl->iothread || vctrl->iothread_parked)
+		return;
+
+	vctrl->iothread_parked = true;
+	kthread_park(vctrl->iothread);
+}
+
+/* setup the main IO thread */
+int nvme_mdev_io_create(struct nvme_mdev_vctrl *vctrl, unsigned int cpu)
+{
+	/*TODOLATER: IO: Better thread name*/
+	char name[TASK_COMM_LEN];
+
+	_DBG(vctrl, "IO: creating the polling iothread\n");
+
+	if (WARN_ON(vctrl->iothread))
+		return -EINVAL;
+
+	snprintf(name, sizeof(name), "nvme%d_poll_io", vctrl->hctrl->id);
+
+	vctrl->iothread_cpu = cpu;
+	vctrl->iothread_parked = false;
+	vctrl->io_idle = true;
+
+	vctrl->iothread = kthread_create_on_node(nvme_mdev_io_polling_thread,
+						 vctrl,
+						 vctrl->hctrl->node,
+						 name);
+	if (IS_ERR(vctrl->iothread)) {
+		vctrl->iothread = NULL;
+		return PTR_ERR(vctrl->iothread);
+	}
+
+	kthread_bind(vctrl->iothread, cpu);
+
+	if (vctrl->io_idle) {
+		vctrl->iothread_parked = true;
+		kthread_park(vctrl->iothread);
+		return 0;
+	}
+
+	wake_up_process(vctrl->iothread);
+	return 0;
+}
+
+/* End the  main IO thread */
+void nvme_mdev_io_free(struct nvme_mdev_vctrl *vctrl)
+{
+	int ret;
+
+	_DBG(vctrl, "IO: destroying the polling iothread\n");
+
+	lockdep_assert_held(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+	ret = kthread_stop(vctrl->iothread);
+	WARN_ON(ret);
+	vctrl->iothread = NULL;
+}
+
+void nvme_mdev_assert_io_not_running(struct nvme_mdev_vctrl *vctrl)
+{
+	if (WARN_ON(vctrl->iothread && !vctrl->iothread_parked))
+		nvme_mdev_io_pause(vctrl);
+}
diff --git a/drivers/nvme/mdev/irq.c b/drivers/nvme/mdev/irq.c
new file mode 100644
index 000000000000..5809cdb4d84c
--- /dev/null
+++ b/drivers/nvme/mdev/irq.c
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller IRQ implementation (MSIx and INTx)
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* Setup the interrupt subsystem */
+void nvme_mdev_irqs_setup(struct nvme_mdev_vctrl *vctrl)
+{
+	vctrl->irqs.mode = NVME_MDEV_IMODE_NONE;
+	vctrl->irqs.irq_coalesc_max = 1;
+}
+
+/* Enable INTx or MSIx interrupts  */
+static int __nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+				   enum nvme_mdev_irq_mode mode)
+{
+	if (vctrl->irqs.mode == mode)
+		return 0;
+	if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE)
+		return -EBUSY;
+
+	if (mode == NVME_MDEV_IMODE_INTX)
+		_DBG(vctrl, "IRQ: enable INTx interrupts\n");
+	else if (mode == NVME_MDEV_IMODE_MSIX)
+		_DBG(vctrl, "IRQ: enable MSIX interrupts\n");
+	else
+		WARN_ON(1);
+
+	nvme_mdev_io_pause(vctrl);
+	vctrl->irqs.mode = mode;
+	nvme_mdev_io_resume(vctrl);
+	return 0;
+}
+
+int nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_mdev_irq_mode mode)
+{
+	int retval = 0;
+
+	mutex_lock(&vctrl->lock);
+	retval = __nvme_mdev_irqs_enable(vctrl, mode);
+	mutex_unlock(&vctrl->lock);
+	return retval;
+}
+
+/* Disable INTx or MSIx interrupts  */
+static void __nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+				     enum nvme_mdev_irq_mode mode)
+{
+	unsigned int i;
+
+	if (vctrl->irqs.mode == NVME_MDEV_IMODE_NONE)
+		return;
+	if (vctrl->irqs.mode != mode)
+		return;
+
+	if (vctrl->irqs.mode == NVME_MDEV_IMODE_INTX)
+		_DBG(vctrl, "IRQ: disable INTx interrupts\n");
+	else if (vctrl->irqs.mode == NVME_MDEV_IMODE_MSIX)
+		_DBG(vctrl, "IRQ: disable MSIX interrupts\n");
+	else
+		WARN_ON(1);
+
+	nvme_mdev_io_pause(vctrl);
+
+	for (i = 0; i < MAX_VIRTUAL_IRQS; i++) {
+		struct nvme_mdev_user_irq *vec = &vctrl->irqs.vecs[i];
+
+		if (vec->trigger) {
+			eventfd_ctx_put(vec->trigger);
+			vec->trigger = NULL;
+		}
+		vec->irq_pending_cnt = 0;
+		vec->irq_time = 0;
+	}
+	vctrl->irqs.mode = NVME_MDEV_IMODE_NONE;
+	nvme_mdev_io_resume(vctrl);
+}
+
+void nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+			    enum nvme_mdev_irq_mode mode)
+{
+	mutex_lock(&vctrl->lock);
+	__nvme_mdev_irqs_disable(vctrl, mode);
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Set eventfd triggers for INTx or MSIx interrupts */
+int nvme_mdev_irqs_set_triggers(struct nvme_mdev_vctrl *vctrl,
+				int start, int count, int32_t *fds)
+{
+	unsigned int i;
+
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+
+	for (i = 0; i < count; i++) {
+		int irqindex = start + i;
+		struct eventfd_ctx *trigger;
+		struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[irqindex];
+
+		if (irq->trigger) {
+			eventfd_ctx_put(irq->trigger);
+			irq->trigger = NULL;
+		}
+
+		if (fds[i] < 0)
+			continue;
+
+		trigger = eventfd_ctx_fdget(fds[i]);
+		if (IS_ERR(trigger))
+			return PTR_ERR(trigger);
+
+		irq->trigger = trigger;
+	}
+	nvme_mdev_io_resume(vctrl);
+	mutex_unlock(&vctrl->lock);
+	return 0;
+}
+
+/* Set eventfd trigger for unplug interrupt */
+static int __nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+					       int32_t fd)
+{
+	struct eventfd_ctx *trigger;
+
+	if (vctrl->irqs.request_trigger) {
+		_DBG(vctrl, "IRQ: clear hotplug trigger\n");
+		eventfd_ctx_put(vctrl->irqs.request_trigger);
+		vctrl->irqs.request_trigger = NULL;
+	}
+
+	if (fd < 0)
+		return 0;
+
+	_DBG(vctrl, "IRQ: set hotplug trigger\n");
+
+	trigger = eventfd_ctx_fdget(fd);
+	if (IS_ERR(trigger))
+		return PTR_ERR(trigger);
+
+	vctrl->irqs.request_trigger = trigger;
+	return 0;
+}
+
+int nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+				      int32_t fd)
+{
+	int retval;
+
+	mutex_lock(&vctrl->lock);
+	retval = __nvme_mdev_irqs_set_unplug_trigger(vctrl, fd);
+	mutex_unlock(&vctrl->lock);
+	return retval;
+}
+
+/* Reset the interrupts subsystem */
+void nvme_mdev_irqs_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	int i;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (vctrl->irqs.mode != NVME_MDEV_IMODE_NONE)
+		__nvme_mdev_irqs_disable(vctrl, vctrl->irqs.mode);
+
+	__nvme_mdev_irqs_set_unplug_trigger(vctrl, -1);
+
+	for (i = 0; i < MAX_VIRTUAL_IRQS; i++) {
+		struct nvme_mdev_user_irq *vec = &vctrl->irqs.vecs[i];
+
+		vec->irq_coalesc_en = false;
+		vec->irq_pending_cnt = 0;
+		vec->irq_time = 0;
+	}
+
+	vctrl->irqs.irq_coalesc_time_us = 0;
+}
+
+/* Check if interrupt can be coalesced */
+static bool nvme_mdev_irq_coalesce(struct nvme_mdev_vctrl *vctrl,
+				   struct nvme_mdev_user_irq *irq)
+{
+	s64 delta;
+
+	if (!irq->irq_coalesc_en)
+		return false;
+
+	if (irq->irq_pending_cnt >= vctrl->irqs.irq_coalesc_max)
+		return false;
+
+	delta = ktime_us_delta(vctrl->now, irq->irq_time);
+	return (delta < vctrl->irqs.irq_coalesc_time_us);
+}
+
+void nvme_mdev_irq_raise_unplug_event(struct nvme_mdev_vctrl *vctrl,
+				      unsigned int count)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->irqs.request_trigger) {
+		if (!(count % 10))
+			dev_notice_ratelimited(mdev_dev(vctrl->mdev),
+					       "Relaying device request to user (#%u)\n",
+					       count);
+
+		eventfd_signal(vctrl->irqs.request_trigger, 1);
+
+	} else if (count == 0) {
+		dev_notice(mdev_dev(vctrl->mdev),
+			   "No device request channel registered, blocked until released by user\n");
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Raise an interrupt */
+void nvme_mdev_irq_raise(struct nvme_mdev_vctrl *vctrl, unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	irq->irq_pending_cnt++;
+}
+
+/* Unraise an interrupt */
+void nvme_mdev_irq_clear(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	irq->irq_time = vctrl->now;
+	irq->irq_pending_cnt = 0;
+}
+
+/* Directly trigger an interrupt without affecting irq coalescing settings */
+void nvme_mdev_irq_trigger(struct nvme_mdev_vctrl *vctrl,
+			   unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	if (irq->trigger)
+		eventfd_signal(irq->trigger, 1);
+}
+
+/* Trigger previously raised interrupt */
+void nvme_mdev_irq_cond_trigger(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index)
+{
+	struct nvme_mdev_user_irq *irq = &vctrl->irqs.vecs[index];
+
+	if (irq->irq_pending_cnt == 0)
+		return;
+
+	if (!nvme_mdev_irq_coalesce(vctrl, irq)) {
+		nvme_mdev_irq_trigger(vctrl, index);
+		nvme_mdev_irq_clear(vctrl, index);
+	}
+}
diff --git a/drivers/nvme/mdev/mdev.h b/drivers/nvme/mdev/mdev.h
new file mode 100644
index 000000000000..d139e090520e
--- /dev/null
+++ b/drivers/nvme/mdev/mdev.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * NVME VFIO mediated driver
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#ifndef _MDEV_NVME_MDEV_H
+#define _MDEV_NVME_MDEV_H
+
+#include <linux/kernel.h>
+#include <linux/byteorder/generic.h>
+#include <linux/nvme.h>
+
+struct page_map {
+	void *kmap;
+	struct page *page;
+	dma_addr_t iova;
+};
+
+struct user_prplist {
+	/* used by user data iterator*/
+	struct page_map page;
+	unsigned int index;	/* index of current entry */
+};
+
+struct kernel_data {
+	/* used by kernel data iterator*/
+	void		*data;
+	unsigned int	size;
+	dma_addr_t	dma_addr;
+};
+
+struct nvme_ext_data_iter {
+	/* private */
+	struct nvme_mdev_viommu *viommu;
+	union {
+		const union nvme_data_ptr *dptr;
+		struct user_prplist uprp;
+		struct kernel_data kmem;
+	};
+
+	/* user interface */
+	u64		count;	/* number of data pages, yet to be covered */
+
+	phys_addr_t	physical; /* iterator physical address value*/
+	dma_addr_t	host_iova; /* iterator dma address value*/
+
+	/* moves iterator to the next item */
+	int (*next)(struct nvme_ext_data_iter *data_iter);
+
+	/* if != NULL, user should call this when it done with data
+	 * pointed by the iterator
+	 */
+	void (*release)(struct nvme_ext_data_iter *data_iter);
+};
+#endif
diff --git a/drivers/nvme/mdev/mmio.c b/drivers/nvme/mdev/mmio.c
new file mode 100644
index 000000000000..cf03c1f22f4c
--- /dev/null
+++ b/drivers/nvme/mdev/mmio.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller MMIO implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include "priv.h"
+
+#define DB_AREA_SIZE (MAX_VIRTUAL_QUEUES * 2 * (4 << DB_STRIDE_SHIFT))
+#define DB_MASK ((4 << DB_STRIDE_SHIFT) - 1)
+#define MMIO_BAR_SIZE __roundup_pow_of_two(NVME_REG_DBS + DB_AREA_SIZE)
+
+/* Put the controller into fatal error state. Only way out is reset */
+static void nvme_mdev_mmio_fatal_error(struct nvme_mdev_vctrl *vctrl)
+{
+	if (vctrl->mmio.csts & NVME_CSTS_CFS)
+		return;
+
+	vctrl->mmio.csts |= NVME_CSTS_CFS;
+	nvme_mdev_io_pause(vctrl);
+
+	if (vctrl->mmio.csts & NVME_CSTS_RDY)
+		nvme_mdev_vctrl_disable(vctrl);
+}
+
+/* This sends an generic error notification to the user */
+static void nvme_mdev_mmio_error(struct nvme_mdev_vctrl *vctrl,
+				 enum nvme_async_event info)
+{
+	nvme_mdev_event_send(vctrl, NVME_AER_TYPE_ERROR, info);
+}
+
+/* This is memory fault handler for the mmap area of the doorbells*/
+static vm_fault_t nvme_mdev_mmio_dbs_mmap_fault(struct vm_fault *vmf)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct nvme_mdev_vctrl *vctrl = vma->vm_private_data;
+
+	/* DB area is just one page, starting at offset 4096 of the mmio*/
+	if (WARN_ON(vmf->pgoff != 1))
+		return VM_FAULT_SIGBUS;
+
+	get_page(vctrl->mmio.dbs_page);
+	vmf->page = vctrl->mmio.dbs_page;
+	return 0;
+}
+
+static const struct vm_operations_struct nvme_mdev_mmio_dbs_vm_ops = {
+	.fault = nvme_mdev_mmio_dbs_mmap_fault,
+};
+
+/* check that user db write is valid and send an error if not*/
+bool nvme_mdev_mmio_db_check(struct nvme_mdev_vctrl *vctrl,
+			     u16 qid, u16 size, u16 db)
+{
+	if (get_current() != vctrl->iothread)
+		lockdep_assert_held(&vctrl->lock);
+
+	if (db < size)
+		return true;
+	if (qid == 0) {
+		_DBG(vctrl, "MMIO: invalid admin DB write - fatal error\n");
+		nvme_mdev_mmio_fatal_error(vctrl);
+		return false;
+	}
+
+	_DBG(vctrl, "MMIO: invalid DB value write qid=%d, size=%d, value=%d\n",
+	     qid, size, db);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_VALUE);
+	return false;
+}
+
+/* handle submission queue doorbell write */
+static void nvme_mdev_mmio_db_write_sq(struct nvme_mdev_vctrl *vctrl,
+				       u32 qid, u32 val)
+{
+	_DBG(vctrl, "MMIO: doorbell SQID %d, DB write %d\n", qid, val);
+
+	lockdep_assert_held(&vctrl->lock);
+	/* check if the db belongs to a valid queue */
+	if (qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vsq_en))
+		goto err_db;
+
+	/* emulate the shadow doorbell functionality */
+	if (!vctrl->mmio.shadow_db_en || qid == 0)
+		vctrl->mmio.dbs[qid].sqt = cpu_to_le32(val & 0x0000FFFF);
+
+	if (qid != 0)
+		vctrl->io_idle = false;
+
+	if (vctrl->vctrl_paused || !vctrl->mmio.shadow_db_supported)
+		return;
+
+	qid ? nvme_mdev_io_resume(vctrl) : nvme_mdev_adm_process_sq(vctrl);
+	return;
+err_db:
+
+	_DBG(vctrl, "MMIO: inactive/invalid SQ DB write qid=%d, value=%d\n",
+	     qid, val);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_REG);
+}
+
+/* handle doorbell write */
+static void nvme_mdev_mmio_db_write_cq(struct nvme_mdev_vctrl *vctrl,
+				       u32 qid, u32 val)
+{
+	_DBG(vctrl, "MMIO: doorbell CQID %d, DB write %d\n", qid, val);
+
+	lockdep_assert_held(&vctrl->lock);
+	/* check if the db belongs to a valid queue */
+	if (qid >= MAX_VIRTUAL_QUEUES || !test_bit(qid, vctrl->vcq_en))
+		goto err_db;
+
+	/* emulate the shadow doorbell functionality */
+	if (!vctrl->mmio.shadow_db_en || qid == 0)
+		vctrl->mmio.dbs[qid].cqh = cpu_to_le16(val & 0xFFFF);
+
+	if (vctrl->vctrl_paused || !vctrl->mmio.shadow_db_supported)
+		return;
+
+	if (qid == 0) {
+		nvme_mdev_vcq_process(vctrl, 0, false);
+		// if completion queue was full prior to that, we
+		// might have some admin commands pending,
+		// and this is the last chance to process them
+		nvme_mdev_adm_process_sq(vctrl);
+	}
+	return;
+err_db:
+	_DBG(vctrl,
+	     "MMIO: inactive/invalid CQ DB write qid=%d, value=%d\n",
+	     qid, val);
+
+	nvme_mdev_mmio_error(vctrl, NVME_AER_ERROR_INVALID_DB_REG);
+}
+
+/* This is called when user enables the controller */
+static void nvme_mdev_mmio_cntrl_enable(struct nvme_mdev_vctrl *vctrl)
+{
+	u64 acq, asq;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	// Controller must be reset from the dead state
+	if (nvme_mdev_vctrl_is_dead(vctrl))
+		goto error;
+
+	/* only NVME command set supported */
+	if (((vctrl->mmio.cc >> NVME_CC_CSS_SHIFT) & 0x7) != 0)
+		goto error;
+
+	/* Check the queue arbitration method*/
+	if ((vctrl->mmio.cc & NVME_CC_AMS_MASK) != NVME_CC_AMS_RR)
+		goto error;
+
+	/* Check the page size*/
+	if (((vctrl->mmio.cc >> NVME_CC_MPS_SHIFT) & 0xF) != (PAGE_SHIFT - 12))
+		goto error;
+
+	/* Start the admin completion queue*/
+	acq = vctrl->mmio.acql | ((u64)vctrl->mmio.acqh << 32);
+	asq = vctrl->mmio.asql | ((u64)vctrl->mmio.asqh << 32);
+
+	if (!nvme_mdev_vctrl_enable(vctrl, acq, asq, vctrl->mmio.aqa))
+		goto error;
+
+	/* Success! */
+	vctrl->mmio.csts |= NVME_CSTS_RDY;
+	return;
+error:
+	_DBG(vctrl, "MMIO: failure to enable the controller - fatal error\n");
+	nvme_mdev_mmio_fatal_error(vctrl);
+}
+
+/* This is called when user sends a notification that controller is
+ * about to be disabled
+ */
+static void nvme_mdev_mmio_cntrl_shutdown(struct nvme_mdev_vctrl *vctrl)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	/* clear shutdown notification bits */
+	vctrl->mmio.cc &= ~NVME_CC_SHN_MASK;
+
+	if (nvme_mdev_vctrl_is_dead(vctrl)) {
+		_DBG(vctrl, "MMIO: shutdown notification for dead ctrl\n");
+		return;
+	}
+
+	/* not enabled */
+	if (!(vctrl->mmio.csts & NVME_CSTS_RDY)) {
+		_DBG(vctrl, "MMIO: shutdown notification with CSTS.RDY==0\n");
+		nvme_mdev_assert_io_not_running(vctrl);
+		return;
+	}
+
+	nvme_mdev_io_pause(vctrl);
+	nvme_mdev_vctrl_disable(vctrl);
+	vctrl->mmio.csts |= NVME_CSTS_SHST_CMPLT;
+}
+
+/* MMIO BAR read/write */
+static int nvme_mdev_mmio_bar_access(struct nvme_mdev_vctrl *vctrl,
+				     u16 offset, char *buf,
+				     u32 count, bool is_write)
+{
+	u32 val, oldval;
+
+	mutex_lock(&vctrl->lock);
+
+	/* Drop non DWORD sized and aligned reads/writes
+	 * (QWORD  read/writes are split by the caller)
+	 */
+	if (count != 4 || (offset & 0x3))
+		goto drop;
+
+	val = is_write ? le32_to_cpu(*(__le32 *)buf) : 0;
+
+	switch (offset) {
+	case NVME_REG_CAP:
+		/* controller capabilities (low 32 bit)*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.cap & 0xFFFFFFFF);
+		break;
+
+	case NVME_REG_CAP + 4:
+		/* controller capabilities (upper 32 bit)*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.cap >> 32);
+		break;
+
+	case NVME_REG_VS:
+		if (is_write)
+			goto drop;
+		store_le32(buf, NVME_MDEV_NVME_VER);
+		break;
+
+	case NVME_REG_INTMS:
+	case NVME_REG_INTMC:
+		/* Interrupt Mask Set & Clear */
+		goto drop;
+
+	case NVME_REG_CC:
+		/* Controller Configuration */
+		if (!is_write) {
+			store_le32(buf, vctrl->mmio.cc);
+			break;
+		}
+
+		oldval = vctrl->mmio.cc;
+		vctrl->mmio.cc = val;
+
+		/* drop if reserved bits set */
+		if (vctrl->mmio.cc & 0xFF00000E) {
+			_DBG(vctrl,
+			     "MMIO: reserved bits of CC set - fatal error\n");
+			nvme_mdev_mmio_fatal_error(vctrl);
+			goto drop;
+		}
+
+		/* CSS(command set),MPS(memory page size),AMS(queue arbitration)
+		 * must not be changed while controller is running
+		 */
+		if (vctrl->mmio.csts & NVME_CSTS_RDY) {
+			if ((vctrl->mmio.cc & 0x3FF0) != (oldval & 0x3FF0)) {
+				_DBG(vctrl,
+				     "MMIO: attempt to change setting bits of CC while CC.EN=1 - fatal error\n");
+
+				nvme_mdev_mmio_fatal_error(vctrl);
+				goto drop;
+			}
+		}
+
+		if ((vctrl->mmio.cc & NVME_CC_SHN_MASK) != NVME_CC_SHN_NONE) {
+			_DBG(vctrl, "MMIO: CC.SHN != 0 - shutdown\n");
+			nvme_mdev_mmio_cntrl_shutdown(vctrl);
+		}
+
+		/* change in controller enabled state */
+		if ((val & NVME_CC_ENABLE) == (oldval & NVME_CC_ENABLE))
+			break;
+
+		if (vctrl->mmio.cc & NVME_CC_ENABLE) {
+			_DBG(vctrl, "MMIO: CC.EN<=1 - enable the controller\n");
+			nvme_mdev_mmio_cntrl_enable(vctrl);
+		} else {
+			_DBG(vctrl, "MMIO: CC.EN<=0 - reset controller\n");
+			__nvme_mdev_vctrl_reset(vctrl, false);
+		}
+
+		break;
+
+	case NVME_REG_CSTS:
+		/* Controller Status */
+		if (is_write)
+			goto drop;
+		store_le32(buf, vctrl->mmio.csts);
+		break;
+
+	case NVME_REG_AQA:
+		/* admin queue submission and completion size*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.aqa);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.aqa = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ASQ:
+		/* admin submission queue address (low 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.asql);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.asql = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ASQ + 4:
+		/* admin submission queue address (high 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.asqh);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.asqh = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ACQ:
+		/* admin completion queue address (low 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.acql);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.acql = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_ACQ + 4:
+		/* admin completion queue address (high 32 bit)*/
+		if (!is_write)
+			store_le32(buf, vctrl->mmio.acqh);
+		else if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			vctrl->mmio.acqh = val;
+		else
+			goto drop;
+		break;
+
+	case NVME_REG_CMBLOC:
+	case NVME_REG_CMBSZ:
+		/* not supported - hardwired to 0*/
+		if (is_write)
+			goto drop;
+		store_le32(buf, 0);
+		break;
+
+	case NVME_REG_DBS ... (NVME_REG_DBS + DB_AREA_SIZE - 1): {
+		/* completion and submission doorbells */
+		u16 db_offset = offset - NVME_REG_DBS;
+		u16 index = db_offset >> (DB_STRIDE_SHIFT + 2);
+		u16 qid = index >> 1;
+		bool sq = (index & 0x1) == 0;
+
+		if (!is_write || (db_offset & DB_MASK))
+			goto drop;
+
+		if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+			goto drop;
+
+		if (nvme_mdev_vctrl_is_dead(vctrl))
+			goto drop;
+
+		sq ? nvme_mdev_mmio_db_write_sq(vctrl, qid, val) :
+		     nvme_mdev_mmio_db_write_cq(vctrl, qid, val);
+		break;
+	}
+	default:
+		goto drop;
+	}
+
+	mutex_unlock(&vctrl->lock);
+	return count;
+drop:
+	_DBG(vctrl, "MMIO: dropping write at 0x%x\n", offset);
+	mutex_unlock(&vctrl->lock);
+	return 0;
+}
+
+/* Called when the virtual controller is created */
+int nvme_mdev_mmio_create(struct nvme_mdev_vctrl *vctrl)
+{
+	int ret;
+
+	/* BAR0 */
+	nvme_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_0,
+				MMIO_BAR_SIZE, nvme_mdev_mmio_bar_access);
+
+	/* Spec allows for maximum depth of 0x10000, but we limit
+	 * it to 1 less to avoid various overflows
+	 */
+	BUILD_BUG_ON(MAX_VIRTUAL_QUEUE_DEPTH > 0xFFFF);
+
+	/* CAP has 4 bits for the doorbell stride shift*/
+	BUILD_BUG_ON(DB_STRIDE_SHIFT > 0xF);
+
+	/* Shadow doorbell limits doorbells to 1 page*/
+	BUILD_BUG_ON(DB_AREA_SIZE > PAGE_SIZE);
+
+	/* Just in case...*/
+	BUILD_BUG_ON((PAGE_SHIFT - 12) > 0xF);
+
+	vctrl->mmio.cap =
+		// MQES: maximum queue entries
+		((u64)(MAX_VIRTUAL_QUEUE_DEPTH - 1) << 0) |
+		// CQR: physically contiguous queues - no
+		(0ULL << 16) |
+		// AMS: Queue arbitration.
+		// TODOLATER: IO: implement WRRU
+		(0ULL << 17) |
+		// TO: RDY timeout - 0 (done in sync)
+		(0ULL << 24) |
+		// DSTRD: doorbell stride
+		((u64)DB_STRIDE_SHIFT << 32) |
+		// NSSRS: no support for nvme subsystem reset
+		(0ULL << 36) |
+		// CSS: NVM command set supported
+		(1ULL << 37) |
+		// BPS: no support for boot partition
+		(0ULL << 45) |
+		// MPSMIN: Minimum page size supported is PAGE_SIZE
+		((u64)(PAGE_SHIFT - 12) << 48) |
+		// MPSMAX: Maximum page size is PAGE_SIZE as well
+		((u64)(PAGE_SHIFT - 12) << 52);
+
+	/* Create the (regular) doorbell buffers */
+	vctrl->mmio.dbs_page = alloc_pages_node(vctrl->hctrl->node,
+						__GFP_ZERO, 0);
+
+	ret = -ENOMEM;
+
+	if (!vctrl->mmio.dbs_page)
+		goto error0;
+
+	vctrl->mmio.db_page_kmap = kmap(vctrl->mmio.dbs_page);
+	if (!vctrl->mmio.db_page_kmap)
+		goto error1;
+
+	vctrl->mmio.fake_eidx_page = alloc_pages_node(vctrl->hctrl->node,
+						      __GFP_ZERO, 0);
+	if (!vctrl->mmio.fake_eidx_page)
+		goto error2;
+
+	vctrl->mmio.fake_eidx_kmap = kmap(vctrl->mmio.fake_eidx_page);
+	if (!vctrl->mmio.fake_eidx_kmap)
+		goto error3;
+	return 0;
+error3:
+	put_page(vctrl->mmio.fake_eidx_kmap);
+error2:
+	kunmap(vctrl->mmio.dbs_page);
+error1:
+	put_page(vctrl->mmio.dbs_page);
+error0:
+	return ret;
+}
+
+/* Called when the virtual controller is reset */
+void nvme_mdev_mmio_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset)
+{
+	vctrl->mmio.cc = 0;
+	vctrl->mmio.csts = 0;
+
+	if (pci_reset) {
+		vctrl->mmio.aqa  = 0;
+		vctrl->mmio.asql = 0;
+		vctrl->mmio.asqh = 0;
+		vctrl->mmio.acql = 0;
+		vctrl->mmio.acqh = 0;
+	}
+}
+
+/* Called when the virtual controller is opened */
+void nvme_mdev_mmio_open(struct nvme_mdev_vctrl *vctrl)
+{
+	if (!vctrl->mmio.shadow_db_supported)
+		nvme_mdev_vctrl_region_set_mmap(vctrl,
+						VFIO_PCI_BAR0_REGION_INDEX,
+						NVME_REG_DBS, PAGE_SIZE,
+						&nvme_mdev_mmio_dbs_vm_ops);
+	else
+		nvme_mdev_vctrl_region_disable_mmap(vctrl,
+						    VFIO_PCI_BAR0_REGION_INDEX);
+}
+
+/* Called when the virtual controller queues are enabled */
+int nvme_mdev_mmio_enable_dbs(struct nvme_mdev_vctrl *vctrl)
+{
+	if (WARN_ON(vctrl->mmio.shadow_db_en))
+		return -EINVAL;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	/* setup normal doorbells and reset them*/
+	vctrl->mmio.dbs = vctrl->mmio.db_page_kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.fake_eidx_kmap;
+	memset((void *)vctrl->mmio.dbs, 0, DB_AREA_SIZE);
+	memset((void *)vctrl->mmio.eidxs, 0, DB_AREA_SIZE);
+	return 0;
+}
+
+/* Called when the virtual controller shadow doorbell is enabled */
+int nvme_mdev_mmio_enable_dbs_shadow(struct nvme_mdev_vctrl *vctrl,
+				     dma_addr_t sdb_iova,
+				     dma_addr_t eidx_iova)
+{
+	int ret;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	ret = nvme_mdev_viommu_create_kmap(&vctrl->viommu,
+					   sdb_iova, &vctrl->mmio.sdb_map);
+	if (ret)
+		return ret;
+
+	ret = nvme_mdev_viommu_create_kmap(&vctrl->viommu,
+					   eidx_iova, &vctrl->mmio.seidx_map);
+	if (ret) {
+		nvme_mdev_viommu_free_kmap(&vctrl->viommu,
+					   &vctrl->mmio.sdb_map);
+		return ret;
+	}
+
+	vctrl->mmio.dbs = vctrl->mmio.sdb_map.kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.seidx_map.kmap;
+
+	memcpy((void *)vctrl->mmio.dbs,
+	       vctrl->mmio.db_page_kmap, DB_AREA_SIZE);
+
+	memcpy((void *)vctrl->mmio.eidxs,
+	       vctrl->mmio.db_page_kmap, DB_AREA_SIZE);
+
+	vctrl->mmio.shadow_db_en = true;
+	return 0;
+}
+
+/* Called on guest mapping update to
+ * verify that our mappings are still intact
+ */
+void nvme_mdev_mmio_viommu_update(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+	if (!vctrl->mmio.shadow_db_en)
+		return;
+
+	nvme_mdev_viommu_update_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map);
+	nvme_mdev_viommu_update_kmap(&vctrl->viommu, &vctrl->mmio.seidx_map);
+
+	vctrl->mmio.dbs = vctrl->mmio.sdb_map.kmap;
+	vctrl->mmio.eidxs = vctrl->mmio.seidx_map.kmap;
+}
+
+/* Disable the doorbells */
+void nvme_mdev_mmio_disable_dbs(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	/* Free the shadow doorbells */
+	nvme_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.sdb_map);
+	nvme_mdev_viommu_free_kmap(&vctrl->viommu, &vctrl->mmio.seidx_map);
+
+	/* Clear the doorbells */
+	vctrl->mmio.dbs = NULL;
+	vctrl->mmio.eidxs = NULL;
+	vctrl->mmio.shadow_db_en = false;
+}
+
+/* Called when the virtual controller is about to be freed */
+void nvme_mdev_mmio_free(struct nvme_mdev_vctrl *vctrl)
+{
+	nvme_mdev_assert_io_not_running(vctrl);
+	kunmap(vctrl->mmio.dbs_page);
+	put_page(vctrl->mmio.dbs_page);
+	kunmap(vctrl->mmio.fake_eidx_page);
+	put_page(vctrl->mmio.fake_eidx_page);
+}
diff --git a/drivers/nvme/mdev/pci.c b/drivers/nvme/mdev/pci.c
new file mode 100644
index 000000000000..b7cdeaaf9c2e
--- /dev/null
+++ b/drivers/nvme/mdev/pci.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NVMe virtual controller minimal PCI/PCIe config space implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include "priv.h"
+
+/* setup a 64 bit PCI bar */
+void nvme_mdev_pci_setup_bar(struct nvme_mdev_vctrl *vctrl,
+			     u8 bar,
+			     unsigned int size,
+			     region_access_fn access_fn)
+{
+	nvme_mdev_vctrl_add_region(vctrl,
+				   VFIO_PCI_BAR0_REGION_INDEX +
+				   ((bar - PCI_BASE_ADDRESS_0) >> 2),
+				   size, access_fn);
+
+	store_le32(vctrl->pcicfg.wmask + bar, ~((u64)size - 1));
+	store_le32(vctrl->pcicfg.values + bar,
+		   PCI_BASE_ADDRESS_SPACE_MEMORY |
+		   PCI_BASE_ADDRESS_MEM_TYPE_64);
+}
+
+/* Allocate a pci capability*/
+static u8 nvme_mdev_pci_allocate_cap(struct nvme_mdev_vctrl *vctrl,
+				     u8 id, u8 size)
+{
+	u8 *cfg = vctrl->pcicfg.values;
+	u8 newcap = vctrl->pcicfg.end;
+	u8 cap = cfg[PCI_CAPABILITY_LIST];
+
+	size = round_up(size, 4);
+	// only standard cfg space caps for now
+	WARN_ON(newcap + size > 256);
+
+	if (!cfg[PCI_CAPABILITY_LIST]) {
+		/*special case for first capability*/
+		u16 status = load_le16(cfg + PCI_STATUS);
+
+		status |= PCI_STATUS_CAP_LIST;
+		store_le16(cfg + PCI_STATUS, status);
+
+		cfg[PCI_CAPABILITY_LIST] = newcap;
+		goto setupcap;
+	}
+
+	while (cfg[cap + PCI_CAP_LIST_NEXT] != 0)
+		cap = cfg[cap + PCI_CAP_LIST_NEXT];
+
+	cfg[cap + PCI_CAP_LIST_NEXT] = newcap;
+
+setupcap:
+	cfg[newcap + PCI_CAP_LIST_ID] = id;
+	cfg[newcap + PCI_CAP_LIST_NEXT] = 0;
+	vctrl->pcicfg.end += size;
+	return newcap;
+}
+
+static void nvme_mdev_pci_setup_pm_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg  =  vctrl->pcicfg.values;
+	u8 *cfgm =  vctrl->pcicfg.wmask;
+
+	u8 cap = nvme_mdev_pci_allocate_cap(vctrl,
+					    PCI_CAP_ID_PM, PCI_PM_SIZEOF);
+
+	store_le16(cfg + cap + PCI_PM_PMC, 0x3);
+	store_le16(cfg + cap + PCI_PM_CTRL, PCI_PM_CTRL_NO_SOFT_RESET);
+	store_le16(cfgm + cap + PCI_PM_CTRL, 0x3);
+	vctrl->pcicfg.pmcap = cap;
+}
+
+static void nvme_mdev_pci_setup_msix_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg  =  vctrl->pcicfg.values;
+	u8 *cfgm =  vctrl->pcicfg.wmask;
+	u8  cap = nvme_mdev_pci_allocate_cap(vctrl,
+					     PCI_CAP_ID_MSIX,
+					     PCI_CAP_MSIX_SIZEOF);
+
+	int MSIX_TBL_SIZE = roundup(MAX_VIRTUAL_IRQS * 16, PAGE_SIZE);
+	int MSIX_PBA_SIZE = roundup(DIV_ROUND_UP(MAX_VIRTUAL_IRQS, 8),
+				    PAGE_SIZE);
+
+	store_le16(cfg + cap + PCI_MSIX_FLAGS, MAX_VIRTUAL_IRQS - 1);
+	store_le16(cfgm + cap + PCI_MSIX_FLAGS,
+		   PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE);
+
+	store_le32(cfg + cap + PCI_MSIX_TABLE, 0x2);
+	store_le32(cfg + cap + PCI_MSIX_PBA, MSIX_TBL_SIZE | 0x2);
+
+	nvme_mdev_pci_setup_bar(vctrl, PCI_BASE_ADDRESS_2,
+				__roundup_pow_of_two(MSIX_TBL_SIZE +
+						MSIX_PBA_SIZE), NULL);
+	vctrl->pcicfg.msixcap = cap;
+}
+
+static void nvme_mdev_pci_setup_pcie_cap(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg = vctrl->pcicfg.values;
+	u8 cap = nvme_mdev_pci_allocate_cap(vctrl,
+					    PCI_CAP_ID_EXP,
+					    PCI_CAP_EXP_ENDPOINT_SIZEOF_V2);
+
+	store_le16(cfg + cap + PCI_EXP_FLAGS, 0x02 |
+		   (PCI_EXP_TYPE_ENDPOINT << 4));
+
+	store_le32(cfg + cap + PCI_EXP_DEVCAP,
+		   PCI_EXP_DEVCAP_RBER | PCI_EXP_DEVCAP_FLR);
+	store_le32(cfg + cap + PCI_EXP_LNKCAP,
+		   PCI_EXP_LNKCAP_SLS_8_0GB | (4 << 4) /*4x*/);
+	store_le16(cfg + cap + PCI_EXP_LNKSTA,
+		   PCI_EXP_LNKSTA_CLS_8_0GB | (4 << 4) /*4x*/);
+
+	store_le32(cfg + cap + PCI_EXP_LNKCAP2, PCI_EXP_LNKCAP2_SLS_8_0GB);
+	store_le16(cfg + cap + PCI_EXP_LNKCTL2, PCI_EXP_LNKCTL2_TLS_8_0GT);
+	vctrl->pcicfg.pciecap = cap;
+}
+
+/* This is called on PCI config read/write */
+static int nvme_mdev_pci_cfg_access(struct nvme_mdev_vctrl *vctrl,
+				    u16 offset, char *buf,
+				    u32 count, bool is_write)
+{
+	unsigned int i;
+
+	mutex_lock(&vctrl->lock);
+
+	if (!is_write) {
+		memcpy(buf, (vctrl->pcicfg.values + offset), count);
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		u8 address = offset + i;
+		u8 value = buf[i];
+		u8 old_value = vctrl->pcicfg.values[address];
+		u8 wmask = vctrl->pcicfg.wmask[address];
+		u8 new_value = (value & wmask) | (old_value & ~wmask);
+
+		/* D3/D0 power control */
+		if (address == vctrl->pcicfg.pmcap + PCI_PM_CTRL) {
+			u8 state = new_value & 0x03;
+
+			if (state != 0 && state != 3)
+				new_value = old_value;
+
+			if (old_value != new_value) {
+				const char *s = state == 3 ? "D3" : "D0";
+
+				if (state == 3)
+					__nvme_mdev_vctrl_reset(vctrl, true);
+				_DBG(vctrl, "PCI: going to %s\n", s);
+			}
+		}
+
+		/* FLR reset*/
+		if (address == vctrl->pcicfg.pciecap + PCI_EXP_DEVCTL + 1)
+			if (value & 0x80) {
+				_DBG(vctrl, "PCI: FLR reset\n");
+				__nvme_mdev_vctrl_reset(vctrl, true);
+			}
+		vctrl->pcicfg.values[offset + i] = new_value;
+	}
+out:
+	mutex_unlock(&vctrl->lock);
+	return count;
+}
+
+/* setup pci configuration */
+int nvme_mdev_pci_create(struct nvme_mdev_vctrl *vctrl)
+{
+	u8 *cfg, *cfgm;
+
+	vctrl->pcicfg.values = kzalloc(PCI_CFG_SIZE, GFP_KERNEL);
+	if (!vctrl->pcicfg.values)
+		return -ENOMEM;
+
+	vctrl->pcicfg.wmask = kzalloc(PCI_CFG_SIZE, GFP_KERNEL);
+	if (!vctrl->pcicfg.wmask) {
+		kfree(vctrl->pcicfg.values);
+		return -ENOMEM;
+	}
+
+	cfg = vctrl->pcicfg.values;
+	cfgm = vctrl->pcicfg.wmask;
+
+	nvme_mdev_vctrl_add_region(vctrl,
+				   VFIO_PCI_CONFIG_REGION_INDEX,
+				   PCI_CFG_SIZE,
+				   nvme_mdev_pci_cfg_access);
+
+	/* vendor information */
+	store_le16(cfg + PCI_VENDOR_ID, NVME_MDEV_PCI_VENDOR_ID);
+	store_le16(cfg + PCI_DEVICE_ID, NVME_MDEV_PCI_DEVICE_ID);
+
+	/* pci command register */
+	store_le16(cfgm + PCI_COMMAND,
+		   PCI_COMMAND_INTX_DISABLE |
+		   PCI_COMMAND_MEMORY |
+		   PCI_COMMAND_MASTER);
+
+	/* pci status register */
+	store_le16(cfg + PCI_STATUS, PCI_STATUS_CAP_LIST);
+
+	/* subsystem information */
+	store_le16(cfg + PCI_SUBSYSTEM_VENDOR_ID, NVME_MDEV_PCI_SUBVENDOR_ID);
+	store_le16(cfg + PCI_SUBSYSTEM_ID, NVME_MDEV_PCI_SUBDEVICE_ID);
+	store_le8(cfg + PCI_CLASS_REVISION, NVME_MDEV_PCI_REVISION);
+
+	/*Programming Interface (NVM Express) */
+	store_le8(cfg + PCI_CLASS_PROG, 0x02);
+
+	/* Device class and subclass
+	 * (Mass storage controller, Non-Volatile memory controller)
+	 */
+	store_le16(cfg + PCI_CLASS_DEVICE, 0x0108);
+
+	/* dummy read/write */
+	store_le8(cfgm + PCI_CACHE_LINE_SIZE, 0xFF);
+
+	/* initial value*/
+	store_le8(cfg + PCI_CAPABILITY_LIST, 0);
+	vctrl->pcicfg.end = 0x40;
+
+	nvme_mdev_pci_setup_pm_cap(vctrl);
+	nvme_mdev_pci_setup_msix_cap(vctrl);
+	nvme_mdev_pci_setup_pcie_cap(vctrl);
+
+	/* INTX IRQ number - info only for BIOS */
+	store_le8(cfgm + PCI_INTERRUPT_LINE, 0xFF);
+	store_le8(cfg + PCI_INTERRUPT_PIN, 0x01);
+
+	return 0;
+}
+
+/* teardown pci configuration */
+void nvme_mdev_pci_free(struct nvme_mdev_vctrl *vctrl)
+{
+	kfree(vctrl->pcicfg.values);
+	kfree(vctrl->pcicfg.wmask);
+	vctrl->pcicfg.values = NULL;
+	vctrl->pcicfg.wmask = NULL;
+}
diff --git a/drivers/nvme/mdev/priv.h b/drivers/nvme/mdev/priv.h
new file mode 100644
index 000000000000..9f65e46c1ab2
--- /dev/null
+++ b/drivers/nvme/mdev/priv.h
@@ -0,0 +1,700 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Driver private data structures and helper macros
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+
+#ifndef _MDEV_NVME_PRIV_H
+#define _MDEV_NVME_PRIV_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/vfio.h>
+#include <linux/mdev.h>
+#include <linux/pci.h>
+#include <linux/eventfd.h>
+#include <linux/byteorder/generic.h>
+#include "../host/nvme.h"
+#include "mdev.h"
+
+#define NVME_MDEV_NVME_VER  NVME_VS(0x01, 0x03, 0x00)
+#define NVME_MDEV_FIRMWARE_VERSION "1.0"
+
+#define NVME_MDEV_PCI_VENDOR_ID		PCI_VENDOR_ID_REDHAT_QUMRANET
+#define NVME_MDEV_PCI_DEVICE_ID		0x1234
+#define NVME_MDEV_PCI_SUBVENDOR_ID	PCI_SUBVENDOR_ID_REDHAT_QUMRANET
+#define NVME_MDEV_PCI_SUBDEVICE_ID	0
+#define NVME_MDEV_PCI_REVISION		0x0
+
+#define DB_STRIDE_SHIFT 4 /*4 = 1 cacheline */
+#define MAX_VIRTUAL_QUEUES 16
+#define MAX_VIRTUAL_QUEUE_DEPTH 0xFFFF
+#define MAX_VIRTUAL_NAMESPACES 16 /* NSID = 1..16*/
+#define MAX_VIRTUAL_IRQS 16
+
+#define MAX_HOST_QUEUES 4
+#define MAX_AER_COMMANDS 16
+#define MAX_LOG_PAGES 16
+
+extern bool use_shadow_doorbell;
+extern unsigned int io_timeout_ms;
+extern unsigned int poll_timeout_ms;
+extern unsigned int admin_poll_rate_ms;
+
+/* virtual submission queue*/
+struct  nvme_vsq {
+	u16 qid;
+	u16 size;
+	u16 head;	/*next item to read */
+
+	struct nvme_command *data; /*the queue*/
+	struct nvme_vcq *vcq; /* completion queue*/
+
+	dma_addr_t iova;
+	bool cont;
+
+	u16 hsq;
+};
+
+/* virtual completion queue*/
+struct nvme_vcq {
+	/* basic queue settings */
+	u16 qid;
+	u16 size;
+	u16 head;
+	u16 tail;
+	bool phase; /* current queue phase */
+
+	volatile struct nvme_completion *data;
+
+	/* number of items pending*/
+	u16 pending;
+
+	/* IRQ settings */
+	int irq /* -1 if disabled*/;
+
+	dma_addr_t iova;
+	bool cont;
+};
+
+/*A virtual namespace */
+struct nvme_mdev_vns {
+	/* host nvme namespace that we are attached to it*/
+	struct nvme_ns *host_ns;
+
+	/* block device that corresponds to the partition of that namespace */
+	struct block_device *host_part;
+	fmode_t fmode;
+
+	u32 nsid;
+
+	/* NSID on the host*/
+	u32 host_nsid;
+
+	/* host partition ID*/
+	unsigned int host_partid;
+
+	/* Offset inside the host namespace (start of the partition)*/
+	u64 host_lba_offset;
+
+	/* size of each block on the real namespace, same for host and guest */
+	u8 blksize_shift;
+
+	/* size of the namespace in lbas*/
+	u64 ns_size;
+
+	/* is the namespace read only?*/
+	bool readonly;
+
+	/* UUID of this namespace */
+	uuid_t uuid;
+
+	/* Optimal IO boundary*/
+	u16 noiob;
+};
+
+/* Virtual IOMMU */
+struct nvme_mdev_viommu {
+	struct device *hw_dev;
+	struct device *sw_dev;
+
+	/* dma/prp bookkeeping */
+	struct rb_root_cached maps_tree;
+	struct list_head maps_list;
+	struct nvme_mdev_vctrl *vctrl;
+};
+
+struct doorbell {
+	volatile __le32 sqt;
+	u8 rsvd1[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)];
+	volatile __le32 cqh;
+	u8 rsvd2[(4 << DB_STRIDE_SHIFT) - sizeof(__le32)];
+};
+
+/* MMIO state */
+struct nvme_mdev_user_ctrl_mmio {
+	u32 cc;		/* controller configuration */
+	u32 csts;	/* controller status */
+	u64 cap		/* controller capabilities*/;
+
+	/* admin queue location & size */
+	u32 aqa;
+	u32 asql;
+	u32 asqh;
+	u32 acql;
+	u32 acqh;
+
+	bool shadow_db_supported;
+	bool shadow_db_en;
+
+	/* Regular doorbells */
+	struct page *dbs_page;
+	struct page *fake_eidx_page;
+	void *db_page_kmap;
+	void *fake_eidx_kmap;
+
+	/* Shadow doorbells */
+	struct page_map sdb_map;
+	struct page_map seidx_map;
+
+	/* Current doorbell mappings */
+	volatile struct doorbell *dbs;
+	volatile struct doorbell *eidxs;
+};
+
+/* pci configuration space of the device*/
+#define PCI_CFG_SIZE 4096
+struct nvme_mdev_pci_cfg_space {
+	u8 *values;
+	u8 *wmask;
+
+	u8 pmcap;
+	u8 pciecap;
+	u8 msixcap;
+	u8 end;
+};
+
+/*IRQ state of the controller */
+struct nvme_mdev_user_irq {
+	struct eventfd_ctx *trigger;
+	/* IRQ coalescing */
+	bool irq_coalesc_en;
+	time_t irq_time;
+	unsigned int irq_pending_cnt;
+};
+
+enum nvme_mdev_irq_mode {
+	NVME_MDEV_IMODE_NONE,
+	NVME_MDEV_IMODE_INTX,
+	NVME_MDEV_IMODE_MSIX,
+};
+
+struct nvme_mdev_user_irqs {
+	/* one of VFIO_PCI_{INTX|MSI|MSIX}_IRQ_INDEX */
+	enum nvme_mdev_irq_mode mode;
+
+	struct nvme_mdev_user_irq vecs[MAX_VIRTUAL_IRQS];
+	/* user interrupt coalescing settings */
+	u8 irq_coalesc_max;
+	unsigned int irq_coalesc_time_us;
+	/* device removal trigger*/
+	struct eventfd_ctx *request_trigger;
+};
+
+/*AER state */
+struct nvme_mdev_user_events {
+	/* async event request CIDs*/
+	u16 aer_cids[MAX_AER_COMMANDS];
+	unsigned int aer_cid_count;
+
+	/* events that are enabled */
+	unsigned long events_enabled[BITS_TO_LONGS(MAX_LOG_PAGES)];
+
+	/* events that are masked till next log page read*/
+	unsigned long events_masked[BITS_TO_LONGS(MAX_LOG_PAGES)];
+
+	/* events that are pending to be sent when user gives us an AER*/
+	unsigned long  events_pending[BITS_TO_LONGS(MAX_LOG_PAGES)];
+	u32 event_values[MAX_LOG_PAGES];
+};
+
+/* host IO queue */
+struct nvme_mdev_hq {
+	unsigned int usecount;
+	struct list_head link;
+	unsigned int hqid;
+};
+
+/* IO region abstraction (BARs, the PCI config space */
+struct nvme_mdev_vctrl;
+typedef int (*region_access_fn) (struct nvme_mdev_vctrl *vctrl,
+				 u16 offset, char *buf,
+				 u32 size, bool is_write);
+
+struct nvme_mdev_io_region {
+	unsigned int size;
+	region_access_fn rw;
+
+	/* IF != NULL, the mmap_area_start/size specify the mmaped window
+	 * of this region
+	 */
+	const struct vm_operations_struct *mmap_ops;
+	unsigned int mmap_area_start;
+	unsigned int mmap_area_size;
+};
+
+/*Virtual NVME controller state */
+struct nvme_mdev_vctrl {
+	struct kref ref;
+	struct mutex lock;
+	struct list_head link;
+
+	struct mdev_device *mdev;
+	struct nvme_mdev_hctrl *hctrl;
+	bool inuse;
+
+	struct nvme_mdev_io_region regions[VFIO_PCI_NUM_REGIONS];
+
+	/* virtual controller state */
+	struct nvme_mdev_user_ctrl_mmio mmio;
+	struct nvme_mdev_pci_cfg_space pcicfg;
+	struct nvme_mdev_user_irqs irqs;
+	struct nvme_mdev_user_events events;
+
+	/* emulated namespaces */
+	struct nvme_mdev_vns *namespaces[MAX_VIRTUAL_NAMESPACES];
+	__le32 ns_log[MAX_VIRTUAL_NAMESPACES];
+	unsigned int ns_log_size;
+
+	/* emulated submission queues*/
+	struct nvme_vsq vsqs[MAX_VIRTUAL_QUEUES];
+	unsigned long vsq_en[BITS_TO_LONGS(MAX_VIRTUAL_QUEUES)];
+
+	/* emulated completion queues*/
+	unsigned long vcq_en[BITS_TO_LONGS(MAX_VIRTUAL_QUEUES)];
+	struct nvme_vcq vcqs[MAX_VIRTUAL_QUEUES];
+
+	/* Host IO queues*/
+	int max_host_hw_queues;
+	struct list_head host_hw_queues;
+
+	/* Interface to access user memory */
+	struct notifier_block vfio_map_notifier;
+	struct notifier_block vfio_unmap_notifier;
+	struct nvme_mdev_viommu viommu;
+
+	/* the IO thread */
+	struct task_struct *iothread;
+	bool iothread_parked;
+	bool io_idle;
+	ktime_t now;
+
+	/* Settings */
+	unsigned int arb_burst_shift;
+	u8 worload_hint;
+	unsigned int iothread_cpu;
+
+	/* Identification*/
+	char subnqn[256];
+	char serial[9];
+
+	bool vctrl_paused; /* true when the host device paused our IO */
+};
+
+/* mdev instance type*/
+struct nvme_mdev_inst_type {
+	unsigned int max_hw_queues;
+	char name[16];
+	struct attribute_group *attrgroup;
+};
+
+/*Abstraction of the host controller that we are connected to */
+struct nvme_mdev_hctrl {
+	struct mutex lock;
+
+	/* numa node of the host controller*/
+	int node;
+
+	struct list_head link;
+	struct kref ref;
+	bool removing;
+
+	/* for reference counting */
+	struct nvme_ctrl *nvme_ctrl;
+
+	/* Host area*/
+	u16 oncs;
+	u8 mdts;
+	unsigned int id;
+
+	/* book-keeping for number of host queues we can allocate*/
+	unsigned int nr_host_queues;
+};
+
+/* vctrl.c*/
+struct nvme_mdev_vctrl *nvme_mdev_vctrl_create(struct mdev_device *mdev,
+					       struct nvme_mdev_hctrl *hctrl,
+					       unsigned int max_host_queues);
+
+int nvme_mdev_vctrl_destroy(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_vctrl_open(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_release(struct nvme_mdev_vctrl *vctrl);
+
+void nvme_mdev_vctrl_pause(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_resume(struct nvme_mdev_vctrl *vctrl);
+
+bool nvme_mdev_vctrl_enable(struct nvme_mdev_vctrl *vctrl,
+			    dma_addr_t cqiova, dma_addr_t sqiova, u32 sizes);
+
+void nvme_mdev_vctrl_disable(struct nvme_mdev_vctrl *vctrl);
+
+void nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl);
+void __nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset);
+
+void nvme_mdev_vctrl_add_region(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index, unsigned int size,
+				region_access_fn access_fn);
+
+void nvme_mdev_vctrl_region_set_mmap(struct nvme_mdev_vctrl *vctrl,
+				     unsigned int index,
+				     unsigned int offset,
+				     unsigned int size,
+				     const struct vm_operations_struct *ops);
+
+void nvme_mdev_vctrl_region_disable_mmap(struct nvme_mdev_vctrl *vctrl,
+					 unsigned int index);
+
+void nvme_mdev_vctrl_bind_iothread(struct nvme_mdev_vctrl *vctrl,
+				   unsigned int cpu);
+
+int nvme_mdev_vctrl_set_shadow_doorbell_supported(struct nvme_mdev_vctrl *vctrl,
+						  bool enable);
+
+int nvme_mdev_vctrl_hq_alloc(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_vctrl_hq_free(struct nvme_mdev_vctrl *vctrl, u16 qid);
+unsigned int nvme_mdev_vctrl_hqs_list(struct nvme_mdev_vctrl *vctrl, u16 *out);
+bool nvme_mdev_vctrl_is_dead(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_vctrl_viommu_map(struct nvme_mdev_vctrl *vctrl, u32 flags,
+			       dma_addr_t iova, u64 size);
+
+int nvme_mdev_vctrl_viommu_unmap(struct nvme_mdev_vctrl *vctrl,
+				 dma_addr_t iova, u64 size);
+
+/* hctrl.c*/
+struct nvme_mdev_inst_type *nvme_mdev_inst_type_get(const char *name);
+struct nvme_mdev_hctrl *nvme_mdev_hctrl_lookup_get(struct device *parent);
+void nvme_mdev_hctrl_put(struct nvme_mdev_hctrl *hctrl);
+
+int nvme_mdev_hctrl_hqs_available(struct nvme_mdev_hctrl *hctrl);
+
+bool nvme_mdev_hctrl_hqs_reserve(struct nvme_mdev_hctrl *hctrl,
+				 unsigned int n);
+void nvme_mdev_hctrl_hqs_unreserve(struct nvme_mdev_hctrl *hctrl,
+				   unsigned int n);
+
+int nvme_mdev_hctrl_hq_alloc(struct nvme_mdev_hctrl *hctrl);
+void nvme_mdev_hctrl_hq_free(struct nvme_mdev_hctrl *hctrl, u16 qid);
+bool nvme_mdev_hctrl_hq_can_submit(struct nvme_mdev_hctrl *hctrl, u16 qid);
+bool nvme_mdev_hctrl_hq_check_op(struct nvme_mdev_hctrl *hctrl, u8 optcode);
+
+int nvme_mdev_hctrl_hq_submit(struct nvme_mdev_hctrl *hctrl,
+			      u16 qid, u32 tag,
+			      struct nvme_command *cmd,
+			      struct nvme_ext_data_iter *datait);
+
+int nvme_mdev_hctrl_hq_poll(struct nvme_mdev_hctrl *hctrl,
+			    u32 qid,
+			    struct nvme_ext_cmd_result *results,
+			    unsigned int max_len);
+
+void nvme_mdev_hctrl_destroy_all(void);
+
+/* io.c */
+int nvme_mdev_io_create(struct nvme_mdev_vctrl *vctrl, unsigned int cpu);
+void nvme_mdev_io_free(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_io_pause(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_io_resume(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_assert_io_not_running(struct nvme_mdev_vctrl *vctrl);
+
+/* mmio.c*/
+int nvme_mdev_mmio_create(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_open(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset);
+void nvme_mdev_mmio_free(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_mmio_enable_dbs(struct nvme_mdev_vctrl *vctrl);
+int nvme_mdev_mmio_enable_dbs_shadow(struct nvme_mdev_vctrl *vctrl,
+				     dma_addr_t sdb_iova, dma_addr_t eidx_iova);
+
+void nvme_mdev_mmio_viommu_update(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_mmio_disable_dbs(struct nvme_mdev_vctrl *vctrl);
+bool nvme_mdev_mmio_db_check(struct nvme_mdev_vctrl *vctrl,
+			     u16 qid, u16 size, u16 db);
+
+/* pci.c*/
+int nvme_mdev_pci_create(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_pci_free(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_pci_setup_bar(struct nvme_mdev_vctrl *vctrl,
+			     u8 bar, unsigned int size,
+			     region_access_fn access_fn);
+/* adm.c*/
+void nvme_mdev_adm_process_sq(struct nvme_mdev_vctrl *vctrl);
+
+/* events.c */
+void nvme_mdev_events_init(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_events_reset(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_event_request_receive(struct nvme_mdev_vctrl *vctrl, u16 cid);
+void nvme_mdev_event_process_ack(struct nvme_mdev_vctrl *vctrl, u8 log_page);
+
+void nvme_mdev_event_send(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_async_event_type type,
+			  enum nvme_async_event info);
+
+u32 nvme_mdev_event_read_aen_config(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_event_set_aen_config(struct nvme_mdev_vctrl *vctrl, u32 value);
+
+/* irq.c*/
+void nvme_mdev_irqs_setup(struct nvme_mdev_vctrl *vctrl);
+void nvme_mdev_irqs_reset(struct nvme_mdev_vctrl *vctrl);
+
+int nvme_mdev_irqs_enable(struct nvme_mdev_vctrl *vctrl,
+			  enum nvme_mdev_irq_mode mode);
+void nvme_mdev_irqs_disable(struct nvme_mdev_vctrl *vctrl,
+			    enum nvme_mdev_irq_mode mode);
+
+int nvme_mdev_irqs_set_triggers(struct nvme_mdev_vctrl *vctrl,
+				int start, int count, int32_t *fds);
+int nvme_mdev_irqs_set_unplug_trigger(struct nvme_mdev_vctrl *vctrl,
+				      int32_t fd);
+
+void nvme_mdev_irq_raise_unplug_event(struct nvme_mdev_vctrl *vctrl,
+				      unsigned int count);
+void nvme_mdev_irq_raise(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index);
+void nvme_mdev_irq_trigger(struct nvme_mdev_vctrl *vctrl,
+			   unsigned int index);
+void nvme_mdev_irq_cond_trigger(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index);
+void nvme_mdev_irq_clear(struct nvme_mdev_vctrl *vctrl,
+			 unsigned int index);
+
+/* ns.c*/
+int nvme_mdev_vns_open(struct nvme_mdev_vctrl *vctrl,
+		       u32 host_nsid, unsigned int host_partid);
+int nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl,
+			  u32 user_nsid);
+void nvme_mdev_vns_destroy_all(struct nvme_mdev_vctrl *vctrl);
+
+struct nvme_mdev_vns *nvme_mdev_vns_from_vnsid(struct nvme_mdev_vctrl *vctrl,
+					       u32 user_ns_id);
+
+int nvme_mdev_vns_print_description(struct nvme_mdev_vctrl *vctrl,
+				    char *buf, unsigned int size);
+void nvme_mdev_vns_host_ns_update(struct nvme_mdev_vctrl *vctrl,
+				  u32 host_nsid, bool removed);
+
+void nvme_mdev_vns_log_reset(struct nvme_mdev_vctrl *vctrl);
+
+/* vcq.c */
+int nvme_mdev_vcq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, int irq);
+
+int nvme_mdev_vcq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vcq *q);
+
+void nvme_mdev_vcq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid);
+void nvme_mdev_vcq_process(struct nvme_mdev_vctrl *vctrl, u16 qid,
+			   bool trigger_irqs);
+
+bool nvme_mdev_vcq_flush(struct nvme_mdev_vctrl *vctrl, u16 qid);
+bool nvme_mdev_vcq_reserve_space(struct nvme_vcq *q);
+
+void nvme_mdev_vcq_write_io(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vcq *q, u16 sq_head,
+			    u16 sqid, u16 cid, u16 status);
+
+void nvme_mdev_vcq_write_adm(struct nvme_mdev_vctrl *vctrl,
+			     struct nvme_vcq *q, u32 dw0,
+			     u16 sq_head, u16 cid, u16 status);
+/* vsq.c*/
+int nvme_mdev_vsq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, u16 cqid);
+
+int nvme_mdev_vsq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vsq *q);
+
+void nvme_mdev_vsq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid);
+
+bool nvme_mdev_vsq_has_data(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vsq *q);
+
+const struct nvme_command *nvme_mdev_vsq_get_cmd(struct nvme_mdev_vctrl *vctrl,
+						 struct nvme_vsq *q);
+
+void nvme_mdev_vsq_cmd_done_io(struct nvme_mdev_vctrl *vctrl,
+			       u16 sqid, u16 cid, u16 status);
+void nvme_mdev_vsq_cmd_done_adm(struct nvme_mdev_vctrl *vctrl,
+				u32 dw0, u16 cid, u16 status);
+bool nvme_mdev_vsq_suspend_io(struct nvme_mdev_vctrl *vctrl, u16 sqid);
+
+/* udata.c*/
+void nvme_mdev_udata_iter_setup(struct nvme_mdev_viommu *viommu,
+				struct nvme_ext_data_iter *iter);
+
+int nvme_mdev_udata_iter_set_dptr(struct nvme_ext_data_iter *it,
+				  const union nvme_data_ptr *dptr, u64 size);
+
+struct nvme_ext_data_iter *
+nvme_mdev_kdata_iter_alloc(struct nvme_mdev_viommu *viommu, unsigned int size);
+
+int nvme_mdev_read_from_udata(void *dst, struct nvme_ext_data_iter *srcit,
+			      u64 size);
+
+int nvme_mdev_write_to_udata(struct nvme_ext_data_iter *dstit, void *src,
+			     u64 size);
+
+void *nvme_mdev_udata_queue_vmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova,
+				 unsigned int size, bool cont);
+/* viommu.c */
+void nvme_mdev_viommu_init(struct nvme_mdev_viommu *viommu,
+			   struct device *sw_dev,
+			   struct device *hw_dev);
+
+int nvme_mdev_viommu_add(struct nvme_mdev_viommu *viommu, u32 flags,
+			 dma_addr_t iova, u64 size);
+
+int nvme_mdev_viommu_remove(struct nvme_mdev_viommu *viommu,
+			    dma_addr_t iova, u64 size);
+
+int nvme_mdev_viommu_translate(struct nvme_mdev_viommu *viommu,
+			       dma_addr_t iova,
+			       dma_addr_t *physical,
+			       dma_addr_t *host_iova);
+
+int nvme_mdev_viommu_create_kmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova, struct page_map *page);
+
+void nvme_mdev_viommu_free_kmap(struct nvme_mdev_viommu *viommu,
+				struct page_map *page);
+
+void nvme_mdev_viommu_update_kmap(struct nvme_mdev_viommu *viommu,
+				  struct page_map *page);
+
+void nvme_mdev_viommu_reset(struct nvme_mdev_viommu *viommu);
+
+/* some utilities*/
+
+#define store_le64(address, value) (*((__le64 *)(address)) = cpu_to_le64(value))
+#define store_le32(address, value) (*((__le32 *)(address)) = cpu_to_le32(value))
+#define store_le16(address, value) (*((__le16 *)(address)) = cpu_to_le16(value))
+#define store_le8(address, value)  (*((u8 *)(address)) = (value))
+
+#define load_le16(address) le16_to_cpu(*(__le16 *)(address))
+#define load_le32(address) le32_to_cpu(*(__le32 *)(address))
+
+#define store_strsp(dst, src) \
+	memcpy_and_pad(dst, sizeof(dst), src, sizeof(src) - 1, ' ')
+
+#define DNR(e) ((e) | NVME_SC_DNR)
+
+#define PAGE_ADDRESS(address) ((address) & PAGE_MASK)
+#define OFFSET_IN_PAGE(address) ((address) & ~(PAGE_MASK))
+
+#define _DBG(vctrl, fmt, ...) \
+	dev_dbg(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define _INFO(vctrl, fmt, ...) \
+	dev_info(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define _WARN(vctrl, fmt, ...) \
+	dev_warn(mdev_dev((vctrl)->mdev), fmt, ##__VA_ARGS__)
+
+#define mdev_to_vctrl(mdev) \
+	((struct nvme_mdev_vctrl *)mdev_get_drvdata(mdev))
+
+#define dev_to_vctrl(mdev) \
+	mdev_to_vctrl(mdev_from_dev(dev))
+
+#define RSRV_NSID (BIT(1))
+#define RSRV_DW23 (BIT(2) | BIT(3))
+#define RSRV_MPTR (BIT(4) | BIT(5))
+
+#define RSRV_DPTR (BIT(6) | BIT(7) | BIT(8) | BIT(9))
+#define RSRV_DPTR_PRP2 (BIT(8) | BIT(9))
+
+#define RSRV_DW10_15 (BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW11_15 (BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW12_15 (BIT(12) | BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW13_15 (BIT(13) | BIT(14) | BIT(15))
+#define RSRV_DW14_15 (BIT(14) | BIT(15))
+
+static inline bool check_reserved_dwords(const u32 *dwords,
+					 int count, unsigned long bitmask)
+{
+	int bit;
+
+	if (WARN_ON(count > BITS_PER_TYPE(long)))
+		return false;
+
+	for_each_set_bit(bit, &bitmask, count)
+		if (dwords[bit])
+			return false;
+	return true;
+}
+
+static inline bool check_range(u64 start, u64 size, u64 end)
+{
+	u64 test = start + size;
+
+	/* check for overflow */
+	if (test < start || test < size)
+		return false;
+	return test <= end;
+}
+
+/* Rough translation of internal errors to the NVME errors */
+static inline int nvme_mdev_translate_error(int error)
+{
+	// nvme status, including no error (NVME_SC_SUCCESS)
+	if (error >= 0)
+		return error;
+
+	switch (error) {
+	case -ENOMEM:
+		/*no memory - truly an internal error*/
+		return NVME_SC_INTERNAL;
+	case -ENOSPC:
+		/* Happens when user sends to large PRP list
+		 * User shoudn't do this since the maximum transfer size
+		 * is specified in the controller caps
+		 */
+		return DNR(NVME_SC_DATA_XFER_ERROR);
+	case -EFAULT:
+		/* Bad memory pointers in the prp lists*/
+		return DNR(NVME_SC_DATA_XFER_ERROR);
+	case -EINVAL:
+		/* Bad prp offsets in the prp lists/command*/
+		return DNR(NVME_SC_PRP_OFFSET_INVALID);
+	default:
+		/*Shouldn't happen */
+		WARN_ON_ONCE(true);
+		return NVME_SC_INTERNAL;
+	}
+}
+
+static inline bool timeout(ktime_t event, ktime_t now, unsigned long timeout_ms)
+{
+	return ktime_ms_delta(now, event) > (long)timeout_ms;
+}
+
+extern struct mdev_parent_ops mdev_fops;
+extern struct list_head nvme_mdev_vctrl_list;
+extern struct mutex nvme_mdev_vctrl_list_mutex;
+
+#endif // _MDEV_NVME_H
diff --git a/drivers/nvme/mdev/udata.c b/drivers/nvme/mdev/udata.c
new file mode 100644
index 000000000000..7af6b3f6d6aa
--- /dev/null
+++ b/drivers/nvme/mdev/udata.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * User (guest) data access routines
+ * Implementation of PRP iterator in user memory
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+#define MAX_PRP ((PAGE_SIZE / sizeof(__le64)) - 1)
+
+/* Setup up a new PRP iterator */
+void nvme_mdev_udata_iter_setup(struct nvme_mdev_viommu *viommu,
+				struct nvme_ext_data_iter *iter)
+{
+	iter->viommu = viommu;
+	iter->count = 0;
+	iter->next = NULL;
+	iter->release = NULL;
+}
+
+/* Load a new prp list into the iterator. Internal*/
+static int nvme_mdev_udata_iter_load_prplist(struct nvme_ext_data_iter *iter,
+					     dma_addr_t iova)
+{
+	dma_addr_t  data_iova;
+	int ret;
+	__le64 *map;
+
+	/* map the prp list*/
+	ret = nvme_mdev_viommu_create_kmap(iter->viommu,
+					   PAGE_ADDRESS(iova),
+					   &iter->uprp.page);
+	if (ret)
+		return ret;
+
+	iter->uprp.index = OFFSET_IN_PAGE(iova) / (sizeof(__le64));
+
+	/* read its first entry and check its alignment */
+	map = iter->uprp.page.kmap;
+	data_iova = le64_to_cpu(map[iter->uprp.index]);
+
+	if (OFFSET_IN_PAGE(data_iova) != 0) {
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+		return -EINVAL;
+	}
+
+	/* translate the entry to complete the setup*/
+	ret =  nvme_mdev_viommu_translate(iter->viommu, data_iova,
+					  &iter->physical, &iter->host_iova);
+	if (ret)
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+
+	return ret;
+}
+
+/* ->next function when iterator points to prp list*/
+static int nvme_mdev_udata_iter_next_prplist(struct nvme_ext_data_iter *iter)
+{
+	dma_addr_t iova;
+	int ret;
+	__le64 *map = iter->uprp.page.kmap;
+
+	if (WARN_ON(iter->count <= 0))
+		return 0;
+
+	if (--iter->count == 0) {
+		nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+		return 0;
+	}
+
+	iter->uprp.index++;
+
+	if (iter->uprp.index < MAX_PRP || iter->count == 1) {
+		// advance over next pointer in current prp list
+		// these pointers must be page aligned
+		iova = le64_to_cpu(map[iter->uprp.index]);
+		if (OFFSET_IN_PAGE(iova) != 0)
+			return -EINVAL;
+
+		ret  = nvme_mdev_viommu_translate(iter->viommu, iova,
+						  &iter->physical,
+						  &iter->host_iova);
+		if (ret)
+			nvme_mdev_viommu_free_kmap(iter->viommu,
+						   &iter->uprp.page);
+		return ret;
+	}
+
+	/* switch to next prp list. it must be page aligned as well*/
+	iova = le64_to_cpu(map[MAX_PRP]);
+
+	if (OFFSET_IN_PAGE(iova) != 0)
+		return -EINVAL;
+
+	nvme_mdev_viommu_free_kmap(iter->viommu, &iter->uprp.page);
+	return nvme_mdev_udata_iter_load_prplist(iter, iova);
+}
+
+/* ->next function when iterator points to user data pointer*/
+static int nvme_mdev_udata_iter_next_dptr(struct nvme_ext_data_iter *iter)
+{
+	dma_addr_t  iova;
+
+	if (WARN_ON(iter->count <= 0))
+		return 0;
+
+	if (--iter->count == 0)
+		return 0;
+
+	/* we will be called only once to deal with the second
+	 * pointer in the data pointer
+	 */
+	iova = le64_to_cpu(iter->dptr->prp2);
+
+	if (iter->count == 1) {
+		/* only need to read one more entry, meaning
+		 * the 2nd entry of the dptr.
+		 * It must be page aligned
+		 */
+		if (OFFSET_IN_PAGE(iova) != 0)
+			return -EINVAL;
+		return nvme_mdev_viommu_translate(iter->viommu, iova,
+						  &iter->physical,
+						  &iter->host_iova);
+	} else {
+		/*
+		 * Second dptr entry is prp pointer, and it might not
+		 * be page aligned (but QWORD aligned at least)
+		 */
+		if (iova & 0x7ULL)
+			return -EINVAL;
+		iter->next = nvme_mdev_udata_iter_next_prplist;
+		return nvme_mdev_udata_iter_load_prplist(iter, iova);
+	}
+}
+
+/* Set prp list iterator to point to data pointer found in NVME command */
+int nvme_mdev_udata_iter_set_dptr(struct nvme_ext_data_iter *it,
+				  const union nvme_data_ptr *dptr, u64 size)
+{
+	int ret;
+	u64 prp1 = le64_to_cpu(dptr->prp1);
+	dma_addr_t iova = PAGE_ADDRESS(prp1);
+	unsigned int page_offset = OFFSET_IN_PAGE(prp1);
+
+	/* first dptr pointer must be at least DWORD aligned*/
+	if (page_offset & 0x3)
+		return -EINVAL;
+
+	it->dptr = dptr;
+	it->next = nvme_mdev_udata_iter_next_dptr;
+	it->count = DIV_ROUND_UP_ULL(size + page_offset, PAGE_SIZE);
+
+	ret = nvme_mdev_viommu_translate(it->viommu, iova,
+					 &it->physical, &it->host_iova);
+	if (ret)
+		return ret;
+
+	it->physical += page_offset;
+	it->host_iova += page_offset;
+	return 0;
+}
+
+/* ->next function when iterator points to kernel memory buffer */
+static int nvme_mdev_kdata_iter_next(struct nvme_ext_data_iter *it)
+{
+	if (WARN_ON(it->count <= 0))
+		return 0;
+
+	if (--it->count == 0)
+		return 0;
+
+	it->physical = PAGE_ADDRESS(it->physical) + PAGE_SIZE;
+	it->host_iova = PAGE_ADDRESS(it->host_iova) + PAGE_SIZE;
+	return 0;
+}
+
+/* ->release function for kdata iterator to free it after use */
+static void nvme_mdev_kdata_iter_free(struct nvme_ext_data_iter *it)
+{
+	struct device *dma_dev = it->viommu->hw_dev;
+
+	if (dma_dev)
+		dma_free_coherent(dma_dev, it->kmem.size,
+				  it->kmem.data, it->kmem.dma_addr);
+	else
+		kfree(it->kmem.data);
+	kfree(it);
+}
+
+/* allocate a kernel data buffer with read iterator for nvme host device */
+struct nvme_ext_data_iter *
+nvme_mdev_kdata_iter_alloc(struct nvme_mdev_viommu *viommu, unsigned int size)
+{
+	struct nvme_ext_data_iter *it;
+
+	it = kzalloc(sizeof(*it), GFP_KERNEL);
+	if (!it)
+		return NULL;
+
+	it->viommu = viommu;
+	it->kmem.size = size;
+	if (viommu->hw_dev) {
+		it->kmem.data = dma_alloc_coherent(viommu->hw_dev, size,
+						   &it->kmem.dma_addr,
+						   GFP_KERNEL);
+	} else {
+		it->kmem.data = kzalloc(size, GFP_KERNEL);
+		it->kmem.dma_addr = 0;
+	}
+
+	if (!it->kmem.data) {
+		kfree(it);
+		return NULL;
+	}
+
+	it->physical = virt_to_phys(it->kmem.data);
+	it->host_iova = it->kmem.dma_addr;
+
+	it->count = DIV_ROUND_UP(size + OFFSET_IN_PAGE(it->physical),
+				 PAGE_SIZE);
+
+	it->next = nvme_mdev_kdata_iter_next;
+	it->release = nvme_mdev_kdata_iter_free;
+	return it;
+}
+
+/* copy data from user data iterator to a kernel buffer */
+int nvme_mdev_read_from_udata(void *dst, struct nvme_ext_data_iter *srcit,
+			      u64 size)
+{
+	int ret;
+	unsigned int srcoffset, chunk_size;
+
+	while (srcit->count && size > 0) {
+		struct page *page = pfn_to_page(PHYS_PFN(srcit->physical));
+		void *src = kmap(page);
+
+		if (!src)
+			return -ENOMEM;
+
+		srcoffset = OFFSET_IN_PAGE(srcit->physical);
+		chunk_size = min(size, (u64)PAGE_SIZE - srcoffset);
+
+		memcpy(dst, src + srcoffset, chunk_size);
+		dst += chunk_size;
+		size -= chunk_size;
+		kunmap(page);
+
+		ret = srcit->next(srcit);
+		if (ret)
+			return ret;
+	}
+	WARN_ON(size > 0);
+	return 0;
+}
+
+/* copy data from kernel buffer to user data iterator */
+int nvme_mdev_write_to_udata(struct nvme_ext_data_iter *dstit, void *src,
+			     u64 size)
+{
+	int ret, dstoffset, chunk_size;
+
+	while (dstit->count && size > 0) {
+		struct page *page = pfn_to_page(PHYS_PFN(dstit->physical));
+		void *dst = kmap(page);
+
+		if (!dst)
+			return -ENOMEM;
+
+		dstoffset = OFFSET_IN_PAGE(dstit->physical);
+		chunk_size = min(size, (u64)PAGE_SIZE - dstoffset);
+
+		memcpy(dst + dstoffset, src, chunk_size);
+		src += chunk_size;
+		size -= chunk_size;
+		kunmap(page);
+
+		ret = dstit->next(dstit);
+		if (ret)
+			return ret;
+	}
+	WARN_ON(size > 0);
+	return 0;
+}
+
+/* Set prp list iterator to point to prp list found in create queue command */
+static int
+nvme_mdev_udata_iter_set_queue_prplist(struct nvme_mdev_viommu *viommu,
+				       struct nvme_ext_data_iter *iter,
+				       dma_addr_t iova, unsigned int size)
+{
+	if (iova & ~PAGE_MASK)
+		return -EINVAL;
+
+	nvme_mdev_udata_iter_setup(viommu, iter);
+	iter->count = DIV_ROUND_UP(size, PAGE_SIZE);
+	iter->next = nvme_mdev_udata_iter_next_prplist;
+	return nvme_mdev_udata_iter_load_prplist(iter, iova);
+}
+
+/* Map an SQ/CQ queue (contiguous in guest physical memory) */
+static int nvme_mdev_queue_getpages_contiguous(struct nvme_mdev_viommu *viommu,
+					       dma_addr_t iova,
+					       struct page **pages,
+					       unsigned int npages)
+{
+	int ret;
+	unsigned int i;
+
+	dma_addr_t host_page_iova;
+	phys_addr_t physical;
+
+	for (i = 0 ; i < npages; i++) {
+		ret = nvme_mdev_viommu_translate(viommu, iova + (PAGE_SIZE * i),
+						 &physical,
+						 &host_page_iova);
+		if (ret)
+			return ret;
+		pages[i] = pfn_to_page(PHYS_PFN(physical));
+	}
+	return 0;
+}
+
+/* Map an SQ/CQ queue (non contiguous in guest physical memory) */
+static int nvme_mdev_queue_getpages_prplist(struct nvme_mdev_viommu *viommu,
+					    dma_addr_t iova,
+					    struct page **pages,
+					    unsigned int npages)
+{
+	int ret, i = 0;
+	struct nvme_ext_data_iter uprpit;
+
+	ret = nvme_mdev_udata_iter_set_queue_prplist(viommu,
+						     &uprpit, iova,
+						     npages * PAGE_SIZE);
+	if (ret)
+		return ret;
+
+	while (uprpit.count && i < npages) {
+		pages[i++] = pfn_to_page(PHYS_PFN(uprpit.physical));
+		ret = uprpit.next(&uprpit);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+/* map a SQ/CQ queue to host physical memory */
+void *nvme_mdev_udata_queue_vmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova,
+				 unsigned int size,
+				 bool cont)
+{
+	int ret;
+	unsigned int npages;
+	void *map;
+	struct page **pages;
+
+	// queue must be page aligned
+	if (OFFSET_IN_PAGE(iova) != 0)
+		return ERR_PTR(-EINVAL);
+
+	npages = DIV_ROUND_UP(size, PAGE_SIZE);
+	pages = kcalloc(npages, sizeof(struct page *), GFP_KERNEL);
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+
+	ret = cont ?
+		nvme_mdev_queue_getpages_contiguous(viommu, iova, pages, npages)
+		: nvme_mdev_queue_getpages_prplist(viommu, iova, pages, npages);
+
+	if (ret) {
+		map = ERR_PTR(ret);
+		goto out;
+	}
+
+	map =  vmap(pages, npages, VM_MAP, PAGE_KERNEL);
+	if (!map)
+		map = ERR_PTR(-ENOMEM);
+out:
+	kfree(pages);
+	return map;
+}
diff --git a/drivers/nvme/mdev/vcq.c b/drivers/nvme/mdev/vcq.c
new file mode 100644
index 000000000000..7702137eb8bc
--- /dev/null
+++ b/drivers/nvme/mdev/vcq.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe completion queue implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "priv.h"
+
+/* Create new virtual completion queue */
+int nvme_mdev_vcq_init(struct nvme_mdev_vctrl *vctrl, u16 qid,
+		       dma_addr_t iova, bool cont, u16 size, int irq)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	int ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	q->iova = iova;
+	q->cont = cont;
+	q->data = NULL;
+	q->qid = qid;
+	q->size = size;
+	q->tail = 0;
+	q->phase = true;
+	q->irq = irq;
+	q->pending = 0;
+	q->head = 0;
+
+	ret = nvme_mdev_vcq_viommu_update(&vctrl->viommu, q);
+	if (ret && (ret != -EFAULT))
+		return ret;
+
+	_DBG(vctrl, "VCQ: create qid=%d contig=%d depth=%d irq=%d\n",
+	     qid, cont, size, irq);
+
+	set_bit(qid, vctrl->vcq_en);
+
+	vctrl->mmio.dbs[q->qid].cqh = 0;
+	vctrl->mmio.eidxs[q->qid].cqh = 0;
+	return 0;
+}
+
+/* Update the kernel mapping of the queue */
+int nvme_mdev_vcq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vcq *q)
+{
+	void *data;
+
+	if (q->data)
+		vunmap((void *)q->data);
+
+	data = nvme_mdev_udata_queue_vmap(viommu, q->iova,
+					  (unsigned int)q->size *
+					  sizeof(struct nvme_completion),
+					  q->cont);
+
+	q->data = IS_ERR(data) ? NULL : data;
+	return IS_ERR(data) ? PTR_ERR(data) : 0;
+}
+
+/* Delete a virtual completion queue */
+void nvme_mdev_vcq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (q->data)
+		vunmap((void *)q->data);
+	q->data = NULL;
+
+	_DBG(vctrl, "VCQ: delete qid=%d\n", q->qid);
+	clear_bit(qid, vctrl->vcq_en);
+}
+
+/* Move queue tail one item forward */
+static void nvme_mdev_vcq_advance_tail(struct nvme_vcq *q)
+{
+	if (++q->tail == q->size) {
+		q->tail = 0;
+		q->phase = !q->phase;
+	}
+}
+
+/* Move queue head one item forward */
+static void nvme_mdev_vcq_advance_head(struct nvme_vcq *q)
+{
+	q->head++;
+	if (q->head == q->size)
+		q->head = 0;
+}
+
+/* Process a virtual completion queue*/
+void nvme_mdev_vcq_process(struct nvme_mdev_vctrl *vctrl, u16 qid,
+			   bool trigger_irqs)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	u16 new_head;
+	u32 eidx;
+
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs)
+		return;
+
+	new_head = le32_to_cpu(vctrl->mmio.dbs[qid].cqh);
+
+	if (new_head != q->head) {
+		/* bad tail - can't process*/
+		if (!nvme_mdev_mmio_db_check(vctrl, q->qid, q->size, new_head))
+			return;
+
+		while (q->head != new_head) {
+			nvme_mdev_vcq_advance_head(q);
+			WARN_ON_ONCE(q->pending == 0);
+			if (q->pending > 0)
+				q->pending--;
+		}
+
+		eidx = q->head + (q->size >> 1);
+		if (eidx >= q->size)
+			eidx -= q->size;
+		vctrl->mmio.eidxs[q->qid].cqh = cpu_to_le32(eidx);
+	}
+
+	if (q->irq != -1 && trigger_irqs) {
+		if (q->tail != new_head)
+			nvme_mdev_irq_cond_trigger(vctrl, q->irq);
+		else
+			nvme_mdev_irq_clear(vctrl, q->irq);
+	}
+}
+
+/* flush interrupts on a completion queue */
+bool nvme_mdev_vcq_flush(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vcq *q = &vctrl->vcqs[qid];
+	u16 new_head = le32_to_cpu(vctrl->mmio.dbs[qid].cqh);
+
+	if (new_head == q->tail || q->irq == -1)
+		return false;
+
+	nvme_mdev_irq_trigger(vctrl, q->irq);
+	nvme_mdev_irq_clear(vctrl, q->irq);
+	return true;
+}
+
+/* Reserve space for one completion entry, that will be added later */
+bool nvme_mdev_vcq_reserve_space(struct nvme_vcq *q)
+{
+	/* TODOLATER: track passed through commmands
+	 * If we pass through a command to host and never receive a response
+	 * we will keep space for response in CQ forever, eventually stalling
+	 * the CQ forever.
+	 * In this case, the guest is still expected to recover by resetting
+	 * our controller
+	 * This can be fixed by tracking all the commands that we send
+	 * to the host
+	 */
+
+	if (q->pending == q->size - 1)
+		return false;
+	q->pending++;
+	return true;
+}
+
+/* Write a new item into the completion queue (IO version) */
+void nvme_mdev_vcq_write_io(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vcq *q, u16 sq_head,
+			    u16 sqid, u16 cid, u16 status)
+{
+	volatile u64 *qw = (__le64 *)(&q->data[q->tail]);
+
+	u64 phase = q->phase ? (0x1ULL << 48) : 0;
+	u64 qw1 =
+		((u64)sq_head) |
+		((u64)sqid << 16) |
+		((u64)cid << 32) |
+		((u64)status << 49) | phase;
+
+	WRITE_ONCE(qw[1], cpu_to_le64(qw1));
+
+	nvme_mdev_vcq_advance_tail(q);
+	if (q->irq != -1)
+		nvme_mdev_irq_raise(vctrl, q->irq);
+}
+
+/* Write a new item into the completion queue (ADMIN version) */
+void nvme_mdev_vcq_write_adm(struct nvme_mdev_vctrl *vctrl,
+			     struct nvme_vcq *q, u32 dw0,
+			     u16 sq_head, u16 cid, u16 status)
+{
+	volatile u64 *qw = (__le64 *)(&q->data[q->tail]);
+
+	u64 phase = q->phase ? (0x1ULL << 48) : 0;
+	u64 qw1 =
+		((u64)sq_head) |
+		((u64)cid << 32) |
+		((u64)status << 49) | phase;
+
+	WRITE_ONCE(qw[0], cpu_to_le64(dw0));
+	/* ensure that hardware sees the phase bit flip last */
+	wmb();
+	WRITE_ONCE(qw[1], cpu_to_le64(qw1));
+
+	nvme_mdev_vcq_advance_tail(q);
+	if (q->irq != -1)
+		nvme_mdev_irq_trigger(vctrl, q->irq);
+}
diff --git a/drivers/nvme/mdev/vctrl.c b/drivers/nvme/mdev/vctrl.c
new file mode 100644
index 000000000000..6f087b8fb2fc
--- /dev/null
+++ b/drivers/nvme/mdev/vctrl.c
@@ -0,0 +1,515 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe controller implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+bool nvme_mdev_vctrl_is_dead(struct nvme_mdev_vctrl *vctrl)
+{
+	return (vctrl->mmio.csts & (NVME_CSTS_CFS | NVME_CSTS_SHST_MASK)) != 0;
+}
+
+/* Setup the controller guid and serial */
+static void nvme_mdev_vctrl_init_id(struct nvme_mdev_vctrl *vctrl)
+{
+	guid_t guid = mdev_uuid(vctrl->mdev);
+
+	snprintf(vctrl->subnqn, sizeof(vctrl->subnqn),
+		 "nqn.2014-08.org.nvmexpress:uuid:%pUl", guid.b);
+
+	snprintf(vctrl->serial, sizeof(vctrl->serial), "%pUl", guid.b);
+}
+
+/* Change the IO thread CPU pinning */
+void nvme_mdev_vctrl_bind_iothread(struct nvme_mdev_vctrl *vctrl,
+				   unsigned int cpu)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (cpu == vctrl->iothread_cpu)
+		goto out;
+
+	nvme_mdev_io_free(vctrl);
+	nvme_mdev_io_create(vctrl, cpu);
+out:
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Change the status of support for shadow doorbell */
+int nvme_mdev_vctrl_set_shadow_doorbell_supported(struct nvme_mdev_vctrl *vctrl,
+						  bool enable)
+{
+	if (vctrl->inuse)
+		return -EBUSY;
+	vctrl->mmio.shadow_db_supported = enable;
+	return 0;
+}
+
+/* Called when memory mapping are changed. Propagate this to all kmap users */
+static void nvme_mdev_vctrl_viommu_update(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 qid;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	if (!(vctrl->mmio.csts & NVME_CSTS_RDY))
+		return;
+
+	/* update mappings for submission and completion queues */
+	for_each_set_bit(qid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vsq_viommu_update(&vctrl->viommu, &vctrl->vsqs[qid]);
+
+	for_each_set_bit(qid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vcq_viommu_update(&vctrl->viommu, &vctrl->vcqs[qid]);
+
+	/* update mapping for the shadow doorbells */
+	nvme_mdev_mmio_viommu_update(vctrl);
+}
+
+/* Create a new virtual controller */
+struct nvme_mdev_vctrl *nvme_mdev_vctrl_create(struct mdev_device *mdev,
+					       struct nvme_mdev_hctrl *hctrl,
+					       unsigned int max_host_queues)
+{
+	int ret;
+	struct nvme_mdev_vctrl *vctrl = kzalloc_node(sizeof(*vctrl),
+						     GFP_KERNEL, hctrl->node);
+	if (!vctrl)
+		return ERR_PTR(-ENOMEM);
+
+	/* Basic init */
+	vctrl->hctrl = hctrl;
+	vctrl->mdev = mdev;
+	vctrl->max_host_hw_queues = max_host_queues;
+	vctrl->viommu.vctrl = vctrl;
+
+	kref_init(&vctrl->ref);
+	mutex_init(&vctrl->lock);
+	nvme_mdev_vctrl_init_id(vctrl);
+	INIT_LIST_HEAD(&vctrl->host_hw_queues);
+
+	get_device(mdev_dev(mdev));
+	mdev_set_drvdata(mdev, vctrl);
+
+	/* reserve host IO queues */
+	if (!nvme_mdev_hctrl_hqs_reserve(hctrl, max_host_queues)) {
+		ret = -ENOSPC;
+		goto error1;
+	}
+
+	/* default feature values*/
+	vctrl->arb_burst_shift = 3;
+	vctrl->mmio.shadow_db_supported = use_shadow_doorbell;
+
+	ret = nvme_mdev_pci_create(vctrl);
+	if (ret)
+		goto error2;
+
+	ret = nvme_mdev_mmio_create(vctrl);
+	if (ret)
+		goto error3;
+
+	nvme_mdev_irqs_setup(vctrl);
+
+	/* Create the IO thread */
+	/*TODOLATER: IO: smp_processor_id() is not an ideal pinning choice */
+	ret = nvme_mdev_io_create(vctrl, smp_processor_id());
+	if (ret)
+		goto error4;
+
+	_INFO(vctrl, "device created using %d host queues\n", max_host_queues);
+	return vctrl;
+error4:
+	nvme_mdev_mmio_free(vctrl);
+error3:
+	nvme_mdev_pci_free(vctrl);
+error2:
+	nvme_mdev_hctrl_hqs_unreserve(hctrl, max_host_queues);
+error1:
+	put_device(mdev_dev(mdev));
+	kfree(vctrl);
+	return ERR_PTR(ret);
+}
+
+/*Try to destroy an vctrl */
+int nvme_mdev_vctrl_destroy(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->inuse) {
+		/* vctrl has mdev users */
+		mutex_unlock(&vctrl->lock);
+		return -EBUSY;
+	}
+
+	_INFO(vctrl, "device is destroying\n");
+
+	mdev_set_drvdata(vctrl->mdev, NULL);
+	mutex_unlock(&vctrl->lock);
+
+	mutex_lock(&nvme_mdev_vctrl_list_mutex);
+	list_del_init(&vctrl->link);
+	mutex_unlock(&nvme_mdev_vctrl_list_mutex);
+
+	mutex_lock(&vctrl->lock); /*only for lockdep checks */
+	nvme_mdev_io_free(vctrl);
+	nvme_mdev_vns_destroy_all(vctrl);
+	__nvme_mdev_vctrl_reset(vctrl, true);
+
+	nvme_mdev_hctrl_hqs_unreserve(vctrl->hctrl, vctrl->max_host_hw_queues);
+
+	nvme_mdev_pci_free(vctrl);
+	nvme_mdev_mmio_free(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+
+	put_device(mdev_dev(vctrl->mdev));
+	_INFO(vctrl, "device is destroyed\n");
+	kfree(vctrl);
+	return 0;
+}
+
+/* Suspends a running virtual controller
+ * Called when host needs to regain full control of the device
+ */
+void nvme_mdev_vctrl_pause(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	if (!vctrl->vctrl_paused) {
+		_INFO(vctrl, "pausing the virtual controller\n");
+		if (vctrl->mmio.csts & NVME_CSTS_RDY)
+			nvme_mdev_io_pause(vctrl);
+		vctrl->vctrl_paused = true;
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Resumes a virtual controller
+ * Called when host done with exclusive access and allows us
+ * again to attach to the controller
+ */
+void nvme_mdev_vctrl_resume(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	if (vctrl->vctrl_paused) {
+		_INFO(vctrl, "resuming the virtual controller\n");
+
+		if (vctrl->mmio.csts & NVME_CSTS_RDY) {
+			/* handle all pending admin commands*/
+			nvme_mdev_adm_process_sq(vctrl);
+			/* start the IO thread again if it was stopped or
+			 * if we had doorbell writes during the pause
+			 */
+			nvme_mdev_io_resume(vctrl);
+		}
+		vctrl->vctrl_paused = false;
+	}
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Called when emulator opens the virtual device */
+int nvme_mdev_vctrl_open(struct nvme_mdev_vctrl *vctrl)
+{
+	struct device *dma_dev = NULL;
+	int ret = 0;
+
+	mutex_lock(&vctrl->lock);
+
+	if (vctrl->hctrl->removing) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (vctrl->inuse) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	_INFO(vctrl, "device is opened\n");
+
+	if (vctrl->hctrl->nvme_ctrl->ops->flags & NVME_F_MDEV_DMA_SUPPORTED)
+		dma_dev = vctrl->hctrl->nvme_ctrl->dev;
+
+	nvme_mdev_viommu_init(&vctrl->viommu, mdev_dev(vctrl->mdev), dma_dev);
+
+	nvme_mdev_mmio_open(vctrl);
+	vctrl->inuse = true;
+out:
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Called when emulator closes the virtual device */
+void nvme_mdev_vctrl_release(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+
+	/* Remove the guest DMA mappings - new user that will open the
+	 * device might be a different guest
+	 */
+	nvme_mdev_viommu_reset(&vctrl->viommu);
+
+	/* Reset the controller to a clean state for a new user */
+	__nvme_mdev_vctrl_reset(vctrl, false);
+	nvme_mdev_irqs_reset(vctrl);
+	vctrl->inuse = false;
+	mutex_unlock(&vctrl->lock);
+
+	WARN_ON(!list_empty(&vctrl->host_hw_queues));
+
+	_INFO(vctrl, "device is released\n");
+
+	/* If we are released after request to remove the host controller
+	 * we are dead, won't be opened again ever, so remove ourselves
+	 */
+	if (vctrl->hctrl->removing)
+		nvme_mdev_vctrl_destroy(vctrl);
+}
+
+/* Called each time the controller is reset (CC.EN <= 0 or VM level reset) */
+void __nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl, bool pci_reset)
+{
+	lockdep_assert_held(&vctrl->lock);
+
+	if ((vctrl->mmio.csts & NVME_CSTS_RDY) &&
+	    !(vctrl->mmio.csts & NVME_CSTS_SHST_MASK)) {
+		_DBG(vctrl, "unsafe reset (CSTS.RDY==1)\n");
+		nvme_mdev_io_pause(vctrl);
+		nvme_mdev_vctrl_disable(vctrl);
+	}
+	nvme_mdev_mmio_reset(vctrl, pci_reset);
+}
+
+/* setups initial admin queues and doorbells */
+bool nvme_mdev_vctrl_enable(struct nvme_mdev_vctrl *vctrl,
+			    dma_addr_t cqiova, dma_addr_t sqiova, u32 sizes)
+{
+	int ret;
+	u16 cqentries, sqentries;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	lockdep_assert_held(&vctrl->lock);
+
+	sqentries = (sizes & 0xFFFF) + 1;
+	cqentries = (sizes >> 16) + 1;
+
+	if (cqentries > 4096 || cqentries < 2)
+		return false;
+	if (sqentries > 4096 || sqentries < 2)
+		return false;
+
+	ret = nvme_mdev_mmio_enable_dbs(vctrl);
+	if (ret)
+		goto error0;
+
+	ret = nvme_mdev_vcq_init(vctrl, 0, cqiova, true, cqentries, 0);
+	if (ret)
+		goto error1;
+
+	ret = nvme_mdev_vsq_init(vctrl, 0, sqiova, true, sqentries, 0);
+	if (ret)
+		goto error2;
+
+	nvme_mdev_events_init(vctrl);
+
+	if (!vctrl->mmio.shadow_db_supported) {
+		/* start polling right away to support admin queue */
+		vctrl->io_idle = false;
+		nvme_mdev_io_resume(vctrl);
+	}
+
+	return true;
+error2:
+	nvme_mdev_mmio_disable_dbs(vctrl);
+error1:
+	nvme_mdev_vcq_delete(vctrl, 0);
+error0:
+	return false;
+}
+
+/* destroy all io/admin queues on the controller  */
+void nvme_mdev_vctrl_disable(struct nvme_mdev_vctrl *vctrl)
+{
+	u16 sqid, cqid;
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	lockdep_assert_held(&vctrl->lock);
+
+	nvme_mdev_events_reset(vctrl);
+	nvme_mdev_vns_log_reset(vctrl);
+
+	sqid = 1;
+	for_each_set_bit_from(sqid, vctrl->vsq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vsq_delete(vctrl, sqid);
+
+	cqid = 1;
+	for_each_set_bit_from(cqid, vctrl->vcq_en, MAX_VIRTUAL_QUEUES)
+		nvme_mdev_vcq_delete(vctrl, cqid);
+
+	nvme_mdev_vsq_delete(vctrl, 0);
+	nvme_mdev_vcq_delete(vctrl, 0);
+
+	nvme_mdev_mmio_disable_dbs(vctrl);
+	vctrl->io_idle = true;
+}
+
+/* External reset */
+void nvme_mdev_vctrl_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	mutex_lock(&vctrl->lock);
+	_INFO(vctrl, "reset\n");
+	__nvme_mdev_vctrl_reset(vctrl, true);
+	mutex_unlock(&vctrl->lock);
+}
+
+/* Add IO region*/
+void nvme_mdev_vctrl_add_region(struct nvme_mdev_vctrl *vctrl,
+				unsigned int index, unsigned int size,
+				region_access_fn access_fn)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->size = size;
+	region->rw = access_fn;
+	region->mmap_ops = NULL;
+}
+
+/* Enable mmap window on an IO region */
+void nvme_mdev_vctrl_region_set_mmap(struct nvme_mdev_vctrl *vctrl,
+				     unsigned int index,
+				     unsigned int offset,
+				     unsigned int size,
+				     const struct vm_operations_struct *ops)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->mmap_area_start = offset;
+	region->mmap_area_size = size;
+	region->mmap_ops = ops;
+}
+
+/* Disable mmap window on an IO region */
+void nvme_mdev_vctrl_region_disable_mmap(struct nvme_mdev_vctrl *vctrl,
+					 unsigned int index)
+{
+	struct nvme_mdev_io_region *region = &vctrl->regions[index];
+
+	region->mmap_area_start = 0;
+	region->mmap_area_size = 0;
+	region->mmap_ops = NULL;
+}
+
+/* Allocate a host IO queue */
+int nvme_mdev_vctrl_hq_alloc(struct nvme_mdev_vctrl *vctrl)
+{
+	struct nvme_mdev_hq *hq = NULL, *tmp;
+	int hwqcount = 0, ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	list_for_each_entry(tmp, &vctrl->host_hw_queues, link) {
+		if (!hq || tmp->usecount < hq->usecount)
+			hq = tmp;
+		hwqcount++;
+	}
+
+	if (hwqcount < vctrl->max_host_hw_queues) {
+		ret = nvme_mdev_hctrl_hq_alloc(vctrl->hctrl);
+		if (ret < 0)
+			return ret;
+
+		hq = kzalloc_node(sizeof(*hq), GFP_KERNEL, vctrl->hctrl->node);
+		if (!hq) {
+			nvme_mdev_hctrl_hq_free(vctrl->hctrl, ret);
+			return -ENOMEM;
+		}
+
+		hq->hqid = ret;
+		hq->usecount = 1;
+		list_add_tail(&hq->link, &vctrl->host_hw_queues);
+	} else {
+		hq->usecount++;
+	}
+	return hq->hqid;
+}
+
+/* Free a host IO queue */
+void nvme_mdev_vctrl_hq_free(struct nvme_mdev_vctrl *vctrl, u16 hqid)
+{
+	struct nvme_mdev_hq *hq;
+
+	lockdep_assert_held(&vctrl->lock);
+	nvme_mdev_assert_io_not_running(vctrl);
+
+	list_for_each_entry(hq, &vctrl->host_hw_queues, link)
+		if (hq->hqid == hqid) {
+			if (--hq->usecount > 0)
+				return;
+			nvme_mdev_hctrl_hq_free(vctrl->hctrl, hq->hqid);
+			list_del(&hq->link);
+			kfree(hq);
+			return;
+		}
+	WARN_ON(1);
+}
+
+/* get current list of host queues */
+unsigned int nvme_mdev_vctrl_hqs_list(struct nvme_mdev_vctrl *vctrl, u16 *out)
+{
+	struct nvme_mdev_hq *q;
+	unsigned int i = 0;
+
+	list_for_each_entry(q, &vctrl->host_hw_queues, link) {
+		out[i++] = q->hqid;
+		if (WARN_ON(i > MAX_HOST_QUEUES))
+			break;
+	}
+	return i;
+}
+
+/* add a user memory mapping */
+int nvme_mdev_vctrl_viommu_map(struct nvme_mdev_vctrl *vctrl, u32 flags,
+			       dma_addr_t iova, u64 size)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+
+	nvme_mdev_io_pause(vctrl);
+	ret = nvme_mdev_viommu_add(&vctrl->viommu, flags, iova, size);
+	nvme_mdev_vctrl_viommu_update(vctrl);
+	nvme_mdev_io_resume(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* remove a user memory mapping */
+int nvme_mdev_vctrl_viommu_unmap(struct nvme_mdev_vctrl *vctrl,
+				 dma_addr_t iova, u64 size)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+
+	nvme_mdev_io_pause(vctrl);
+	ret = nvme_mdev_viommu_remove(&vctrl->viommu, iova, size);
+	nvme_mdev_vctrl_viommu_update(vctrl);
+	nvme_mdev_io_resume(vctrl);
+
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
diff --git a/drivers/nvme/mdev/viommu.c b/drivers/nvme/mdev/viommu.c
new file mode 100644
index 000000000000..31b86e8f5768
--- /dev/null
+++ b/drivers/nvme/mdev/viommu.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual IOMMU - mapping user memory to the real device
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/mdev.h>
+#include <linux/vmalloc.h>
+#include <linux/nvme.h>
+#include <linux/iommu.h>
+#include <linux/interval_tree_generic.h>
+#include "priv.h"
+
+struct mem_mapping {
+	struct rb_node rb;
+	struct list_head link;
+
+	dma_addr_t __subtree_last;
+	dma_addr_t iova_start; /* first iova in this mapping*/
+	dma_addr_t iova_last;  /* last iova in this mapping*/
+
+	unsigned long pfn;  /* physical address of this mapping */
+	dma_addr_t host_iova;  /* dma mapping to the real device*/
+};
+
+#define map_len(m) (((m)->iova_last - (m)->iova_start) + 1ULL)
+#define map_pages(m) (map_len(m) >> PAGE_SHIFT)
+#define START(node) ((node)->iova_start)
+#define LAST(node) ((node)->iova_last)
+
+INTERVAL_TREE_DEFINE(struct mem_mapping, rb, dma_addr_t, __subtree_last,
+		     START, LAST, static inline, viommu_int_tree);
+
+static void nvme_mdev_viommu_dbg_dma_range(struct nvme_mdev_viommu *viommu,
+					   struct mem_mapping *map,
+					   const char *action)
+{
+	dma_addr_t iova_start  = map->iova_start;
+	dma_addr_t iova_end    = map->iova_start + map_len(map) - 1;
+	dma_addr_t hiova_start = map->host_iova;
+	dma_addr_t hiova_end   = map->host_iova  + map_len(map) - 1;
+
+	_DBG(viommu->vctrl,
+	     "vIOMMU: %s RW IOVA %pad-%pad -> DMA %pad-%pad\n",
+	     action, &iova_start, &iova_end, &hiova_start, &hiova_end);
+}
+
+/* unpin N pages starting at given IOVA*/
+static void nvme_mdev_viommu_unpin_pages(struct nvme_mdev_viommu *viommu,
+					 dma_addr_t iova, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		unsigned long  user_pfn = (iova >> PAGE_SHIFT) + i;
+		int ret = vfio_unpin_pages(viommu->sw_dev, &user_pfn, 1);
+
+		WARN_ON(ret != 1);
+	}
+}
+
+/* User memory init code*/
+void nvme_mdev_viommu_init(struct nvme_mdev_viommu *viommu,
+			   struct device *sw_dev,
+			   struct device *hw_dev)
+{
+	viommu->sw_dev = sw_dev;
+	viommu->hw_dev = hw_dev;
+	viommu->maps_tree = RB_ROOT_CACHED;
+	INIT_LIST_HEAD(&viommu->maps_list);
+}
+
+/* User memory end code*/
+void nvme_mdev_viommu_reset(struct nvme_mdev_viommu *viommu)
+{
+	nvme_mdev_viommu_remove(viommu, 0, 0xFFFFFFFFFFFFFFFFULL);
+	WARN_ON(!list_empty(&viommu->maps_list));
+}
+
+/* Adds a new range of user memory*/
+int nvme_mdev_viommu_add(struct nvme_mdev_viommu *viommu,
+			 u32 flags,
+			 dma_addr_t iova,
+			 u64 size)
+{
+	u64 offset;
+	dma_addr_t iova_end = iova + size - 1;
+	struct mem_mapping *map = NULL, *tmp;
+	LIST_HEAD(new_mappings_list);
+	int ret;
+
+	if (!(flags & VFIO_DMA_MAP_FLAG_READ) ||
+	    !(flags & VFIO_DMA_MAP_FLAG_WRITE)) {
+		const char *type = "none";
+
+		if (flags & VFIO_DMA_MAP_FLAG_READ)
+			type = "RO";
+		else if (flags & VFIO_DMA_MAP_FLAG_WRITE)
+			type = "WO";
+
+		_DBG(viommu->vctrl, "vIOMMU: IGN %s IOVA %pad-%pad\n",
+		     type, &iova, &iova_end);
+		return 0;
+	}
+
+	WARN_ON_ONCE(nvme_mdev_viommu_remove(viommu, iova, size) != 0);
+
+	if (WARN_ON_ONCE(size & ~PAGE_MASK))
+		return -EINVAL;
+
+	// VFIO pinning all the pages
+	for (offset = 0; offset < size; offset += PAGE_SIZE) {
+		unsigned long vapfn = ((iova + offset) >> PAGE_SHIFT), pa_pfn;
+
+		ret = vfio_pin_pages(viommu->sw_dev,
+				     &vapfn, 1,
+				     VFIO_DMA_MAP_FLAG_READ |
+				     VFIO_DMA_MAP_FLAG_WRITE,
+				     &pa_pfn);
+
+		if (ret != 1) {
+			/*sadly mdev api doesn't return an error*/
+			ret = -EFAULT;
+
+			_DBG(viommu->vctrl,
+			     "vIOMMU: ADD RW IOVA %pad - pin failed\n",
+			     &iova);
+			goto unwind;
+		}
+
+		// new mapping needed
+		if (!map || map->pfn + map_pages(map) != pa_pfn) {
+			int node = viommu->hw_dev ?
+				dev_to_node(viommu->hw_dev) : NUMA_NO_NODE;
+
+			map = kzalloc_node(sizeof(*map), GFP_KERNEL, node);
+
+			if (WARN_ON(!map)) {
+				vfio_unpin_pages(viommu->sw_dev, &vapfn, 1);
+				ret = -ENOMEM;
+				goto unwind;
+			}
+			map->iova_start = iova + offset;
+			map->iova_last = iova + offset + PAGE_SIZE - 1ULL;
+			map->pfn = pa_pfn;
+			map->host_iova = 0;
+			list_add_tail(&map->link, &new_mappings_list);
+		} else {
+			// current map can be extended
+			map->iova_last += PAGE_SIZE;
+		}
+	}
+
+	// DMA mapping the pages
+	list_for_each_entry_safe(map, tmp, &new_mappings_list, link) {
+		if (viommu->hw_dev) {
+			map->host_iova =
+				dma_map_page(viommu->hw_dev,
+					     pfn_to_page(map->pfn),
+					     0,
+					     map_len(map),
+					     DMA_BIDIRECTIONAL);
+
+			ret = dma_mapping_error(viommu->hw_dev, map->host_iova);
+			if (ret) {
+				_DBG(viommu->vctrl,
+				     "vIOMMU: ADD RW IOVA %pad-%pad - DMA map failed\n",
+				     &iova, &iova_end);
+				goto unwind;
+			}
+		}
+
+		nvme_mdev_viommu_dbg_dma_range(viommu, map, "ADD");
+		list_del(&map->link);
+		list_add_tail(&map->link, &viommu->maps_list);
+		viommu_int_tree_insert(map, &viommu->maps_tree);
+	}
+	return 0;
+unwind:
+	list_for_each_entry_safe(map, tmp, &new_mappings_list, link) {
+		nvme_mdev_viommu_unpin_pages(viommu, map->iova_start,
+					     map_pages(map));
+
+		list_del(&map->link);
+		kfree(map);
+	}
+	nvme_mdev_viommu_remove(viommu, iova, size);
+	return ret;
+}
+
+/* Removes a  range of user memory*/
+int nvme_mdev_viommu_remove(struct nvme_mdev_viommu *viommu,
+			    dma_addr_t iova,
+			    u64 size)
+{
+	struct mem_mapping *map = NULL, *tmp;
+	dma_addr_t last_iova = iova + (size) - 1ULL;
+	LIST_HEAD(remove_list);
+	int count = 0;
+
+	/* find out all the relevant ranges */
+	map = viommu_int_tree_iter_first(&viommu->maps_tree, iova, last_iova);
+	while (map) {
+		list_del(&map->link);
+		list_add_tail(&map->link, &remove_list);
+		map = viommu_int_tree_iter_next(map, iova, last_iova);
+	}
+
+	/* remove them */
+	list_for_each_entry_safe(map, tmp, &remove_list, link) {
+		count++;
+
+		nvme_mdev_viommu_dbg_dma_range(viommu, map, "DEL");
+		if (viommu->hw_dev)
+			dma_unmap_page(viommu->hw_dev, map->host_iova,
+				       map_len(map), DMA_BIDIRECTIONAL);
+
+		nvme_mdev_viommu_unpin_pages(viommu, map->iova_start,
+					     map_pages(map));
+
+		viommu_int_tree_remove(map, &viommu->maps_tree);
+		kfree(map);
+	}
+	return count;
+}
+
+/* Translate an IOVA to a physical address and read device bus address */
+int nvme_mdev_viommu_translate(struct nvme_mdev_viommu *viommu,
+			       dma_addr_t iova,
+			       dma_addr_t *physical,
+			       dma_addr_t *host_iova)
+{
+	struct mem_mapping *mapping;
+	u64 offset;
+
+	if (WARN_ON_ONCE(OFFSET_IN_PAGE(iova) != 0))
+		return -EINVAL;
+
+	mapping = viommu_int_tree_iter_first(&viommu->maps_tree,
+					     iova, iova + PAGE_SIZE - 1);
+	if (!mapping) {
+		_DBG(viommu->vctrl,
+		     "vIOMMU: translation of IOVA %pad failed\n", &iova);
+		return -EFAULT;
+	}
+
+	WARN_ON(iova > mapping->iova_last);
+	WARN_ON(OFFSET_IN_PAGE(mapping->iova_start) != 0);
+
+	offset = iova - mapping->iova_start;
+	*physical = PFN_PHYS(mapping->pfn) + offset;
+	*host_iova = mapping->host_iova + offset;
+	return 0;
+}
+
+/* map an IOVA to kernel address space  */
+int nvme_mdev_viommu_create_kmap(struct nvme_mdev_viommu *viommu,
+				 dma_addr_t iova, struct page_map *page)
+{
+	dma_addr_t host_iova;
+	phys_addr_t physical;
+	struct page *new_page;
+	int ret;
+
+	page->iova = iova;
+
+	ret = nvme_mdev_viommu_translate(viommu, iova, &physical, &host_iova);
+	if (ret)
+		return ret;
+
+	new_page = pfn_to_page(PHYS_PFN(physical));
+
+	page->kmap = kmap(new_page);
+	if (!page->kmap)
+		return -ENOMEM;
+
+	page->page = new_page;
+	return 0;
+}
+
+/* update IOVA <-> kernel mapping. If fails, removes the previous mapping */
+void nvme_mdev_viommu_update_kmap(struct nvme_mdev_viommu *viommu,
+				  struct page_map *page)
+{
+	dma_addr_t host_iova;
+	phys_addr_t physical;
+	struct page *new_page;
+	int ret;
+
+	ret = nvme_mdev_viommu_translate(viommu, page->iova,
+					 &physical, &host_iova);
+	if (ret) {
+		nvme_mdev_viommu_free_kmap(viommu, page);
+		return;
+	}
+
+	new_page = pfn_to_page(PHYS_PFN(physical));
+	if (new_page == page->page)
+		return;
+
+	nvme_mdev_viommu_free_kmap(viommu, page);
+
+	page->kmap = kmap(new_page);
+	if (!page->kmap)
+		return;
+	page->page = new_page;
+}
+
+/* unmap an IOVA to kernel address space  */
+void nvme_mdev_viommu_free_kmap(struct nvme_mdev_viommu *viommu,
+				struct page_map *page)
+{
+	if (page->page) {
+		kunmap(page->page);
+		page->page = NULL;
+		page->kmap = NULL;
+	}
+}
diff --git a/drivers/nvme/mdev/vns.c b/drivers/nvme/mdev/vns.c
new file mode 100644
index 000000000000..42d4f8d7423b
--- /dev/null
+++ b/drivers/nvme/mdev/vns.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe namespace implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/nvme.h>
+#include "priv.h"
+
+/* Reset the changed namespace log */
+void nvme_mdev_vns_log_reset(struct nvme_mdev_vctrl *vctrl)
+{
+	vctrl->ns_log_size = 0;
+}
+
+/* This adds entry to NS changed log and sends to the user a notification */
+static void nvme_mdev_vns_send_event(struct nvme_mdev_vctrl *vctrl, u32 ns)
+{
+	unsigned int i;
+	unsigned int log_size = vctrl->ns_log_size;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	_INFO(vctrl, "host namespace list rescanned\n");
+
+	if (WARN_ON(ns == 0 || ns > MAX_VIRTUAL_NAMESPACES))
+		return;
+
+	// check if the namespace ID is alredy in the log
+	if (log_size == MAX_VIRTUAL_NAMESPACES)
+		return;
+
+	for (i = 0; i < log_size; i++)
+		if (vctrl->ns_log[i] == cpu_to_le32(ns))
+			return;
+
+	vctrl->ns_log[log_size++] = cpu_to_le32(ns);
+	vctrl->ns_log_size++;
+	nvme_mdev_event_send(vctrl, NVME_AER_TYPE_NOTICE,
+			     NVME_AER_NOTICE_NS_CHANGED);
+}
+
+/* Read host NS/partition parameters to update our virtual NS */
+static void nvme_mdev_vns_read_host_properties(struct nvme_mdev_vctrl *vctrl,
+					       struct nvme_mdev_vns *vns,
+					       struct nvme_ns *host_ns)
+{
+	unsigned int sector_to_lba_shift;
+	u64 host_ns_size, start, nr, align_mask;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	/* read the namespace block size */
+	vns->blksize_shift = host_ns->lba_shift;
+
+	if (WARN_ON(vns->blksize_shift < 9)) {
+		_WARN(vctrl, "NS/create: device block size is bad\n");
+		goto error;
+	}
+
+	sector_to_lba_shift = vns->blksize_shift - 9;
+	align_mask = (1ULL << sector_to_lba_shift) - 1;
+
+	/* read the partition start and size*/
+	start = get_start_sect(vns->host_part);
+	nr = part_nr_sects_read(vns->host_part->bd_part);
+
+	/* check that partition is aligned on LBA size*/
+	if (sector_to_lba_shift != 0) {
+		if ((start & align_mask) || (nr & align_mask)) {
+			_WARN(vctrl, "NS/create: partition not aligned\n");
+			goto error;
+		}
+	}
+
+	vns->host_lba_offset = start >> sector_to_lba_shift;
+	vns->ns_size = nr >> sector_to_lba_shift;
+	host_ns_size = get_capacity(host_ns->disk) >> sector_to_lba_shift;
+
+	/*TODOLATER: NS: support metadata on host namespace */
+	if (host_ns->ms) {
+		_WARN(vctrl, "NS/create: no support for namespace metadata\n");
+		goto error;
+	}
+
+	if (vns->ns_size == 0) {
+		_WARN(vctrl, "NS/create: host namespace has size 0\n");
+		goto error;
+	}
+
+	/* sanity check that partition doesn't extend beyond the namespace */
+	if (!check_range(vns->host_lba_offset, vns->ns_size, host_ns_size)) {
+		_WARN(vctrl, "NS/create: host namespace size mismatch\n");
+		goto error;
+	}
+
+	/* check if namespace is readonly*/
+	if (!vns->readonly)
+		vns->readonly = get_disk_ro(host_ns->disk);
+
+	vns->noiob = host_ns->noiob;
+	if (vns->noiob != 0) {
+		u64 tmp = vns->host_lba_offset;
+
+		if (do_div(tmp, vns->noiob)) {
+			_WARN(vctrl,
+			      "NS/create: host partition is not aligned on host optimum IO boundary, performance might suffer");
+			vns->noiob = 0;
+		}
+	}
+	return;
+error:
+	vns->ns_size = 0;
+}
+
+/* Open new reference to a host namespace */
+int nvme_mdev_vns_open(struct nvme_mdev_vctrl *vctrl,
+		       u32 host_nsid, unsigned int host_partid)
+{
+	struct nvme_mdev_vns *vns;
+	u32 user_nsid;
+	int ret;
+
+	_INFO(vctrl, "open host_namespace=%u, partition=%u\n",
+	      host_nsid, host_partid);
+
+	mutex_lock(&vctrl->lock);
+	ret = -ENODEV;
+	if (nvme_mdev_vctrl_is_dead(vctrl))
+		goto out;
+
+	/* create the namespace object */
+	ret = -ENOMEM;
+	vns = kzalloc_node(sizeof(*vns), GFP_KERNEL, vctrl->hctrl->node);
+	if (!vns)
+		goto out;
+
+	uuid_gen(&vns->uuid); // TODOLATER: NS: non random NS UUID
+	vns->host_nsid = host_nsid;
+	vns->host_partid = host_partid;
+
+	/* find the host namespace */
+	vns->host_ns = nvme_find_get_ns(vctrl->hctrl->nvme_ctrl, host_nsid);
+	if (!vns->host_ns) {
+		ret = -ENODEV;
+		goto error1;
+	}
+
+	if (test_bit(NVME_NS_DEAD, &vns->host_ns->flags) ||
+	    test_bit(NVME_NS_REMOVING, &vns->host_ns->flags) ||
+	    !vns->host_ns->disk) {
+		ret = -ENODEV;
+		goto error2;
+	}
+
+	/* get the block device for the partition that we will use */
+	vns->host_part = bdget_disk(vns->host_ns->disk, host_partid);
+	if (!vns->host_part) {
+		ret = -ENODEV;
+		goto error2;
+	}
+
+	/* get exclusive access to the block device (partition) */
+	vns->fmode = FMODE_READ | FMODE_EXCL;
+	if (!vns->readonly)
+		vns->fmode |= FMODE_WRITE;
+
+	ret = blkdev_get(vns->host_part, vns->fmode, vns);
+	if (ret)
+		goto error2;
+
+	/* read properties of the host namespace */
+	nvme_mdev_vns_read_host_properties(vctrl, vns, vns->host_ns);
+
+	/* Allocate a user namespace ID for this namespace */
+	ret = -ENOSPC;
+	for (user_nsid = 1; user_nsid <= MAX_VIRTUAL_NAMESPACES; user_nsid++)
+		if (!nvme_mdev_vns_from_vnsid(vctrl, user_nsid))
+			break;
+
+	if (user_nsid > MAX_VIRTUAL_NAMESPACES)
+		goto error3;
+
+	nvme_mdev_io_pause(vctrl);
+
+	vctrl->namespaces[user_nsid - 1] = vns;
+	vns->nsid = user_nsid;
+
+	/* Announce the new namespace to the user */
+	nvme_mdev_vns_send_event(vctrl, user_nsid);
+	nvme_mdev_io_resume(vctrl);
+	ret = 0;
+	goto out;
+error3:
+	blkdev_put(vns->host_part, vns->fmode);
+error2:
+	nvme_put_ns(vns->host_ns);
+error1:
+	kfree(vns);
+out:
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Re-open new reference to a host namespace, after notification
+ * of change in the host namespace
+ */
+static bool nvme_mdev_vns_reopen(struct nvme_mdev_vctrl *vctrl,
+				 struct nvme_mdev_vns *vns)
+{
+	struct nvme_ns *host_ns;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	_INFO(vctrl, "reopen host namespace %u, partition=%u\n",
+	      vns->host_nsid, vns->host_partid);
+
+	/* namespace disappeared on the host - invalid*/
+	host_ns = nvme_find_get_ns(vctrl->hctrl->nvme_ctrl, vns->host_nsid);
+	if (!host_ns)
+		return false;
+
+	/* different namespace with same ID on the host - invalid*/
+	if (vns->host_ns != host_ns)
+		goto error1;
+
+	// basic checks on the namespace
+	if (test_bit(NVME_NS_DEAD, &host_ns->flags) ||
+	    test_bit(NVME_NS_REMOVING, &host_ns->flags) ||
+	    !host_ns->disk)
+		goto error1;
+
+	/* read properties of the host namespace */
+	nvme_mdev_io_pause(vctrl);
+	nvme_mdev_vns_read_host_properties(vctrl, vns, host_ns);
+	nvme_mdev_io_resume(vctrl);
+
+	nvme_put_ns(host_ns);
+	return true;
+error1:
+	nvme_put_ns(host_ns);
+	return false;
+}
+
+/* Destroy a virtual namespace*/
+static int __nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl, u32 user_nsid)
+{
+	struct nvme_mdev_vns *vns;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	vns = nvme_mdev_vns_from_vnsid(vctrl, user_nsid);
+	if (!vns)
+		return -ENODEV;
+
+	nvme_mdev_vns_send_event(vctrl, user_nsid);
+	nvme_mdev_io_pause(vctrl);
+
+	vctrl->namespaces[user_nsid - 1] = NULL;
+	blkdev_put(vns->host_part, vns->fmode);
+	nvme_put_ns(vns->host_ns);
+	kfree(vns);
+	nvme_mdev_io_resume(vctrl);
+	return 0;
+}
+
+/* Destroy a virtual namespace (external interface) */
+int nvme_mdev_vns_destroy(struct nvme_mdev_vctrl *vctrl, u32 user_nsid)
+{
+	int ret;
+
+	mutex_lock(&vctrl->lock);
+	nvme_mdev_io_pause(vctrl);
+	ret = __nvme_mdev_vns_destroy(vctrl, user_nsid);
+	nvme_mdev_io_resume(vctrl);
+	mutex_unlock(&vctrl->lock);
+
+	return ret;
+}
+
+/* Destroy all virtual namespaces */
+void nvme_mdev_vns_destroy_all(struct nvme_mdev_vctrl *vctrl)
+{
+	u32 user_nsid;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	for (user_nsid = 1 ; user_nsid <= MAX_VIRTUAL_NAMESPACES ; user_nsid++)
+		__nvme_mdev_vns_destroy(vctrl, user_nsid);
+}
+
+/* Get a virtual namespace */
+struct nvme_mdev_vns *nvme_mdev_vns_from_vnsid(struct nvme_mdev_vctrl *vctrl,
+					       u32 user_ns_id)
+{
+	if (user_ns_id == 0 || user_ns_id > MAX_VIRTUAL_NAMESPACES)
+		return NULL;
+	return vctrl->namespaces[user_ns_id - 1];
+}
+
+/* Print description off all virtual namespaces */
+int nvme_mdev_vns_print_description(struct nvme_mdev_vctrl *vctrl,
+				    char *buf, unsigned int size)
+{
+	int nsid, ret = 0;
+
+	mutex_lock(&vctrl->lock);
+
+	for (nsid = 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++) {
+		int n;
+		struct nvme_mdev_vns *vns = nvme_mdev_vns_from_vnsid(vctrl,
+				nsid);
+		if (!vns)
+			continue;
+
+		else if (vns->host_partid == 0)
+			n = snprintf(buf, size, "VNS%d: nvme%dn%d\n",
+				     nsid, vctrl->hctrl->id,
+				     (int)vns->host_nsid);
+		else
+			n = snprintf(buf, size, "VNS%d: nvme%dn%dp%d\n",
+				     nsid, vctrl->hctrl->id,
+				     (int)vns->host_nsid,
+				     (int)vns->host_partid);
+		if (n > size)
+			return -ENOMEM;
+		buf += n;
+		size -= n;
+		ret += n;
+	}
+	mutex_unlock(&vctrl->lock);
+	return ret;
+}
+
+/* Processes an update on the host namespace */
+void nvme_mdev_vns_host_ns_update(struct nvme_mdev_vctrl *vctrl,
+				  u32 host_nsid, bool removed)
+{
+	int nsid;
+
+	mutex_lock(&vctrl->lock);
+
+	for (nsid = 1; nsid <= MAX_VIRTUAL_NAMESPACES; nsid++) {
+		struct nvme_mdev_vns *vns = nvme_mdev_vns_from_vnsid(vctrl,
+								     nsid);
+		if (!vns || vns->host_nsid != host_nsid)
+			continue;
+
+		if (removed || !nvme_mdev_vns_reopen(vctrl, vns))
+			__nvme_mdev_vns_destroy(vctrl, nsid);
+		else
+			nvme_mdev_vns_send_event(vctrl, nsid);
+	}
+	mutex_unlock(&vctrl->lock);
+}
diff --git a/drivers/nvme/mdev/vsq.c b/drivers/nvme/mdev/vsq.c
new file mode 100644
index 000000000000..5b63081c144d
--- /dev/null
+++ b/drivers/nvme/mdev/vsq.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtual NVMe submission queue implementation
+ * Copyright (c) 2019 - Maxim Levitsky
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include "priv.h"
+
+/* Create new virtual completion queue */
+int nvme_mdev_vsq_init(struct nvme_mdev_vctrl *vctrl,
+		       u16 qid, dma_addr_t iova, bool cont, u16 size, u16 cqid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[qid];
+	int ret;
+
+	lockdep_assert_held(&vctrl->lock);
+
+	q->iova = iova;
+	q->cont = cont;
+	q->qid = qid;
+	q->size = size;
+	q->head = 0;
+	q->vcq = &vctrl->vcqs[cqid];
+	q->data = NULL;
+	q->hsq = 0;
+
+	ret = nvme_mdev_vsq_viommu_update(&vctrl->viommu, q);
+	if (ret && (ret != -EFAULT))
+		return ret;
+
+	if (qid > 0) {
+		ret = nvme_mdev_vctrl_hq_alloc(vctrl);
+		if (ret < 0) {
+			vunmap(q->data);
+			return ret;
+		}
+		q->hsq = ret;
+	}
+
+	_DBG(vctrl, "VSQ: create qid=%d contig=%d, depth=%d cqid=%d\n",
+	     qid, cont, size, cqid);
+
+	set_bit(qid, vctrl->vsq_en);
+
+	vctrl->mmio.dbs[q->qid].sqt = 0;
+	vctrl->mmio.eidxs[q->qid].sqt = 0;
+
+	return 0;
+}
+
+/* Update the kernel mapping of the queue */
+int nvme_mdev_vsq_viommu_update(struct nvme_mdev_viommu *viommu,
+				struct nvme_vsq *q)
+{
+	void *data;
+
+	if (q->data)
+		vunmap((void *)q->data);
+
+	data = nvme_mdev_udata_queue_vmap(viommu, q->iova,
+					  (unsigned int)q->size *
+					  sizeof(struct nvme_command),
+					  q->cont);
+
+	q->data = IS_ERR(data) ? NULL : data;
+	return IS_ERR(data) ? PTR_ERR(data) : 0;
+}
+
+/* Delete an virtual completion queue */
+void nvme_mdev_vsq_delete(struct nvme_mdev_vctrl *vctrl, u16 qid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[qid];
+
+	lockdep_assert_held(&vctrl->lock);
+	_DBG(vctrl, "VSQ: delete qid=%d\n", q->qid);
+
+	if (q->data)
+		vunmap(q->data);
+	q->data = NULL;
+
+	if (q->hsq) {
+		nvme_mdev_vctrl_hq_free(vctrl, q->hsq);
+		q->hsq = 0;
+	}
+
+	clear_bit(qid, vctrl->vsq_en);
+}
+
+/* Move queue head one item forward */
+static void nvme_mdev_vsq_advance_head(struct nvme_vsq *q)
+{
+	q->head++;
+	if (q->head == q->size)
+		q->head = 0;
+}
+
+bool nvme_mdev_vsq_has_data(struct nvme_mdev_vctrl *vctrl,
+			    struct nvme_vsq *q)
+{
+	u16 tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data)
+		return false;
+
+	if  (tail == q->head)
+		return false;
+
+	if (!nvme_mdev_mmio_db_check(vctrl, q->qid, q->size, tail))
+		return false;
+	return true;
+}
+
+/* get one command from a virtual submission queue */
+const struct nvme_command *nvme_mdev_vsq_get_cmd(struct nvme_mdev_vctrl *vctrl,
+						 struct nvme_vsq *q)
+{
+	u16 oldhead = q->head;
+	u32 eidx;
+
+	if (!nvme_mdev_vsq_has_data(vctrl, q))
+		return NULL;
+	if (!nvme_mdev_vcq_reserve_space(q->vcq))
+		return NULL;
+	nvme_mdev_vsq_advance_head(q);
+
+	eidx = q->head + (q->size >> 1);
+	if (eidx >= q->size)
+		eidx -= q->size;
+
+	vctrl->mmio.eidxs[q->qid].sqt = cpu_to_le32(eidx);
+
+	return &q->data[oldhead];
+}
+
+bool nvme_mdev_vsq_suspend_io(struct nvme_mdev_vctrl *vctrl, u16 sqid)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[sqid];
+	u16 tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+
+	/* If the queue is not in working state don't allow the idle code
+	 * to kick in
+	 */
+	if (!vctrl->mmio.dbs || !vctrl->mmio.eidxs || !q->data)
+		return false;
+
+	/* queue has data - refuse idle*/
+	if (tail != q->head)
+		return false;
+
+	/* Write eventid to tell the user to ring normal doorbell*/
+	vctrl->mmio.eidxs[q->qid].sqt = cpu_to_le32(q->head);
+
+	/* memory barrier to ensure that the user have seen the eidx */
+	mb();
+
+	/* Check that doorbell diddn't move meanwhile */
+	tail = le32_to_cpu(vctrl->mmio.dbs[q->qid].sqt);
+	return (tail == q->head);
+}
+
+/* complete a command (IO version)*/
+void nvme_mdev_vsq_cmd_done_io(struct nvme_mdev_vctrl *vctrl,
+			       u16 sqid, u16 cid, u16 status)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[sqid];
+
+	nvme_mdev_vcq_write_io(vctrl, q->vcq, q->head, q->qid, cid, status);
+}
+
+/* complete a command (ADMIN version)*/
+void nvme_mdev_vsq_cmd_done_adm(struct nvme_mdev_vctrl *vctrl,
+				u32 dw0, u16 cid, u16 status)
+{
+	struct nvme_vsq *q = &vctrl->vsqs[0];
+
+	nvme_mdev_vcq_write_adm(vctrl, q->vcq, dw0, q->head, cid, status);
+}
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 9/9] nvme/pci: implement the mdev external queue allocation interface
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:41   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)


Note that currently the number of hw queues reserved for mdev,
has to be pre determined on module load.

(I used to allocate the queues dynamicaly on demand, but
recent changes to allocate polled/read queues made
this somewhat difficult, so I dropped this for now)

Signed-off-by: Maxim Levitsky <mlevitsk at redhat.com>
---
 drivers/nvme/host/pci.c | 376 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 369 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 806b551d3582..deb9e8de0fe8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -31,6 +31,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/sed-opal.h>
 #include <linux/pci-p2pdma.h>
+#include "../mdev/mdev.h"
 
 #include "trace.h"
 #include "nvme.h"
@@ -40,6 +41,7 @@
 
 #define SGES_PER_PAGE	(PAGE_SIZE / sizeof(struct nvme_sgl_desc))
 
+#define USE_SMALL_PRP_POOL(nprps) ((nprps) < (256 / 8))
 /*
  * These can be higher, but we need to ensure that any command doesn't
  * require an sg allocation that needs more than a page of data.
@@ -91,12 +93,24 @@ static int poll_queues = 0;
 module_param_cb(poll_queues, &queue_count_ops, &poll_queues, 0644);
 MODULE_PARM_DESC(poll_queues, "Number of queues to use for polled IO.");
 
+static int mdev_queues;
+#ifdef CONFIG_NVME_MDEV
+module_param_cb(mdev_queues, &queue_count_ops, &mdev_queues, 0644);
+MODULE_PARM_DESC(mdev_queues, "Number of queues to use for mediated VFIO");
+#endif
+
 struct nvme_dev;
 struct nvme_queue;
 
 static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown);
 static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode);
 
+#ifdef CONFIG_NVME_MDEV
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid);
+#else
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid) {}
+#endif
+
 /*
  * Represents an NVM Express device.  Each nvme_dev is a PCI function.
  */
@@ -111,6 +125,7 @@ struct nvme_dev {
 	unsigned online_queues;
 	unsigned max_qid;
 	unsigned io_queues[HCTX_MAX_TYPES];
+	unsigned int mdev_queues;
 	unsigned int num_vecs;
 	int q_depth;
 	u32 db_stride;
@@ -118,6 +133,7 @@ struct nvme_dev {
 	unsigned long bar_mapped_size;
 	struct work_struct remove_work;
 	struct mutex shutdown_lock;
+	struct mutex ext_dev_lock;
 	bool subsystem;
 	u64 cmb_size;
 	bool cmb_use_sqes;
@@ -178,6 +194,16 @@ static inline struct nvme_dev *to_nvme_dev(struct nvme_ctrl *ctrl)
 	return container_of(ctrl, struct nvme_dev, ctrl);
 }
 
+/* Simplified IO descriptor for MDEV use */
+struct nvme_ext_iod {
+	struct list_head link;
+	u32 user_tag;
+	int nprps;
+	struct nvme_ext_data_iter *saved_iter;
+	dma_addr_t first_prplist_dma;
+	__le64 *prpslists[NVME_MAX_SEGS];
+};
+
 /*
  * An NVM Express queue.  Each device has at least two (one for admin
  * commands and one for I/O commands).
@@ -203,14 +229,25 @@ struct nvme_queue {
 	u16 qid;
 	u8 cq_phase;
 	unsigned long flags;
+
 #define NVMEQ_ENABLED		0
 #define NVMEQ_SQ_CMB		1
 #define NVMEQ_DELETE_ERROR	2
+#define NVMEQ_EXTERNAL		4
+
 	u32 *dbbuf_sq_db;
 	u32 *dbbuf_cq_db;
 	u32 *dbbuf_sq_ei;
 	u32 *dbbuf_cq_ei;
 	struct completion delete_done;
+
+	/* queue passthrough for external use */
+	struct {
+		int inflight;
+		struct nvme_ext_iod *iods;
+		struct list_head free_iods;
+		struct list_head used_iods;
+	} ext;
 };
 
 /*
@@ -255,7 +292,7 @@ static inline void _nvme_check_size(void)
 
 static unsigned int max_io_queues(void)
 {
-	return num_possible_cpus() + write_queues + poll_queues;
+	return num_possible_cpus() + write_queues + poll_queues + mdev_queues;
 }
 
 static unsigned int max_queue_count(void)
@@ -1057,6 +1094,7 @@ static irqreturn_t nvme_irq(int irq, void *data)
 	 * the irq handler, even if that was on another CPU.
 	 */
 	rmb();
+
 	if (nvmeq->cq_head != nvmeq->last_cq_head)
 		ret = IRQ_HANDLED;
 	nvme_process_cq(nvmeq, &start, &end, -1);
@@ -1167,6 +1205,7 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
 	c.create_cq.cqid = cpu_to_le16(qid);
 	c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
 	c.create_cq.cq_flags = cpu_to_le16(flags);
+
 	if (vector != -1)
 		c.create_cq.irq_vector = cpu_to_le16(vector);
 	else
@@ -1551,7 +1590,11 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
 	memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth));
 	nvme_dbbuf_init(dev, nvmeq, qid);
 	dev->online_queues++;
+
 	wmb(); /* ensure the first interrupt sees the initialization */
+
+	if (test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+		nvme_ext_queue_reset(nvmeq->dev, qid);
 }
 
 static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
@@ -1757,7 +1800,7 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
 	}
 
 	max = min(dev->max_qid, dev->ctrl.queue_count - 1);
-	if (max != 1 && dev->io_queues[HCTX_TYPE_POLL]) {
+	if (max != 1) {
 		rw_queues = dev->io_queues[HCTX_TYPE_DEFAULT] +
 				dev->io_queues[HCTX_TYPE_READ];
 	} else {
@@ -2094,14 +2137,23 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
 	 * Poll queues don't need interrupts, but we need at least one IO
 	 * queue left over for non-polled IO.
 	 */
-	this_p_queues = poll_queues;
+	this_p_queues = poll_queues + mdev_queues;
 	if (this_p_queues >= nr_io_queues) {
 		this_p_queues = nr_io_queues - 1;
 		irq_queues = 1;
 	} else {
 		irq_queues = nr_io_queues - this_p_queues + 1;
 	}
+
+	if (mdev_queues > this_p_queues) {
+		mdev_queues = this_p_queues;
+		this_p_queues = 0;
+	} else {
+		this_p_queues -= mdev_queues;
+	}
+
 	dev->io_queues[HCTX_TYPE_POLL] = this_p_queues;
+	dev->mdev_queues = mdev_queues;
 
 	/*
 	 * For irq sets, we have to ask for minvec == maxvec. This passes
@@ -2208,7 +2260,8 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
 
 	dev->num_vecs = result;
 	result = max(result - 1, 1);
-	dev->max_qid = result + dev->io_queues[HCTX_TYPE_POLL];
+	dev->max_qid = result + dev->io_queues[HCTX_TYPE_POLL] +
+			dev->mdev_queues;
 
 	/*
 	 * Should investigate if there's a performance win from allocating
@@ -2233,10 +2286,11 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
 		nvme_suspend_io_queues(dev);
 		goto retry;
 	}
-	dev_info(dev->ctrl.device, "%d/%d/%d default/read/poll queues\n",
+	dev_info(dev->ctrl.device, "%d/%d/%d/%d default/read/poll/mdev queues\n",
 					dev->io_queues[HCTX_TYPE_DEFAULT],
 					dev->io_queues[HCTX_TYPE_READ],
-					dev->io_queues[HCTX_TYPE_POLL]);
+					dev->io_queues[HCTX_TYPE_POLL],
+					dev->mdev_queues);
 	return 0;
 }
 
@@ -2667,6 +2721,301 @@ static void nvme_remove_dead_ctrl_work(struct work_struct *work)
 	nvme_put_ctrl(&dev->ctrl);
 }
 
+#ifdef CONFIG_NVME_MDEV
+static void nvme_ext_free_iod(struct nvme_dev *dev, struct nvme_ext_iod *iod)
+{
+	int i = 0, max_prp, nprps = iod->nprps;
+	dma_addr_t dma = iod->first_prplist_dma;
+
+	if (iod->saved_iter) {
+		iod->saved_iter->release(iod->saved_iter);
+		iod->saved_iter = NULL;
+	}
+
+	if (--nprps < 2) {
+		goto out;
+	} else if (USE_SMALL_PRP_POOL(nprps)) {
+		dma_pool_free(dev->prp_small_pool, iod->prpslists[0], dma);
+		goto out;
+	}
+
+	max_prp = (dev->ctrl.page_size >> 3) - 1;
+	while (nprps > 0) {
+		if (i > 0) {
+			dma = iod->prpslists[i - 1][max_prp];
+			if (nprps == 1)
+				break;
+		}
+		dma_pool_free(dev->prp_page_pool, iod->prpslists[i++], dma);
+		nprps -= max_prp;
+	}
+out:
+	iod->nprps = -1;
+	iod->first_prplist_dma = 0;
+	iod->user_tag = 0xDEADDEAD;
+}
+
+static int nvme_ext_setup_iod(struct nvme_dev *dev, struct nvme_ext_iod *iod,
+			      struct nvme_common_command *cmd,
+			      struct nvme_ext_data_iter *iter)
+{
+	int ret, i, j;
+	__le64 *prp_list;
+	dma_addr_t prp_dma;
+	struct dma_pool *pool;
+	int max_prp = (dev->ctrl.page_size >> 3) - 1;
+
+	iod->saved_iter = iter && iter->release ? iter : NULL;
+	iod->nprps = iter ? iter->count : 0;
+	cmd->dptr.prp1 = 0;
+	cmd->dptr.prp2 = 0;
+	cmd->metadata = 0;
+
+	if (!iter)
+		return 0;
+
+	/* put first pointer*/
+	cmd->dptr.prp1 = cpu_to_le64(iter->host_iova);
+	if (iter->count == 1)
+		return 0;
+
+	ret = iter->next(iter);
+	if (ret)
+		goto error;
+
+	/* if only have one more pointer, put it to second data pointer*/
+	if (iter->count == 1) {
+		cmd->dptr.prp2 = cpu_to_le64(iter->host_iova);
+		return 0;
+	}
+
+	pool = USE_SMALL_PRP_POOL(iter->count) ?  dev->prp_small_pool :
+						  dev->prp_page_pool;
+
+	/* Allocate prp lists as needed and fill them */
+	for (i = 0 ; i < NVME_MAX_SEGS && iter->count ; i++) {
+		prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+		if (!prp_list) {
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		iod->prpslists[i++] = prp_list;
+
+		if (i == 1) {
+			iod->first_prplist_dma = prp_dma;
+			cmd->dptr.prp2 = cpu_to_le64(prp_dma);
+			j = 0;
+		} else {
+			prp_list[0] = iod->prpslists[i - 1][max_prp];
+			iod->prpslists[i - 1][max_prp] = prp_dma;
+			j = 1;
+		}
+
+		while (j <= max_prp && iter->count) {
+			prp_list[j++] = iter->host_iova;
+			ret = iter->next(iter);
+			if (ret)
+				goto error;
+		}
+	}
+
+	if (iter->count) {
+		ret = -ENOSPC;
+		goto error;
+	}
+	return 0;
+error:
+	iod->nprps -= iter->count;
+	nvme_ext_free_iod(dev, iod);
+	return ret;
+}
+
+static int nvme_ext_queues_available(struct nvme_ctrl *ctrl)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	unsigned int ret = 0, qid;
+	unsigned int first_mdev_q = dev->online_queues - dev->mdev_queues;
+
+	for (qid = first_mdev_q; qid < dev->online_queues; qid++) {
+		struct nvme_queue *nvmeq = &dev->queues[qid];
+
+		if (!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+			ret++;
+	}
+	return ret;
+}
+
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid)
+{
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	struct nvme_ext_iod *iod, *tmp;
+
+	list_for_each_entry_safe(iod, tmp, &nvmeq->ext.used_iods, link) {
+		if (iod->saved_iter && iod->saved_iter->release) {
+			iod->saved_iter->release(iod->saved_iter);
+			iod->saved_iter = NULL;
+			list_move(&iod->link, &nvmeq->ext.free_iods);
+		}
+	}
+
+	nvmeq->ext.inflight = 0;
+}
+
+static int nvme_ext_queue_alloc(struct nvme_ctrl *ctrl, u16 *ret_qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq;
+	int ret = 0, qid, i;
+	unsigned int first_mdev_q = dev->online_queues - dev->mdev_queues;
+
+	mutex_lock(&dev->ext_dev_lock);
+
+	/* find a polled queue to allocate */
+	for (qid = dev->online_queues - 1 ; qid >= first_mdev_q ; qid--) {
+		nvmeq = &dev->queues[qid];
+		if (!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+			break;
+	}
+
+	if (qid < first_mdev_q) {
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&nvmeq->ext.free_iods);
+	INIT_LIST_HEAD(&nvmeq->ext.used_iods);
+
+	nvmeq->ext.iods =
+		vzalloc_node(sizeof(struct nvme_ext_iod) * nvmeq->q_depth,
+			     dev_to_node(dev->dev));
+
+	if (!nvmeq->ext.iods) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0 ; i < nvmeq->q_depth ; i++)
+		list_add_tail(&nvmeq->ext.iods[i].link, &nvmeq->ext.free_iods);
+
+	set_bit(NVMEQ_EXTERNAL, &nvmeq->flags);
+	*ret_qid = qid;
+out:
+	mutex_unlock(&dev->ext_dev_lock);
+	return ret;
+}
+
+static void nvme_ext_queue_free(struct nvme_ctrl *ctrl, u16 qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq;
+
+	mutex_lock(&dev->ext_dev_lock);
+	nvmeq = &dev->queues[qid];
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return;
+
+	nvme_ext_queue_reset(dev, qid);
+
+	vfree(nvmeq->ext.iods);
+	nvmeq->ext.iods = NULL;
+	INIT_LIST_HEAD(&nvmeq->ext.free_iods);
+	INIT_LIST_HEAD(&nvmeq->ext.used_iods);
+
+	clear_bit(NVMEQ_EXTERNAL, &nvmeq->flags);
+	mutex_unlock(&dev->ext_dev_lock);
+}
+
+static int nvme_ext_queue_submit(struct nvme_ctrl *ctrl, u16 qid, u32 user_tag,
+				 struct nvme_command *command,
+				 struct nvme_ext_data_iter *iter)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	struct nvme_ext_iod *iod;
+	int ret;
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return -EINVAL;
+
+	if (list_empty(&nvmeq->ext.free_iods))
+		return -1;
+
+	iod = list_first_entry(&nvmeq->ext.free_iods,
+			       struct nvme_ext_iod, link);
+
+	list_move(&iod->link, &nvmeq->ext.used_iods);
+
+	command->common.command_id = cpu_to_le16(iod - nvmeq->ext.iods);
+	iod->user_tag = user_tag;
+
+	ret = nvme_ext_setup_iod(dev, iod, &command->common, iter);
+	if (ret) {
+		list_move(&iod->link, &nvmeq->ext.free_iods);
+		return ret;
+	}
+
+	nvmeq->ext.inflight++;
+	nvme_submit_cmd(nvmeq, command, true);
+	return 0;
+}
+
+static int nvme_ext_queue_poll(struct nvme_ctrl *ctrl, u16 qid,
+			       struct nvme_ext_cmd_result *results,
+			       unsigned int max_len)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	u16 old_head;
+	int i, j;
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return -EINVAL;
+
+	if (nvmeq->ext.inflight == 0)
+		return -1;
+
+	old_head = nvmeq->cq_head;
+
+	for (i = 0 ; nvme_cqe_pending(nvmeq) && i < max_len ; i++) {
+		u16 status = le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].status);
+		u16 tag = le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].command_id);
+
+		results[i].status = status >> 1;
+		results[i].tag = (u32)tag;
+		nvme_update_cq_head(nvmeq);
+	}
+
+	if (old_head != nvmeq->cq_head)
+		nvme_ring_cq_doorbell(nvmeq);
+
+	for (j = 0 ; j < i ; j++)  {
+		u16 tag = results[j].tag & 0xFFFF;
+		struct nvme_ext_iod *iod = &nvmeq->ext.iods[tag];
+
+		if (WARN_ON(tag >= nvmeq->q_depth || iod->nprps == -1))
+			continue;
+
+		results[j].tag = iod->user_tag;
+		nvme_ext_free_iod(dev, iod);
+		list_move(&iod->link, &nvmeq->ext.free_iods);
+		nvmeq->ext.inflight--;
+	}
+
+	WARN_ON(nvmeq->ext.inflight < 0);
+	return i;
+}
+
+static bool nvme_ext_queue_full(struct nvme_ctrl *ctrl, u16 qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+
+	return nvmeq->ext.inflight < nvmeq->q_depth - 1;
+}
+#endif
+
 static int nvme_pci_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
 {
 	*val = readl(to_nvme_dev(ctrl)->bar + off);
@@ -2696,13 +3045,25 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
 	.name			= "pcie",
 	.module			= THIS_MODULE,
 	.flags			= NVME_F_METADATA_SUPPORTED |
-				  NVME_F_PCI_P2PDMA,
+				  NVME_F_PCI_P2PDMA |
+				  NVME_F_MDEV_SUPPORTED |
+				  NVME_F_MDEV_DMA_SUPPORTED,
+
 	.reg_read32		= nvme_pci_reg_read32,
 	.reg_write32		= nvme_pci_reg_write32,
 	.reg_read64		= nvme_pci_reg_read64,
 	.free_ctrl		= nvme_pci_free_ctrl,
 	.submit_async_event	= nvme_pci_submit_async_event,
 	.get_address		= nvme_pci_get_address,
+
+#ifdef CONFIG_NVME_MDEV
+	.ext_queues_available	= nvme_ext_queues_available,
+	.ext_queue_alloc	= nvme_ext_queue_alloc,
+	.ext_queue_free		= nvme_ext_queue_free,
+	.ext_queue_submit	= nvme_ext_queue_submit,
+	.ext_queue_poll		= nvme_ext_queue_poll,
+	.ext_queue_full		= nvme_ext_queue_full,
+#endif
 };
 
 static int nvme_dev_map(struct nvme_dev *dev)
@@ -2791,6 +3152,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
 	INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
 	mutex_init(&dev->shutdown_lock);
+	mutex_init(&dev->ext_dev_lock);
 
 	result = nvme_setup_prp_pools(dev);
 	if (result)
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 9/9] nvme/pci: implement the mdev external queue allocation interface
@ 2019-03-19 14:41   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:41 UTC (permalink / raw)
  To: linux-nvme
  Cc: Maxim Levitsky, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John 

Note that currently the number of hw queues reserved for mdev,
has to be pre determined on module load.

(I used to allocate the queues dynamicaly on demand, but
recent changes to allocate polled/read queues made
this somewhat difficult, so I dropped this for now)

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 drivers/nvme/host/pci.c | 376 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 369 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 806b551d3582..deb9e8de0fe8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -31,6 +31,7 @@
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/sed-opal.h>
 #include <linux/pci-p2pdma.h>
+#include "../mdev/mdev.h"
 
 #include "trace.h"
 #include "nvme.h"
@@ -40,6 +41,7 @@
 
 #define SGES_PER_PAGE	(PAGE_SIZE / sizeof(struct nvme_sgl_desc))
 
+#define USE_SMALL_PRP_POOL(nprps) ((nprps) < (256 / 8))
 /*
  * These can be higher, but we need to ensure that any command doesn't
  * require an sg allocation that needs more than a page of data.
@@ -91,12 +93,24 @@ static int poll_queues = 0;
 module_param_cb(poll_queues, &queue_count_ops, &poll_queues, 0644);
 MODULE_PARM_DESC(poll_queues, "Number of queues to use for polled IO.");
 
+static int mdev_queues;
+#ifdef CONFIG_NVME_MDEV
+module_param_cb(mdev_queues, &queue_count_ops, &mdev_queues, 0644);
+MODULE_PARM_DESC(mdev_queues, "Number of queues to use for mediated VFIO");
+#endif
+
 struct nvme_dev;
 struct nvme_queue;
 
 static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown);
 static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode);
 
+#ifdef CONFIG_NVME_MDEV
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid);
+#else
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid) {}
+#endif
+
 /*
  * Represents an NVM Express device.  Each nvme_dev is a PCI function.
  */
@@ -111,6 +125,7 @@ struct nvme_dev {
 	unsigned online_queues;
 	unsigned max_qid;
 	unsigned io_queues[HCTX_MAX_TYPES];
+	unsigned int mdev_queues;
 	unsigned int num_vecs;
 	int q_depth;
 	u32 db_stride;
@@ -118,6 +133,7 @@ struct nvme_dev {
 	unsigned long bar_mapped_size;
 	struct work_struct remove_work;
 	struct mutex shutdown_lock;
+	struct mutex ext_dev_lock;
 	bool subsystem;
 	u64 cmb_size;
 	bool cmb_use_sqes;
@@ -178,6 +194,16 @@ static inline struct nvme_dev *to_nvme_dev(struct nvme_ctrl *ctrl)
 	return container_of(ctrl, struct nvme_dev, ctrl);
 }
 
+/* Simplified IO descriptor for MDEV use */
+struct nvme_ext_iod {
+	struct list_head link;
+	u32 user_tag;
+	int nprps;
+	struct nvme_ext_data_iter *saved_iter;
+	dma_addr_t first_prplist_dma;
+	__le64 *prpslists[NVME_MAX_SEGS];
+};
+
 /*
  * An NVM Express queue.  Each device has at least two (one for admin
  * commands and one for I/O commands).
@@ -203,14 +229,25 @@ struct nvme_queue {
 	u16 qid;
 	u8 cq_phase;
 	unsigned long flags;
+
 #define NVMEQ_ENABLED		0
 #define NVMEQ_SQ_CMB		1
 #define NVMEQ_DELETE_ERROR	2
+#define NVMEQ_EXTERNAL		4
+
 	u32 *dbbuf_sq_db;
 	u32 *dbbuf_cq_db;
 	u32 *dbbuf_sq_ei;
 	u32 *dbbuf_cq_ei;
 	struct completion delete_done;
+
+	/* queue passthrough for external use */
+	struct {
+		int inflight;
+		struct nvme_ext_iod *iods;
+		struct list_head free_iods;
+		struct list_head used_iods;
+	} ext;
 };
 
 /*
@@ -255,7 +292,7 @@ static inline void _nvme_check_size(void)
 
 static unsigned int max_io_queues(void)
 {
-	return num_possible_cpus() + write_queues + poll_queues;
+	return num_possible_cpus() + write_queues + poll_queues + mdev_queues;
 }
 
 static unsigned int max_queue_count(void)
@@ -1057,6 +1094,7 @@ static irqreturn_t nvme_irq(int irq, void *data)
 	 * the irq handler, even if that was on another CPU.
 	 */
 	rmb();
+
 	if (nvmeq->cq_head != nvmeq->last_cq_head)
 		ret = IRQ_HANDLED;
 	nvme_process_cq(nvmeq, &start, &end, -1);
@@ -1167,6 +1205,7 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
 	c.create_cq.cqid = cpu_to_le16(qid);
 	c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
 	c.create_cq.cq_flags = cpu_to_le16(flags);
+
 	if (vector != -1)
 		c.create_cq.irq_vector = cpu_to_le16(vector);
 	else
@@ -1551,7 +1590,11 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
 	memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth));
 	nvme_dbbuf_init(dev, nvmeq, qid);
 	dev->online_queues++;
+
 	wmb(); /* ensure the first interrupt sees the initialization */
+
+	if (test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+		nvme_ext_queue_reset(nvmeq->dev, qid);
 }
 
 static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
@@ -1757,7 +1800,7 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
 	}
 
 	max = min(dev->max_qid, dev->ctrl.queue_count - 1);
-	if (max != 1 && dev->io_queues[HCTX_TYPE_POLL]) {
+	if (max != 1) {
 		rw_queues = dev->io_queues[HCTX_TYPE_DEFAULT] +
 				dev->io_queues[HCTX_TYPE_READ];
 	} else {
@@ -2094,14 +2137,23 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
 	 * Poll queues don't need interrupts, but we need at least one IO
 	 * queue left over for non-polled IO.
 	 */
-	this_p_queues = poll_queues;
+	this_p_queues = poll_queues + mdev_queues;
 	if (this_p_queues >= nr_io_queues) {
 		this_p_queues = nr_io_queues - 1;
 		irq_queues = 1;
 	} else {
 		irq_queues = nr_io_queues - this_p_queues + 1;
 	}
+
+	if (mdev_queues > this_p_queues) {
+		mdev_queues = this_p_queues;
+		this_p_queues = 0;
+	} else {
+		this_p_queues -= mdev_queues;
+	}
+
 	dev->io_queues[HCTX_TYPE_POLL] = this_p_queues;
+	dev->mdev_queues = mdev_queues;
 
 	/*
 	 * For irq sets, we have to ask for minvec == maxvec. This passes
@@ -2208,7 +2260,8 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
 
 	dev->num_vecs = result;
 	result = max(result - 1, 1);
-	dev->max_qid = result + dev->io_queues[HCTX_TYPE_POLL];
+	dev->max_qid = result + dev->io_queues[HCTX_TYPE_POLL] +
+			dev->mdev_queues;
 
 	/*
 	 * Should investigate if there's a performance win from allocating
@@ -2233,10 +2286,11 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
 		nvme_suspend_io_queues(dev);
 		goto retry;
 	}
-	dev_info(dev->ctrl.device, "%d/%d/%d default/read/poll queues\n",
+	dev_info(dev->ctrl.device, "%d/%d/%d/%d default/read/poll/mdev queues\n",
 					dev->io_queues[HCTX_TYPE_DEFAULT],
 					dev->io_queues[HCTX_TYPE_READ],
-					dev->io_queues[HCTX_TYPE_POLL]);
+					dev->io_queues[HCTX_TYPE_POLL],
+					dev->mdev_queues);
 	return 0;
 }
 
@@ -2667,6 +2721,301 @@ static void nvme_remove_dead_ctrl_work(struct work_struct *work)
 	nvme_put_ctrl(&dev->ctrl);
 }
 
+#ifdef CONFIG_NVME_MDEV
+static void nvme_ext_free_iod(struct nvme_dev *dev, struct nvme_ext_iod *iod)
+{
+	int i = 0, max_prp, nprps = iod->nprps;
+	dma_addr_t dma = iod->first_prplist_dma;
+
+	if (iod->saved_iter) {
+		iod->saved_iter->release(iod->saved_iter);
+		iod->saved_iter = NULL;
+	}
+
+	if (--nprps < 2) {
+		goto out;
+	} else if (USE_SMALL_PRP_POOL(nprps)) {
+		dma_pool_free(dev->prp_small_pool, iod->prpslists[0], dma);
+		goto out;
+	}
+
+	max_prp = (dev->ctrl.page_size >> 3) - 1;
+	while (nprps > 0) {
+		if (i > 0) {
+			dma = iod->prpslists[i - 1][max_prp];
+			if (nprps == 1)
+				break;
+		}
+		dma_pool_free(dev->prp_page_pool, iod->prpslists[i++], dma);
+		nprps -= max_prp;
+	}
+out:
+	iod->nprps = -1;
+	iod->first_prplist_dma = 0;
+	iod->user_tag = 0xDEADDEAD;
+}
+
+static int nvme_ext_setup_iod(struct nvme_dev *dev, struct nvme_ext_iod *iod,
+			      struct nvme_common_command *cmd,
+			      struct nvme_ext_data_iter *iter)
+{
+	int ret, i, j;
+	__le64 *prp_list;
+	dma_addr_t prp_dma;
+	struct dma_pool *pool;
+	int max_prp = (dev->ctrl.page_size >> 3) - 1;
+
+	iod->saved_iter = iter && iter->release ? iter : NULL;
+	iod->nprps = iter ? iter->count : 0;
+	cmd->dptr.prp1 = 0;
+	cmd->dptr.prp2 = 0;
+	cmd->metadata = 0;
+
+	if (!iter)
+		return 0;
+
+	/* put first pointer*/
+	cmd->dptr.prp1 = cpu_to_le64(iter->host_iova);
+	if (iter->count == 1)
+		return 0;
+
+	ret = iter->next(iter);
+	if (ret)
+		goto error;
+
+	/* if only have one more pointer, put it to second data pointer*/
+	if (iter->count == 1) {
+		cmd->dptr.prp2 = cpu_to_le64(iter->host_iova);
+		return 0;
+	}
+
+	pool = USE_SMALL_PRP_POOL(iter->count) ?  dev->prp_small_pool :
+						  dev->prp_page_pool;
+
+	/* Allocate prp lists as needed and fill them */
+	for (i = 0 ; i < NVME_MAX_SEGS && iter->count ; i++) {
+		prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
+		if (!prp_list) {
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		iod->prpslists[i++] = prp_list;
+
+		if (i == 1) {
+			iod->first_prplist_dma = prp_dma;
+			cmd->dptr.prp2 = cpu_to_le64(prp_dma);
+			j = 0;
+		} else {
+			prp_list[0] = iod->prpslists[i - 1][max_prp];
+			iod->prpslists[i - 1][max_prp] = prp_dma;
+			j = 1;
+		}
+
+		while (j <= max_prp && iter->count) {
+			prp_list[j++] = iter->host_iova;
+			ret = iter->next(iter);
+			if (ret)
+				goto error;
+		}
+	}
+
+	if (iter->count) {
+		ret = -ENOSPC;
+		goto error;
+	}
+	return 0;
+error:
+	iod->nprps -= iter->count;
+	nvme_ext_free_iod(dev, iod);
+	return ret;
+}
+
+static int nvme_ext_queues_available(struct nvme_ctrl *ctrl)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	unsigned int ret = 0, qid;
+	unsigned int first_mdev_q = dev->online_queues - dev->mdev_queues;
+
+	for (qid = first_mdev_q; qid < dev->online_queues; qid++) {
+		struct nvme_queue *nvmeq = &dev->queues[qid];
+
+		if (!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+			ret++;
+	}
+	return ret;
+}
+
+static void nvme_ext_queue_reset(struct nvme_dev *dev, u16 qid)
+{
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	struct nvme_ext_iod *iod, *tmp;
+
+	list_for_each_entry_safe(iod, tmp, &nvmeq->ext.used_iods, link) {
+		if (iod->saved_iter && iod->saved_iter->release) {
+			iod->saved_iter->release(iod->saved_iter);
+			iod->saved_iter = NULL;
+			list_move(&iod->link, &nvmeq->ext.free_iods);
+		}
+	}
+
+	nvmeq->ext.inflight = 0;
+}
+
+static int nvme_ext_queue_alloc(struct nvme_ctrl *ctrl, u16 *ret_qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq;
+	int ret = 0, qid, i;
+	unsigned int first_mdev_q = dev->online_queues - dev->mdev_queues;
+
+	mutex_lock(&dev->ext_dev_lock);
+
+	/* find a polled queue to allocate */
+	for (qid = dev->online_queues - 1 ; qid >= first_mdev_q ; qid--) {
+		nvmeq = &dev->queues[qid];
+		if (!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags))
+			break;
+	}
+
+	if (qid < first_mdev_q) {
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&nvmeq->ext.free_iods);
+	INIT_LIST_HEAD(&nvmeq->ext.used_iods);
+
+	nvmeq->ext.iods =
+		vzalloc_node(sizeof(struct nvme_ext_iod) * nvmeq->q_depth,
+			     dev_to_node(dev->dev));
+
+	if (!nvmeq->ext.iods) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0 ; i < nvmeq->q_depth ; i++)
+		list_add_tail(&nvmeq->ext.iods[i].link, &nvmeq->ext.free_iods);
+
+	set_bit(NVMEQ_EXTERNAL, &nvmeq->flags);
+	*ret_qid = qid;
+out:
+	mutex_unlock(&dev->ext_dev_lock);
+	return ret;
+}
+
+static void nvme_ext_queue_free(struct nvme_ctrl *ctrl, u16 qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq;
+
+	mutex_lock(&dev->ext_dev_lock);
+	nvmeq = &dev->queues[qid];
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return;
+
+	nvme_ext_queue_reset(dev, qid);
+
+	vfree(nvmeq->ext.iods);
+	nvmeq->ext.iods = NULL;
+	INIT_LIST_HEAD(&nvmeq->ext.free_iods);
+	INIT_LIST_HEAD(&nvmeq->ext.used_iods);
+
+	clear_bit(NVMEQ_EXTERNAL, &nvmeq->flags);
+	mutex_unlock(&dev->ext_dev_lock);
+}
+
+static int nvme_ext_queue_submit(struct nvme_ctrl *ctrl, u16 qid, u32 user_tag,
+				 struct nvme_command *command,
+				 struct nvme_ext_data_iter *iter)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	struct nvme_ext_iod *iod;
+	int ret;
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return -EINVAL;
+
+	if (list_empty(&nvmeq->ext.free_iods))
+		return -1;
+
+	iod = list_first_entry(&nvmeq->ext.free_iods,
+			       struct nvme_ext_iod, link);
+
+	list_move(&iod->link, &nvmeq->ext.used_iods);
+
+	command->common.command_id = cpu_to_le16(iod - nvmeq->ext.iods);
+	iod->user_tag = user_tag;
+
+	ret = nvme_ext_setup_iod(dev, iod, &command->common, iter);
+	if (ret) {
+		list_move(&iod->link, &nvmeq->ext.free_iods);
+		return ret;
+	}
+
+	nvmeq->ext.inflight++;
+	nvme_submit_cmd(nvmeq, command, true);
+	return 0;
+}
+
+static int nvme_ext_queue_poll(struct nvme_ctrl *ctrl, u16 qid,
+			       struct nvme_ext_cmd_result *results,
+			       unsigned int max_len)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+	u16 old_head;
+	int i, j;
+
+	if (WARN_ON(!test_bit(NVMEQ_EXTERNAL, &nvmeq->flags)))
+		return -EINVAL;
+
+	if (nvmeq->ext.inflight == 0)
+		return -1;
+
+	old_head = nvmeq->cq_head;
+
+	for (i = 0 ; nvme_cqe_pending(nvmeq) && i < max_len ; i++) {
+		u16 status = le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].status);
+		u16 tag = le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].command_id);
+
+		results[i].status = status >> 1;
+		results[i].tag = (u32)tag;
+		nvme_update_cq_head(nvmeq);
+	}
+
+	if (old_head != nvmeq->cq_head)
+		nvme_ring_cq_doorbell(nvmeq);
+
+	for (j = 0 ; j < i ; j++)  {
+		u16 tag = results[j].tag & 0xFFFF;
+		struct nvme_ext_iod *iod = &nvmeq->ext.iods[tag];
+
+		if (WARN_ON(tag >= nvmeq->q_depth || iod->nprps == -1))
+			continue;
+
+		results[j].tag = iod->user_tag;
+		nvme_ext_free_iod(dev, iod);
+		list_move(&iod->link, &nvmeq->ext.free_iods);
+		nvmeq->ext.inflight--;
+	}
+
+	WARN_ON(nvmeq->ext.inflight < 0);
+	return i;
+}
+
+static bool nvme_ext_queue_full(struct nvme_ctrl *ctrl, u16 qid)
+{
+	struct nvme_dev *dev = to_nvme_dev(ctrl);
+	struct nvme_queue *nvmeq = &dev->queues[qid];
+
+	return nvmeq->ext.inflight < nvmeq->q_depth - 1;
+}
+#endif
+
 static int nvme_pci_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
 {
 	*val = readl(to_nvme_dev(ctrl)->bar + off);
@@ -2696,13 +3045,25 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
 	.name			= "pcie",
 	.module			= THIS_MODULE,
 	.flags			= NVME_F_METADATA_SUPPORTED |
-				  NVME_F_PCI_P2PDMA,
+				  NVME_F_PCI_P2PDMA |
+				  NVME_F_MDEV_SUPPORTED |
+				  NVME_F_MDEV_DMA_SUPPORTED,
+
 	.reg_read32		= nvme_pci_reg_read32,
 	.reg_write32		= nvme_pci_reg_write32,
 	.reg_read64		= nvme_pci_reg_read64,
 	.free_ctrl		= nvme_pci_free_ctrl,
 	.submit_async_event	= nvme_pci_submit_async_event,
 	.get_address		= nvme_pci_get_address,
+
+#ifdef CONFIG_NVME_MDEV
+	.ext_queues_available	= nvme_ext_queues_available,
+	.ext_queue_alloc	= nvme_ext_queue_alloc,
+	.ext_queue_free		= nvme_ext_queue_free,
+	.ext_queue_submit	= nvme_ext_queue_submit,
+	.ext_queue_poll		= nvme_ext_queue_poll,
+	.ext_queue_full		= nvme_ext_queue_full,
+#endif
 };
 
 static int nvme_dev_map(struct nvme_dev *dev)
@@ -2791,6 +3152,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
 	INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
 	mutex_init(&dev->shutdown_lock);
+	mutex_init(&dev->ext_dev_lock);
 
 	result = nvme_setup_prp_pools(dev);
 	if (result)
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 14:58   ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:58 UTC (permalink / raw)


Oops, I placed the subject in the wrong place.

Best regards,
	Maxim Levitsky

On Tue, 2019-03-19@16:41 +0200, Maxim Levitsky wrote:
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of
> doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.
> 
> The idea behind this driver is based on paper you can find at
> https://www.usenix.org/conference/atc18/presentation/peng,
> 
> Although note that I stared the development prior to reading this paper, 
> independently.
> 
> In addition to that implementation is not based on code used in the paper as 
> I wasn't being able at that time to make the source available to me.
> 
> ***Key points about the implementation:***
> 
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising
> results.
> 
> * Guest sees a standard NVME device - this allows to run guest with 
> unmodified drivers, for example windows guests.
> 
> * The NVMe device is shared between host and guest.
> That means that even a single namespace can be split between host 
> and guest based on different partitions.
> 
> * Simple configuration
> 
> *** Performance ***
> 
> Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> and both latency and throughput is very similar to SPDK.
> 
> Soon I will test this on a better server and nvme device and provide
> more formal performance numbers.
> 
> Latency numbers:
> ~80ms - spdk with fio plugin on the host.
> ~84ms - nvme driver on the host
> ~87ms - mdev-nvme + nvme driver in the guest
> 
> Throughput was following similar pattern as well.
> 
> * Configuration example
>   $ modprobe nvme mdev_queues=4
>   $ modprobe nvme-mdev
> 
>   $ UUID=$(uuidgen)
>   $ DEVICE='device pci address'
>   $ echo $UUID > /sys/bus/pci/devices/$DEVICE/mdev_supported_types/nvme-
> 2Q_V1/create
>   $ echo n1p3 > /sys/bus/mdev/devices/$UUID/namespaces/add_namespace #attach
> host namespace 1 parition 3
>   $ echo 11 > /sys/bus/mdev/devices/$UUID/settings/iothread_cpu #pin the io
> thread to cpu 11
> 
>   Afterward boot qemu with
>   -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID
>   
>   Zero configuration on the guest.
>   
> *** FAQ ***
> 
> * Why to make this in the kernel? Why this is better that SPDK
> 
>   -> Reuse the existing nvme kernel driver in the host. No new drivers in the
> guest.
>   
>   -> Share the NVMe device between host and guest. 
>      Even in fully virtualized configurations,
>      some partitions of nvme device could be used by guests as block devices 
>      while others passed through with nvme-mdev to achieve balance between
>      all features of full IO stack emulation and performance.
>   
>   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
>      can send interrupts to the guest directly without a context 
>      switch that can be expensive due to meltdown mitigation.
> 
>   -> Is able to utilize interrupts to get reasonable performance. 
>      This is only implemented
>      as a proof of concept and not included in the patches, 
>      but interrupt driven mode shows reasonable performance
>      
>   -> This is a framework that later can be used to support NVMe devices 
>      with more of the IO virtualization built-in 
>      (IOMMU with PASID support coupled with device that supports it)
> 
> * Why to attach directly to nvme-pci driver and not use block layer IO
>   -> The direct attachment allows for better performance, but I will
>      check the possibility of using block IO, especially for fabrics drivers.
>   
> *** Implementation notes ***
> 
> *  All guest memory is mapped into the physical nvme device 
>    but not 1:1 as vfio-pci would do this.
>    This allows very efficient DMA.
>    To support this, patch 2 adds ability for a mdev device to listen on 
>    guest's memory map events. 
>    Any such memory is immediately pinned and then DMA mapped.
>    (Support for fabric drivers where this is not possible exits too,
>     in which case the fabric driver will do its own DMA mapping)
> 
> *  nvme core driver is modified to announce the appearance 
>    and disappearance of nvme controllers and namespaces,
>    to which the nvme-mdev driver is subscribed.
>  
> *  nvme-pci driver is modified to expose raw interface of attaching to 
>    and sending/polling the IO queues.
>    This allows the mdev driver very efficiently to submit/poll for the IO.
>    By default one host queue is used per each mediated device.
>    (support for other fabric based host drivers is planned)
> 
> * The nvme-mdev doesn't assume presence of KVM, thus any VFIO user, including
>   SPDK, a qemu running with tccg, ... can use this virtual device.
> 
> *** Testing ***
> 
> The device was tested with stock QEMU 3.0 on the host,
> with host was using 5.0 kernel with nvme-mdev added and the following
> hardware:
>  * QEMU nvme virtual device (with nested guest)
>  * Intel DC P3700 on Xeon E5-2620 v2 server
>  * Samsung SM981 (in a Thunderbolt enclosure, with my laptop)
>  * Lenovo NVME device found in my laptop
> 
> The guest was tested with kernel 4.16, 4.18, 4.20 and
> the same custom complied kernel 5.0
> Windows 10 guest was tested too with both Microsoft's inbox driver and
> open source community NVME driver
> (https://lists.openfabrics.org/pipermail/nvmewin/2016-December/001420.html)
> 
> Testing was mostly done on x86_64, but 32 bit host/guest combination
> was lightly tested too.
> 
> In addition to that, the virtual device was tested with nested guest,
> by passing the virtual device to it,
> using pci passthrough, qemu userspace nvme driver, and spdk
> 
> 
> PS: I used to contribute to the kernel as a hobby using the
>     maximlevitsky at gmail.com address
> 
> Maxim Levitsky (9):
>   vfio/mdev: add .request callback
>   nvme/core: add some more values from the spec
>   nvme/core: add NVME_CTRL_SUSPENDED controller state
>   nvme/pci: use the NVME_CTRL_SUSPENDED state
>   nvme/pci: add known admin effects to augument admin effects log page
>   nvme/pci: init shadow doorbell after each reset
>   nvme/core: add mdev interfaces
>   nvme/core: add nvme-mdev core driver
>   nvme/pci: implement the mdev external queue allocation interface
> 
>  MAINTAINERS                   |   5 +
>  drivers/nvme/Kconfig          |   1 +
>  drivers/nvme/Makefile         |   1 +
>  drivers/nvme/host/core.c      | 149 +++++-
>  drivers/nvme/host/nvme.h      |  55 ++-
>  drivers/nvme/host/pci.c       | 385 ++++++++++++++-
>  drivers/nvme/mdev/Kconfig     |  16 +
>  drivers/nvme/mdev/Makefile    |   5 +
>  drivers/nvme/mdev/adm.c       | 873 ++++++++++++++++++++++++++++++++++
>  drivers/nvme/mdev/events.c    | 142 ++++++
>  drivers/nvme/mdev/host.c      | 491 +++++++++++++++++++
>  drivers/nvme/mdev/instance.c  | 802 +++++++++++++++++++++++++++++++
>  drivers/nvme/mdev/io.c        | 563 ++++++++++++++++++++++
>  drivers/nvme/mdev/irq.c       | 264 ++++++++++
>  drivers/nvme/mdev/mdev.h      |  56 +++
>  drivers/nvme/mdev/mmio.c      | 591 +++++++++++++++++++++++
>  drivers/nvme/mdev/pci.c       | 247 ++++++++++
>  drivers/nvme/mdev/priv.h      | 700 +++++++++++++++++++++++++++
>  drivers/nvme/mdev/udata.c     | 390 +++++++++++++++
>  drivers/nvme/mdev/vcq.c       | 207 ++++++++
>  drivers/nvme/mdev/vctrl.c     | 514 ++++++++++++++++++++
>  drivers/nvme/mdev/viommu.c    | 322 +++++++++++++
>  drivers/nvme/mdev/vns.c       | 356 ++++++++++++++
>  drivers/nvme/mdev/vsq.c       | 178 +++++++
>  drivers/vfio/mdev/vfio_mdev.c |  11 +
>  include/linux/mdev.h          |   4 +
>  include/linux/nvme.h          |  88 +++-
>  27 files changed, 7375 insertions(+), 41 deletions(-)
>  create mode 100644 drivers/nvme/mdev/Kconfig
>  create mode 100644 drivers/nvme/mdev/Makefile
>  create mode 100644 drivers/nvme/mdev/adm.c
>  create mode 100644 drivers/nvme/mdev/events.c
>  create mode 100644 drivers/nvme/mdev/host.c
>  create mode 100644 drivers/nvme/mdev/instance.c
>  create mode 100644 drivers/nvme/mdev/io.c
>  create mode 100644 drivers/nvme/mdev/irq.c
>  create mode 100644 drivers/nvme/mdev/mdev.h
>  create mode 100644 drivers/nvme/mdev/mmio.c
>  create mode 100644 drivers/nvme/mdev/pci.c
>  create mode 100644 drivers/nvme/mdev/priv.h
>  create mode 100644 drivers/nvme/mdev/udata.c
>  create mode 100644 drivers/nvme/mdev/vcq.c
>  create mode 100644 drivers/nvme/mdev/vctrl.c
>  create mode 100644 drivers/nvme/mdev/viommu.c
>  create mode 100644 drivers/nvme/mdev/vns.c
>  create mode 100644 drivers/nvme/mdev/vsq.c
> 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-19 14:58   ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-19 14:58 UTC (permalink / raw)
  To: linux-nvme
  Cc: linux-kernel, kvm, Jens Axboe, Alex Williamson, Keith Busch,
	Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney, Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan, John Ferlan

Oops, I placed the subject in the wrong place.

Best regards,
	Maxim Levitsky

On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of
> doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.
> 
> The idea behind this driver is based on paper you can find at
> https://www.usenix.org/conference/atc18/presentation/peng,
> 
> Although note that I stared the development prior to reading this paper, 
> independently.
> 
> In addition to that implementation is not based on code used in the paper as 
> I wasn't being able at that time to make the source available to me.
> 
> ***Key points about the implementation:***
> 
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising
> results.
> 
> * Guest sees a standard NVME device - this allows to run guest with 
> unmodified drivers, for example windows guests.
> 
> * The NVMe device is shared between host and guest.
> That means that even a single namespace can be split between host 
> and guest based on different partitions.
> 
> * Simple configuration
> 
> *** Performance ***
> 
> Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> and both latency and throughput is very similar to SPDK.
> 
> Soon I will test this on a better server and nvme device and provide
> more formal performance numbers.
> 
> Latency numbers:
> ~80ms - spdk with fio plugin on the host.
> ~84ms - nvme driver on the host
> ~87ms - mdev-nvme + nvme driver in the guest
> 
> Throughput was following similar pattern as well.
> 
> * Configuration example
>   $ modprobe nvme mdev_queues=4
>   $ modprobe nvme-mdev
> 
>   $ UUID=$(uuidgen)
>   $ DEVICE='device pci address'
>   $ echo $UUID > /sys/bus/pci/devices/$DEVICE/mdev_supported_types/nvme-
> 2Q_V1/create
>   $ echo n1p3 > /sys/bus/mdev/devices/$UUID/namespaces/add_namespace #attach
> host namespace 1 parition 3
>   $ echo 11 > /sys/bus/mdev/devices/$UUID/settings/iothread_cpu #pin the io
> thread to cpu 11
> 
>   Afterward boot qemu with
>   -device vfio-pci,sysfsdev=/sys/bus/mdev/devices/$UUID
>   
>   Zero configuration on the guest.
>   
> *** FAQ ***
> 
> * Why to make this in the kernel? Why this is better that SPDK
> 
>   -> Reuse the existing nvme kernel driver in the host. No new drivers in the
> guest.
>   
>   -> Share the NVMe device between host and guest. 
>      Even in fully virtualized configurations,
>      some partitions of nvme device could be used by guests as block devices 
>      while others passed through with nvme-mdev to achieve balance between
>      all features of full IO stack emulation and performance.
>   
>   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
>      can send interrupts to the guest directly without a context 
>      switch that can be expensive due to meltdown mitigation.
> 
>   -> Is able to utilize interrupts to get reasonable performance. 
>      This is only implemented
>      as a proof of concept and not included in the patches, 
>      but interrupt driven mode shows reasonable performance
>      
>   -> This is a framework that later can be used to support NVMe devices 
>      with more of the IO virtualization built-in 
>      (IOMMU with PASID support coupled with device that supports it)
> 
> * Why to attach directly to nvme-pci driver and not use block layer IO
>   -> The direct attachment allows for better performance, but I will
>      check the possibility of using block IO, especially for fabrics drivers.
>   
> *** Implementation notes ***
> 
> *  All guest memory is mapped into the physical nvme device 
>    but not 1:1 as vfio-pci would do this.
>    This allows very efficient DMA.
>    To support this, patch 2 adds ability for a mdev device to listen on 
>    guest's memory map events. 
>    Any such memory is immediately pinned and then DMA mapped.
>    (Support for fabric drivers where this is not possible exits too,
>     in which case the fabric driver will do its own DMA mapping)
> 
> *  nvme core driver is modified to announce the appearance 
>    and disappearance of nvme controllers and namespaces,
>    to which the nvme-mdev driver is subscribed.
>  
> *  nvme-pci driver is modified to expose raw interface of attaching to 
>    and sending/polling the IO queues.
>    This allows the mdev driver very efficiently to submit/poll for the IO.
>    By default one host queue is used per each mediated device.
>    (support for other fabric based host drivers is planned)
> 
> * The nvme-mdev doesn't assume presence of KVM, thus any VFIO user, including
>   SPDK, a qemu running with tccg, ... can use this virtual device.
> 
> *** Testing ***
> 
> The device was tested with stock QEMU 3.0 on the host,
> with host was using 5.0 kernel with nvme-mdev added and the following
> hardware:
>  * QEMU nvme virtual device (with nested guest)
>  * Intel DC P3700 on Xeon E5-2620 v2 server
>  * Samsung SM981 (in a Thunderbolt enclosure, with my laptop)
>  * Lenovo NVME device found in my laptop
> 
> The guest was tested with kernel 4.16, 4.18, 4.20 and
> the same custom complied kernel 5.0
> Windows 10 guest was tested too with both Microsoft's inbox driver and
> open source community NVME driver
> (https://lists.openfabrics.org/pipermail/nvmewin/2016-December/001420.html)
> 
> Testing was mostly done on x86_64, but 32 bit host/guest combination
> was lightly tested too.
> 
> In addition to that, the virtual device was tested with nested guest,
> by passing the virtual device to it,
> using pci passthrough, qemu userspace nvme driver, and spdk
> 
> 
> PS: I used to contribute to the kernel as a hobby using the
>     maximlevitsky@gmail.com address
> 
> Maxim Levitsky (9):
>   vfio/mdev: add .request callback
>   nvme/core: add some more values from the spec
>   nvme/core: add NVME_CTRL_SUSPENDED controller state
>   nvme/pci: use the NVME_CTRL_SUSPENDED state
>   nvme/pci: add known admin effects to augument admin effects log page
>   nvme/pci: init shadow doorbell after each reset
>   nvme/core: add mdev interfaces
>   nvme/core: add nvme-mdev core driver
>   nvme/pci: implement the mdev external queue allocation interface
> 
>  MAINTAINERS                   |   5 +
>  drivers/nvme/Kconfig          |   1 +
>  drivers/nvme/Makefile         |   1 +
>  drivers/nvme/host/core.c      | 149 +++++-
>  drivers/nvme/host/nvme.h      |  55 ++-
>  drivers/nvme/host/pci.c       | 385 ++++++++++++++-
>  drivers/nvme/mdev/Kconfig     |  16 +
>  drivers/nvme/mdev/Makefile    |   5 +
>  drivers/nvme/mdev/adm.c       | 873 ++++++++++++++++++++++++++++++++++
>  drivers/nvme/mdev/events.c    | 142 ++++++
>  drivers/nvme/mdev/host.c      | 491 +++++++++++++++++++
>  drivers/nvme/mdev/instance.c  | 802 +++++++++++++++++++++++++++++++
>  drivers/nvme/mdev/io.c        | 563 ++++++++++++++++++++++
>  drivers/nvme/mdev/irq.c       | 264 ++++++++++
>  drivers/nvme/mdev/mdev.h      |  56 +++
>  drivers/nvme/mdev/mmio.c      | 591 +++++++++++++++++++++++
>  drivers/nvme/mdev/pci.c       | 247 ++++++++++
>  drivers/nvme/mdev/priv.h      | 700 +++++++++++++++++++++++++++
>  drivers/nvme/mdev/udata.c     | 390 +++++++++++++++
>  drivers/nvme/mdev/vcq.c       | 207 ++++++++
>  drivers/nvme/mdev/vctrl.c     | 514 ++++++++++++++++++++
>  drivers/nvme/mdev/viommu.c    | 322 +++++++++++++
>  drivers/nvme/mdev/vns.c       | 356 ++++++++++++++
>  drivers/nvme/mdev/vsq.c       | 178 +++++++
>  drivers/vfio/mdev/vfio_mdev.c |  11 +
>  include/linux/mdev.h          |   4 +
>  include/linux/nvme.h          |  88 +++-
>  27 files changed, 7375 insertions(+), 41 deletions(-)
>  create mode 100644 drivers/nvme/mdev/Kconfig
>  create mode 100644 drivers/nvme/mdev/Makefile
>  create mode 100644 drivers/nvme/mdev/adm.c
>  create mode 100644 drivers/nvme/mdev/events.c
>  create mode 100644 drivers/nvme/mdev/host.c
>  create mode 100644 drivers/nvme/mdev/instance.c
>  create mode 100644 drivers/nvme/mdev/io.c
>  create mode 100644 drivers/nvme/mdev/irq.c
>  create mode 100644 drivers/nvme/mdev/mdev.h
>  create mode 100644 drivers/nvme/mdev/mmio.c
>  create mode 100644 drivers/nvme/mdev/pci.c
>  create mode 100644 drivers/nvme/mdev/priv.h
>  create mode 100644 drivers/nvme/mdev/udata.c
>  create mode 100644 drivers/nvme/mdev/vcq.c
>  create mode 100644 drivers/nvme/mdev/vctrl.c
>  create mode 100644 drivers/nvme/mdev/viommu.c
>  create mode 100644 drivers/nvme/mdev/vns.c
>  create mode 100644 drivers/nvme/mdev/vsq.c
> 

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-19 15:22   ` Keith Busch
  -1 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-19 15:22 UTC (permalink / raw)


On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
>   -> Share the NVMe device between host and guest. 
>      Even in fully virtualized configurations,
>      some partitions of nvme device could be used by guests as block devices 
>      while others passed through with nvme-mdev to achieve balance between
>      all features of full IO stack emulation and performance.
>   
>   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
>      can send interrupts to the guest directly without a context 
>      switch that can be expensive due to meltdown mitigation.
> 
>   -> Is able to utilize interrupts to get reasonable performance. 
>      This is only implemented
>      as a proof of concept and not included in the patches, 
>      but interrupt driven mode shows reasonable performance
>      
>   -> This is a framework that later can be used to support NVMe devices 
>      with more of the IO virtualization built-in 
>      (IOMMU with PASID support coupled with device that supports it)

Would be very interested to see the PASID support. You wouldn't even
need to mediate the IO doorbells or translations if assigning entire
namespaces, and should be much faster than the shadow doorbells.

I think you should send 6/9 "nvme/pci: init shadow doorbell after each
reset" separately for immediate inclusion.

I like the idea in principle, but it will take me a little time to get
through reviewing your implementation. I would have guessed we could
have leveraged something from the existing nvme/target for the mediating
controller register access and admin commands. Maybe even start with
implementing an nvme passthrough namespace target type (we currently
have block and file).

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-19 15:22   ` Keith Busch
  0 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-19 15:22 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfe

On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
>   -> Share the NVMe device between host and guest. 
>      Even in fully virtualized configurations,
>      some partitions of nvme device could be used by guests as block devices 
>      while others passed through with nvme-mdev to achieve balance between
>      all features of full IO stack emulation and performance.
>   
>   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
>      can send interrupts to the guest directly without a context 
>      switch that can be expensive due to meltdown mitigation.
> 
>   -> Is able to utilize interrupts to get reasonable performance. 
>      This is only implemented
>      as a proof of concept and not included in the patches, 
>      but interrupt driven mode shows reasonable performance
>      
>   -> This is a framework that later can be used to support NVMe devices 
>      with more of the IO virtualization built-in 
>      (IOMMU with PASID support coupled with device that supports it)

Would be very interested to see the PASID support. You wouldn't even
need to mediate the IO doorbells or translations if assigning entire
namespaces, and should be much faster than the shadow doorbells.

I think you should send 6/9 "nvme/pci: init shadow doorbell after each
reset" separately for immediate inclusion.

I like the idea in principle, but it will take me a little time to get
through reviewing your implementation. I would have guessed we could
have leveraged something from the existing nvme/target for the mediating
controller register access and admin commands. Maybe even start with
implementing an nvme passthrough namespace target type (we currently
have block and file).

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 15:22   ` Keith Busch
@ 2019-03-19 23:49     ` Chaitanya Kulkarni
  -1 siblings, 0 replies; 409+ messages in thread
From: Chaitanya Kulkarni @ 2019-03-19 23:49 UTC (permalink / raw)


Hi Keith,
On 03/19/2019 08:21 AM, Keith Busch wrote:
> On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
>>    -> Share the NVMe device between host and guest.
>>       Even in fully virtualized configurations,
>>       some partitions of nvme device could be used by guests as block devices
>>       while others passed through with nvme-mdev to achieve balance between
>>       all features of full IO stack emulation and performance.
>>
>>    -> NVME-MDEV is a bit faster due to the fact that in-kernel driver
>>       can send interrupts to the guest directly without a context
>>       switch that can be expensive due to meltdown mitigation.
>>
>>    -> Is able to utilize interrupts to get reasonable performance.
>>       This is only implemented
>>       as a proof of concept and not included in the patches,
>>       but interrupt driven mode shows reasonable performance
>>
>>    -> This is a framework that later can be used to support NVMe devices
>>       with more of the IO virtualization built-in
>>       (IOMMU with PASID support coupled with device that supports it)
>
> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.
>
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
>
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).

I have the code for the NVMeOf target passthru-ctrl, I think we can use 
that as it is if you are looking for the passthru for NVMeOF.

I'll post patch-series based on the latest code base soon.
>
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme
>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-19 23:49     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 409+ messages in thread
From: Chaitanya Kulkarni @ 2019-03-19 23:49 UTC (permalink / raw)
  To: Keith Busch, Maxim Levitsky
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm@vger.kernel.org,
	Wolfram Sang, Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre,
	linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org,
	David S . Miller, Jens Axboe, Alex Williamson, Kirti Wankhede,
	Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney 

Hi Keith,
On 03/19/2019 08:21 AM, Keith Busch wrote:
> On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
>>    -> Share the NVMe device between host and guest.
>>       Even in fully virtualized configurations,
>>       some partitions of nvme device could be used by guests as block devices
>>       while others passed through with nvme-mdev to achieve balance between
>>       all features of full IO stack emulation and performance.
>>
>>    -> NVME-MDEV is a bit faster due to the fact that in-kernel driver
>>       can send interrupts to the guest directly without a context
>>       switch that can be expensive due to meltdown mitigation.
>>
>>    -> Is able to utilize interrupts to get reasonable performance.
>>       This is only implemented
>>       as a proof of concept and not included in the patches,
>>       but interrupt driven mode shows reasonable performance
>>
>>    -> This is a framework that later can be used to support NVMe devices
>>       with more of the IO virtualization built-in
>>       (IOMMU with PASID support coupled with device that supports it)
>
> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.
>
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
>
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).

I have the code for the NVMeOf target passthru-ctrl, I think we can use 
that as it is if you are looking for the passthru for NVMeOF.

I'll post patch-series based on the latest code base soon.
>
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme
>


^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 4/9] nvme/pci: use the NVME_CTRL_SUSPENDED state
  2019-03-19 14:41   ` Maxim Levitsky
@ 2019-03-20  2:54     ` Fam Zheng
  -1 siblings, 0 replies; 409+ messages in thread
From: Fam Zheng @ 2019-03-20  2:54 UTC (permalink / raw)


On Tue, 03/19 16:41, Maxim Levitsky wrote:
> When enteriing low power state, the nvme

Typo: "entering".

> driver will now inform the core with the NVME_CTRL_SUSPENDED state
> which will allow mdev driver to act on this information

[snip]

Fam

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 4/9] nvme/pci: use the NVME_CTRL_SUSPENDED state
@ 2019-03-20  2:54     ` Fam Zheng
  0 siblings, 0 replies; 409+ messages in thread
From: Fam Zheng @ 2019-03-20  2:54 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Amnon Ilan, John Ferlan

On Tue, 03/19 16:41, Maxim Levitsky wrote:
> When enteriing low power state, the nvme

Typo: "entering".

> driver will now inform the core with the NVME_CTRL_SUSPENDED state
> which will allow mdev driver to act on this information

[snip]

Fam

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-20 11:03   ` Felipe Franciosi
  -1 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-20 11:03 UTC (permalink / raw)



> On Mar 19, 2019,@2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> 
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.

Hey Maxim!

I'm really excited to see this series, as it aligns to some extent with what we discussed in last year's KVM Forum VFIO BoF.

There's no arguing that we need a better story to efficiently virtualise NVMe devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best attempt at that. However, I seem to recall there was some pushback from qemu-devel in the sense that they would rather see investment in virtio-blk. I'm not sure what's the latest on that work and what are the next steps.

The pushback drove the discussion towards pursuing an mdev approach, which is why I'm excited to see your patches.

What I'm thinking is that passing through namespaces or partitions is very restrictive. It leaves no room to implement more elaborate virtualisation stacks like replicating data across multiple devices (local or remote), storage migration, software-managed thin provisioning, encryption, deduplication, compression, etc. In summary, anything that requires software intervention in the datapath. (Worth noting: vhost-user-nvme allows all of that to be easily done in SPDK's bdev layer.)

These complicated stacks should probably not be implemented in the kernel, though. So I'm wondering whether we could talk about mechanisms to allow efficient and performant userspace datapath intervention  in your approach or pursue a mechanism to completely offload the device emulation to userspace (and align with what SPDK has to offer).

Thoughts welcome!
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-20 11:03   ` Felipe Franciosi
  0 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-20 11:03 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org, Jens Axboe, Alex Williamson, Keith Busch,
	Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney, Paolo Bonzini,
	Liang Cunming, Liu Changpeng <changpeng.


> On Mar 19, 2019, at 2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> 
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.

Hey Maxim!

I'm really excited to see this series, as it aligns to some extent with what we discussed in last year's KVM Forum VFIO BoF.

There's no arguing that we need a better story to efficiently virtualise NVMe devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best attempt at that. However, I seem to recall there was some pushback from qemu-devel in the sense that they would rather see investment in virtio-blk. I'm not sure what's the latest on that work and what are the next steps.

The pushback drove the discussion towards pursuing an mdev approach, which is why I'm excited to see your patches.

What I'm thinking is that passing through namespaces or partitions is very restrictive. It leaves no room to implement more elaborate virtualisation stacks like replicating data across multiple devices (local or remote), storage migration, software-managed thin provisioning, encryption, deduplication, compression, etc. In summary, anything that requires software intervention in the datapath. (Worth noting: vhost-user-nvme allows all of that to be easily done in SPDK's bdev layer.)

These complicated stacks should probably not be implemented in the kernel, though. So I'm wondering whether we could talk about mechanisms to allow efficient and performant userspace datapath intervention  in your approach or pursue a mechanism to completely offload the device emulation to userspace (and align with what SPDK has to offer).

Thoughts welcome!
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 7/9] nvme/core: add mdev interfaces
  2019-03-19 14:41   ` Maxim Levitsky
@ 2019-03-20 11:46     ` Stefan Hajnoczi
  -1 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-20 11:46 UTC (permalink / raw)


On Tue, Mar 19, 2019@04:41:14PM +0200, Maxim Levitsky wrote:
> +int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
> +{
> +	struct nvme_ctrl *ctrl;
> +
> +	if (mdev_driver_interface)
> +		return -EEXIST;
> +
> +	mdev_driver_interface = driver_ops;

Can mdev_driver_interface be accessed from two CPUs at the same time?
mdev_driver_interface isn't protected by the mutex.  The state_changed
functions below also don't protect mdev_driver_interface.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-nvme/attachments/20190320/bc363d0c/attachment.sig>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 7/9] nvme/core: add mdev interfaces
@ 2019-03-20 11:46     ` Stefan Hajnoczi
  0 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-20 11:46 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfe

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

On Tue, Mar 19, 2019 at 04:41:14PM +0200, Maxim Levitsky wrote:
> +int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
> +{
> +	struct nvme_ctrl *ctrl;
> +
> +	if (mdev_driver_interface)
> +		return -EEXIST;
> +
> +	mdev_driver_interface = driver_ops;

Can mdev_driver_interface be accessed from two CPUs at the same time?
mdev_driver_interface isn't protected by the mutex.  The state_changed
functions below also don't protect mdev_driver_interface.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 7/9] nvme/core: add mdev interfaces
  2019-03-20 11:46     ` Stefan Hajnoczi
@ 2019-03-20 12:50       ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 12:50 UTC (permalink / raw)


On Wed, 2019-03-20@11:46 +0000, Stefan Hajnoczi wrote:
> On Tue, Mar 19, 2019@04:41:14PM +0200, Maxim Levitsky wrote:
> > +int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
> > +{
> > +	struct nvme_ctrl *ctrl;
> > +
> > +	if (mdev_driver_interface)
> > +		return -EEXIST;
> > +
> > +	mdev_driver_interface = driver_ops;
> 
> Can mdev_driver_interface be accessed from two CPUs at the same time?
> mdev_driver_interface isn't protected by the mutex.  The state_changed
> functions below also don't protect mdev_driver_interface.

It can be for sure.
However the only time it is updated is when the mdev core module load/unload
routines.

On module load the interface flips from NULL to a pointer to inside of the
module, so this should be safe, and when mdev module unloads, its reference
counter is 0, and all the callers first try to increase it and fail, they don't
call using this interface.

I might still be wrong with this reasoning though.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 7/9] nvme/core: add mdev interfaces
@ 2019-03-20 12:50       ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 12:50 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney, Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfer

On Wed, 2019-03-20 at 11:46 +0000, Stefan Hajnoczi wrote:
> On Tue, Mar 19, 2019 at 04:41:14PM +0200, Maxim Levitsky wrote:
> > +int nvme_core_register_mdev_driver(struct nvme_mdev_driver *driver_ops)
> > +{
> > +	struct nvme_ctrl *ctrl;
> > +
> > +	if (mdev_driver_interface)
> > +		return -EEXIST;
> > +
> > +	mdev_driver_interface = driver_ops;
> 
> Can mdev_driver_interface be accessed from two CPUs at the same time?
> mdev_driver_interface isn't protected by the mutex.  The state_changed
> functions below also don't protect mdev_driver_interface.

It can be for sure.
However the only time it is updated is when the mdev core module load/unload
routines.

On module load the interface flips from NULL to a pointer to inside of the
module, so this should be safe, and when mdev module unloads, its reference
counter is 0, and all the callers first try to increase it and fail, they don't
call using this interface.

I might still be wrong with this reasoning though.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-20 15:08   ` Bart Van Assche
  -1 siblings, 0 replies; 409+ messages in thread
From: Bart Van Assche @ 2019-03-20 15:08 UTC (permalink / raw)


On Tue, 2019-03-19@16:41 +0200, Maxim Levitsky wrote:
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising results.

Which cgroup will the CPU cycles used for polling be attributed to? Can the
polling code be moved into user space such that it becomes easy to identify
which process needs most CPU cycles for polling and such that the polling
CPU cycles are attributed to the proper cgroup?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-20 15:08   ` Bart Van Assche
  0 siblings, 0 replies; 409+ messages in thread
From: Bart Van Assche @ 2019-03-20 15:08 UTC (permalink / raw)
  To: Maxim Levitsky, linux-nvme
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, David S . Miller,
	Greg Kroah-Hartman, Liang Cunming, Wolfram Sang, linux-kernel,
	Kirti Wankhede, Jens Axboe, Alex Williamson, John Ferlan,
	Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney, Amnon Ilan, Christoph Hellwig, Nicolas Ferre

On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising results.

Which cgroup will the CPU cycles used for polling be attributed to? Can the
polling code be moved into user space such that it becomes easy to identify
which process needs most CPU cycles for polling and such that the polling
CPU cycles are attributed to the proper cgroup?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-20 15:28   ` Bart Van Assche
  -1 siblings, 0 replies; 409+ messages in thread
From: Bart Van Assche @ 2019-03-20 15:28 UTC (permalink / raw)


On Tue, 2019-03-19@16:41 +0200, Maxim Levitsky wrote:
> *  All guest memory is mapped into the physical nvme device 
>    but not 1:1 as vfio-pci would do this.
>    This allows very efficient DMA.
>    To support this, patch 2 adds ability for a mdev device to listen on 
>    guest's memory map events. 
>    Any such memory is immediately pinned and then DMA mapped.
>    (Support for fabric drivers where this is not possible exits too,
>     in which case the fabric driver will do its own DMA mapping)

Does this mean that all guest memory is pinned all the time? If so, are you
sure that's acceptable?

Additionally, what is the performance overhead of the IOMMU notifier added
by patch 8/9? How often was that notifier called per second in your tests
and how much time was spent per call in the notifier callbacks?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-20 15:28   ` Bart Van Assche
  0 siblings, 0 replies; 409+ messages in thread
From: Bart Van Assche @ 2019-03-20 15:28 UTC (permalink / raw)
  To: Maxim Levitsky, linux-nvme
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, David S . Miller,
	Greg Kroah-Hartman, Liang Cunming, Wolfram Sang, linux-kernel,
	Kirti Wankhede, Jens Axboe, Alex Williamson, John Ferlan,
	Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney, Amnon Ilan, Christoph Hellwig, Nicolas Ferre

On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:
> *  All guest memory is mapped into the physical nvme device 
>    but not 1:1 as vfio-pci would do this.
>    This allows very efficient DMA.
>    To support this, patch 2 adds ability for a mdev device to listen on 
>    guest's memory map events. 
>    Any such memory is immediately pinned and then DMA mapped.
>    (Support for fabric drivers where this is not possible exits too,
>     in which case the fabric driver will do its own DMA mapping)

Does this mean that all guest memory is pinned all the time? If so, are you
sure that's acceptable?

Additionally, what is the performance overhead of the IOMMU notifier added
by patch 8/9? How often was that notifier called per second in your tests
and how much time was spent per call in the notifier callbacks?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 15:22   ` Keith Busch
@ 2019-03-20 16:30     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:30 UTC (permalink / raw)


On Tue, 2019-03-19@09:22 -0600, Keith Busch wrote:
> On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> >   -> Share the NVMe device between host and guest. 
> >      Even in fully virtualized configurations,
> >      some partitions of nvme device could be used by guests as block
> > devices 
> >      while others passed through with nvme-mdev to achieve balance between
> >      all features of full IO stack emulation and performance.
> >   
> >   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
> >      can send interrupts to the guest directly without a context 
> >      switch that can be expensive due to meltdown mitigation.
> > 
> >   -> Is able to utilize interrupts to get reasonable performance. 
> >      This is only implemented
> >      as a proof of concept and not included in the patches, 
> >      but interrupt driven mode shows reasonable performance
> >      
> >   -> This is a framework that later can be used to support NVMe devices 
> >      with more of the IO virtualization built-in 
> >      (IOMMU with PASID support coupled with device that supports it)
> 

> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.

I fully agree with that.
Note that to enable PASID support two things have to happen in this vendor.

1. Mature support for IOMMU with PASID support. On Intel side I know that they
only have a spec released and currently the kernel bits to support it are
placed.
I still don't know when a product actually supporting this spec is going to be
released. For other vendors (ARM/AMD/) I haven't done yet a research on state of
PASID based IOMMU support on their platforms.

2. NVMe spec has to be extended to support PASID. At minimum, we need an ability
to assign an PASID to a sq/cq queue pair and ability to relocate the doorbells,
such as each guest would get its own (hardware backed) MMIO page with its own
doorbells. Plus of course the hardware vendors have to embrace the spec. I guess
these two things will happen in collaborative manner.


> 
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
I'll do this soon. 

Also '5/9 nvme/pci: add known admin effects to augment admin effects log page'
can be considered for immediate inclusion as well, as it works around a flaw
in the NVMe controller badly done admin side effects page with no side effects
(pun intended) for spec compliant controllers (I think so). 

This can be fixed with a quirk if you prefer though.

> 
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).

I fully agree with you on that I could have used some of the nvme/target code,
and I am planning to do so eventually.

For that I would need to make my driver, to be one of the target drivers, and I
would need to add another target back end, like you said to allow my target
driver to talk directly to the nvme hardware bypassing the block layer.

Or instead I can use the block backend, 
(but note that currently the block back-end doesn't support polling which is
critical for the performance).

Switch to the target code might though have some (probably minor) performance
impact, as it would probably lengthen the critical code path a bit (I might need
for instance to translate the PRP lists I am getting from the virtual controller
to a scattergather list and back).

This is why I did this the way I did, but now knowing that probably I can afford
to loose a bit of performance, I can look at doing that.

Best regards,
Thanks in advance for the review,
	Maxim Levitsky

PS:

For reference currently the IO path looks more or less like that:

My IO thread notices a doorbell write, reads a command from a submission queue,
translates it (without even looking at the data pointer) and sends it to the
nvme pci driver together with pointer to data iterator'.

The nvme pci driver calls the data iterator N times, which makes the iterator
translate and fetch the DMA addresses where the data is already mapped on the
its pci nvme device (the mdev driver maps all the guest memory to the nvme pci
device).
The nvme pci driver uses these addresses it receives, to create a prp list,
which it puts into the data pointer.

The nvme pci driver also allocates an free command id, from a list, puts it into
the command ID and sends the command to the real hardware.

Later the IO thread calls to the nvme pci driver to poll the queue. When
completions arrive, the nvme pci driver returns them back to the IO thread.

> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-20 16:30     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:30 UTC (permalink / raw)
  To: Keith Busch
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, Wolfram Sang,
	Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre, linux-kernel,
	linux-nvme, David S . Miller, Jens Axboe, Alex Williamson,
	Kirti Wankhede, Mauro Carvalho Chehab, Paolo Bonzini,
	Liu Changpeng, Paul E . McKenney, Amnon Ilan, Christoph Hellwig,
	John Ferlan

On Tue, 2019-03-19 at 09:22 -0600, Keith Busch wrote:
> On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> >   -> Share the NVMe device between host and guest. 
> >      Even in fully virtualized configurations,
> >      some partitions of nvme device could be used by guests as block
> > devices 
> >      while others passed through with nvme-mdev to achieve balance between
> >      all features of full IO stack emulation and performance.
> >   
> >   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
> >      can send interrupts to the guest directly without a context 
> >      switch that can be expensive due to meltdown mitigation.
> > 
> >   -> Is able to utilize interrupts to get reasonable performance. 
> >      This is only implemented
> >      as a proof of concept and not included in the patches, 
> >      but interrupt driven mode shows reasonable performance
> >      
> >   -> This is a framework that later can be used to support NVMe devices 
> >      with more of the IO virtualization built-in 
> >      (IOMMU with PASID support coupled with device that supports it)
> 

> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.

I fully agree with that.
Note that to enable PASID support two things have to happen in this vendor.

1. Mature support for IOMMU with PASID support. On Intel side I know that they
only have a spec released and currently the kernel bits to support it are
placed.
I still don't know when a product actually supporting this spec is going to be
released. For other vendors (ARM/AMD/) I haven't done yet a research on state of
PASID based IOMMU support on their platforms.

2. NVMe spec has to be extended to support PASID. At minimum, we need an ability
to assign an PASID to a sq/cq queue pair and ability to relocate the doorbells,
such as each guest would get its own (hardware backed) MMIO page with its own
doorbells. Plus of course the hardware vendors have to embrace the spec. I guess
these two things will happen in collaborative manner.


> 
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
I'll do this soon. 

Also '5/9 nvme/pci: add known admin effects to augment admin effects log page'
can be considered for immediate inclusion as well, as it works around a flaw
in the NVMe controller badly done admin side effects page with no side effects
(pun intended) for spec compliant controllers (I think so). 

This can be fixed with a quirk if you prefer though.

> 
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).

I fully agree with you on that I could have used some of the nvme/target code,
and I am planning to do so eventually.

For that I would need to make my driver, to be one of the target drivers, and I
would need to add another target back end, like you said to allow my target
driver to talk directly to the nvme hardware bypassing the block layer.

Or instead I can use the block backend, 
(but note that currently the block back-end doesn't support polling which is
critical for the performance).

Switch to the target code might though have some (probably minor) performance
impact, as it would probably lengthen the critical code path a bit (I might need
for instance to translate the PRP lists I am getting from the virtual controller
to a scattergather list and back).

This is why I did this the way I did, but now knowing that probably I can afford
to loose a bit of performance, I can look at doing that.

Best regards,
Thanks in advance for the review,
	Maxim Levitsky

PS:

For reference currently the IO path looks more or less like that:

My IO thread notices a doorbell write, reads a command from a submission queue,
translates it (without even looking at the data pointer) and sends it to the
nvme pci driver together with pointer to data iterator'.

The nvme pci driver calls the data iterator N times, which makes the iterator
translate and fetch the DMA addresses where the data is already mapped on the
its pci nvme device (the mdev driver maps all the guest memory to the nvme pci
device).
The nvme pci driver uses these addresses it receives, to create a prp list,
which it puts into the data pointer.

The nvme pci driver also allocates an free command id, from a list, puts it into
the command ID and sends the command to the real hardware.

Later the IO thread calls to the nvme pci driver to poll the queue. When
completions arrive, the nvme pci driver returns them back to the IO thread.

> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-20 15:28   ` Bart Van Assche
@ 2019-03-20 16:42     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:42 UTC (permalink / raw)


On Wed, 2019-03-20@08:28 -0700, Bart Van Assche wrote:
> On Tue, 2019-03-19@16:41 +0200, Maxim Levitsky wrote:
> > *  All guest memory is mapped into the physical nvme device 
> >    but not 1:1 as vfio-pci would do this.
> >    This allows very efficient DMA.
> >    To support this, patch 2 adds ability for a mdev device to listen on 
> >    guest's memory map events. 
> >    Any such memory is immediately pinned and then DMA mapped.
> >    (Support for fabric drivers where this is not possible exits too,
> >     in which case the fabric driver will do its own DMA mapping)
> 
> Does this mean that all guest memory is pinned all the time? If so, are you
> sure that's acceptable?
I think so. The VFIO pci passthrough also pins all the guest memory.
SPDK also does this (pins and dma maps) all the guest memory.

I agree that this is not an ideal solution but this is a fastest and simplest
solution possible.

> 
> Additionally, what is the performance overhead of the IOMMU notifier added
> by patch 8/9? How often was that notifier called per second in your tests
> and how much time was spent per call in the notifier callbacks?

To be honest I haven't optimized my IOMMU notifier at all, so when it is called,
it stops the IO thread, does its work and then restarts it which is very slow.

Fortunelly it is not called at all during normal operation as VFIO dma map/unmap
events are really rare and happen only on guest boot.

The same is even true for nested guests, as nested guest startup causes a wave
of map unmap events while shadow IOMMU updates, but then it just uses these
mapping without changing them.

The only case when performance is really bad is when you boot a guest with
iommu=on intel_iommu=on and then use the nvme driver there. In this case, the
driver in the guest does itself IOMMU maps/unmaps (on the virtual IOMMU) and for
each such event my VFIO map/unmap callback is called.

This can be optimized though to be much better using also some kind of queued
invalidation in my driver. iommu=pt meanwhile in the guest solves that issue.

Best regards,
	Maxim Levitsky

> 
> Thanks,
> 
> Bart.
> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-20 16:42     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:42 UTC (permalink / raw)
  To: Bart Van Assche, linux-nvme
  Cc: Fam Zheng, Jens Axboe, Alex Williamson, Sagi Grimberg, kvm,
	Wolfram Sang, Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre,
	linux-kernel, Liu Changpeng, Keith Busch, Kirti Wankhede,
	Christoph Hellwig, Paolo Bonzini, Mauro Carvalho Chehab,
	John Ferlan, Paul E . McKenney, Amnon Ilan, David S . Miller

On Wed, 2019-03-20 at 08:28 -0700, Bart Van Assche wrote:
> On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:
> > *  All guest memory is mapped into the physical nvme device 
> >    but not 1:1 as vfio-pci would do this.
> >    This allows very efficient DMA.
> >    To support this, patch 2 adds ability for a mdev device to listen on 
> >    guest's memory map events. 
> >    Any such memory is immediately pinned and then DMA mapped.
> >    (Support for fabric drivers where this is not possible exits too,
> >     in which case the fabric driver will do its own DMA mapping)
> 
> Does this mean that all guest memory is pinned all the time? If so, are you
> sure that's acceptable?
I think so. The VFIO pci passthrough also pins all the guest memory.
SPDK also does this (pins and dma maps) all the guest memory.

I agree that this is not an ideal solution but this is a fastest and simplest
solution possible.

> 
> Additionally, what is the performance overhead of the IOMMU notifier added
> by patch 8/9? How often was that notifier called per second in your tests
> and how much time was spent per call in the notifier callbacks?

To be honest I haven't optimized my IOMMU notifier at all, so when it is called,
it stops the IO thread, does its work and then restarts it which is very slow.

Fortunelly it is not called at all during normal operation as VFIO dma map/unmap
events are really rare and happen only on guest boot.

The same is even true for nested guests, as nested guest startup causes a wave
of map unmap events while shadow IOMMU updates, but then it just uses these
mapping without changing them.

The only case when performance is really bad is when you boot a guest with
iommu=on intel_iommu=on and then use the nvme driver there. In this case, the
driver in the guest does itself IOMMU maps/unmaps (on the virtual IOMMU) and for
each such event my VFIO map/unmap callback is called.

This can be optimized though to be much better using also some kind of queued
invalidation in my driver. iommu=pt meanwhile in the guest solves that issue.

Best regards,
	Maxim Levitsky

> 
> Thanks,
> 
> Bart.
> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 23:49     ` Chaitanya Kulkarni
@ 2019-03-20 16:44       ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:44 UTC (permalink / raw)


On Tue, 2019-03-19@23:49 +0000, Chaitanya Kulkarni wrote:
> Hi Keith,
> On 03/19/2019 08:21 AM, Keith Busch wrote:
> > On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> > >    -> Share the NVMe device between host and guest.
> > >       Even in fully virtualized configurations,
> > >       some partitions of nvme device could be used by guests as block
> > > devices
> > >       while others passed through with nvme-mdev to achieve balance
> > > between
> > >       all features of full IO stack emulation and performance.
> > > 
> > >    -> NVME-MDEV is a bit faster due to the fact that in-kernel driver
> > >       can send interrupts to the guest directly without a context
> > >       switch that can be expensive due to meltdown mitigation.
> > > 
> > >    -> Is able to utilize interrupts to get reasonable performance.
> > >       This is only implemented
> > >       as a proof of concept and not included in the patches,
> > >       but interrupt driven mode shows reasonable performance
> > > 
> > >    -> This is a framework that later can be used to support NVMe devices
> > >       with more of the IO virtualization built-in
> > >       (IOMMU with PASID support coupled with device that supports it)
> > 
> > Would be very interested to see the PASID support. You wouldn't even
> > need to mediate the IO doorbells or translations if assigning entire
> > namespaces, and should be much faster than the shadow doorbells.
> > 
> > I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> > reset" separately for immediate inclusion.
> > 
> > I like the idea in principle, but it will take me a little time to get
> > through reviewing your implementation. I would have guessed we could
> > have leveraged something from the existing nvme/target for the mediating
> > controller register access and admin commands. Maybe even start with
> > implementing an nvme passthrough namespace target type (we currently
> > have block and file).
> 
> I have the code for the NVMeOf target passthru-ctrl, I think we can use 
> that as it is if you are looking for the passthru for NVMeOF.
> 
> I'll post patch-series based on the latest code base soon.

I am very intersing in this code. 
Could you explain how your NVMeOF target passthrough works? 
Which components of the NVME stack does it involve?

Best regards,
	Maxim Levitsky

> > 
> > _______________________________________________
> > Linux-nvme mailing list
> > Linux-nvme at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-nvme
> > 
> 
> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-20 16:44       ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:44 UTC (permalink / raw)
  To: Chaitanya Kulkarni, Keith Busch
  Cc: Fam Zheng, Jens Axboe, Sagi Grimberg, kvm@vger.kernel.org,
	Wolfram Sang, Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre,
	linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Keith Busch, Alex Williamson, Christoph Hellwig, Kirti Wankhede,
	Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney

On Tue, 2019-03-19 at 23:49 +0000, Chaitanya Kulkarni wrote:
> Hi Keith,
> On 03/19/2019 08:21 AM, Keith Busch wrote:
> > On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> > >    -> Share the NVMe device between host and guest.
> > >       Even in fully virtualized configurations,
> > >       some partitions of nvme device could be used by guests as block
> > > devices
> > >       while others passed through with nvme-mdev to achieve balance
> > > between
> > >       all features of full IO stack emulation and performance.
> > > 
> > >    -> NVME-MDEV is a bit faster due to the fact that in-kernel driver
> > >       can send interrupts to the guest directly without a context
> > >       switch that can be expensive due to meltdown mitigation.
> > > 
> > >    -> Is able to utilize interrupts to get reasonable performance.
> > >       This is only implemented
> > >       as a proof of concept and not included in the patches,
> > >       but interrupt driven mode shows reasonable performance
> > > 
> > >    -> This is a framework that later can be used to support NVMe devices
> > >       with more of the IO virtualization built-in
> > >       (IOMMU with PASID support coupled with device that supports it)
> > 
> > Would be very interested to see the PASID support. You wouldn't even
> > need to mediate the IO doorbells or translations if assigning entire
> > namespaces, and should be much faster than the shadow doorbells.
> > 
> > I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> > reset" separately for immediate inclusion.
> > 
> > I like the idea in principle, but it will take me a little time to get
> > through reviewing your implementation. I would have guessed we could
> > have leveraged something from the existing nvme/target for the mediating
> > controller register access and admin commands. Maybe even start with
> > implementing an nvme passthrough namespace target type (we currently
> > have block and file).
> 
> I have the code for the NVMeOf target passthru-ctrl, I think we can use 
> that as it is if you are looking for the passthru for NVMeOF.
> 
> I'll post patch-series based on the latest code base soon.

I am very intersing in this code. 
Could you explain how your NVMeOF target passthrough works? 
Which components of the NVME stack does it involve?

Best regards,
	Maxim Levitsky

> > 
> > _______________________________________________
> > Linux-nvme mailing list
> > Linux-nvme@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-nvme
> > 
> 
> 
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-20 15:08   ` Bart Van Assche
@ 2019-03-20 16:48     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:48 UTC (permalink / raw)


On Wed, 2019-03-20@08:08 -0700, Bart Van Assche wrote:
> On Tue, 2019-03-19@16:41 +0200, Maxim Levitsky wrote:
> > * Polling kernel thread is used. The polling is stopped after a 
> > predefined timeout (1/2 sec by default).
> > Support for all interrupt driven mode is planned, and it shows promising
> > results.
> 
> Which cgroup will the CPU cycles used for polling be attributed to? Can the
> polling code be moved into user space such that it becomes easy to identify
> which process needs most CPU cycles for polling and such that the polling
> CPU cycles are attributed to the proper cgroup?


Currently there is a single IO thread per each virtual controller instance.
I would prefer to keep all the driver in the kernel, but I think I can make it
cgroup aware, in a simiar way this is done in vhost-net, and vhost-scsi.

Best regards,
	Maxim Levitsky


> Thanks,
> 
> Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-20 16:48     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 16:48 UTC (permalink / raw)
  To: Bart Van Assche, linux-nvme
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, David S . Miller,
	Greg Kroah-Hartman, Liang Cunming, Wolfram Sang, linux-kernel,
	Kirti Wankhede, Jens Axboe, Alex Williamson, John Ferlan,
	Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney, Amnon Ilan, Christoph Hellwig, Nicolas Ferre

On Wed, 2019-03-20 at 08:08 -0700, Bart Van Assche wrote:
> On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:
> > * Polling kernel thread is used. The polling is stopped after a 
> > predefined timeout (1/2 sec by default).
> > Support for all interrupt driven mode is planned, and it shows promising
> > results.
> 
> Which cgroup will the CPU cycles used for polling be attributed to? Can the
> polling code be moved into user space such that it becomes easy to identify
> which process needs most CPU cycles for polling and such that the polling
> CPU cycles are attributed to the proper cgroup?


Currently there is a single IO thread per each virtual controller instance.
I would prefer to keep all the driver in the kernel, but I think I can make it
cgroup aware, in a simiar way this is done in vhost-net, and vhost-scsi.

Best regards,
	Maxim Levitsky


> Thanks,
> 
> Bart.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-20 16:30     ` Maxim Levitsky
@ 2019-03-20 17:03       ` Keith Busch
  -1 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-20 17:03 UTC (permalink / raw)


On Wed, Mar 20, 2019@06:30:29PM +0200, Maxim Levitsky wrote:
> Or instead I can use the block backend, 
> (but note that currently the block back-end doesn't support polling which is
> critical for the performance).

Oh, I think you can do polling through there. For reference, fs/io_uring.c
has a pretty good implementation that aligns with how you could use it.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-20 17:03       ` Keith Busch
  0 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-20 17:03 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, Wolfram Sang,
	Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre, linux-kernel,
	linux-nvme, David S . Miller, Jens Axboe, Alex Williamson,
	Kirti Wankhede, Mauro Carvalho Chehab, Paolo Bonzini,
	Liu Changpeng, Paul E . McKenney, Amnon Ilan, Christoph Hellwig,
	John Ferlan

On Wed, Mar 20, 2019 at 06:30:29PM +0200, Maxim Levitsky wrote:
> Or instead I can use the block backend, 
> (but note that currently the block back-end doesn't support polling which is
> critical for the performance).

Oh, I think you can do polling through there. For reference, fs/io_uring.c
has a pretty good implementation that aligns with how you could use it.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device
  2019-03-20 16:42     ` Maxim Levitsky
@ 2019-03-20 17:03       ` Alex Williamson
  -1 siblings, 0 replies; 409+ messages in thread
From: Alex Williamson @ 2019-03-20 17:03 UTC (permalink / raw)


On Wed, 20 Mar 2019 18:42:02 +0200
Maxim Levitsky <mlevitsk@redhat.com> wrote:

> On Wed, 2019-03-20@08:28 -0700, Bart Van Assche wrote:
> > On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:  
> > > *  All guest memory is mapped into the physical nvme device 
> > >    but not 1:1 as vfio-pci would do this.
> > >    This allows very efficient DMA.
> > >    To support this, patch 2 adds ability for a mdev device to listen on 
> > >    guest's memory map events. 
> > >    Any such memory is immediately pinned and then DMA mapped.
> > >    (Support for fabric drivers where this is not possible exits too,
> > >     in which case the fabric driver will do its own DMA mapping)  
> > 
> > Does this mean that all guest memory is pinned all the time? If so, are you
> > sure that's acceptable?  
> I think so. The VFIO pci passthrough also pins all the guest memory.
> SPDK also does this (pins and dma maps) all the guest memory.
> 
> I agree that this is not an ideal solution but this is a fastest and simplest
> solution possible.

FWIW, the pinned memory request up through the vfio iommu driver count
against the user's locked memory limits, if that's the concern.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device
@ 2019-03-20 17:03       ` Alex Williamson
  0 siblings, 0 replies; 409+ messages in thread
From: Alex Williamson @ 2019-03-20 17:03 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: Bart Van Assche, linux-nvme, Fam Zheng, Jens Axboe, Sagi Grimberg,
	kvm, Wolfram Sang, Greg Kroah-Hartman, Liang Cunming,
	Nicolas Ferre, linux-kernel, Liu Changpeng, Keith Busch,
	Kirti Wankhede, Christoph Hellwig, Paolo Bonzini,
	Mauro Carvalho Chehab, John Ferlan, Paul E . McKenney, Amnon Ilan,
	David S . Miller

On Wed, 20 Mar 2019 18:42:02 +0200
Maxim Levitsky <mlevitsk@redhat.com> wrote:

> On Wed, 2019-03-20 at 08:28 -0700, Bart Van Assche wrote:
> > On Tue, 2019-03-19 at 16:41 +0200, Maxim Levitsky wrote:  
> > > *  All guest memory is mapped into the physical nvme device 
> > >    but not 1:1 as vfio-pci would do this.
> > >    This allows very efficient DMA.
> > >    To support this, patch 2 adds ability for a mdev device to listen on 
> > >    guest's memory map events. 
> > >    Any such memory is immediately pinned and then DMA mapped.
> > >    (Support for fabric drivers where this is not possible exits too,
> > >     in which case the fabric driver will do its own DMA mapping)  
> > 
> > Does this mean that all guest memory is pinned all the time? If so, are you
> > sure that's acceptable?  
> I think so. The VFIO pci passthrough also pins all the guest memory.
> SPDK also does this (pins and dma maps) all the guest memory.
> 
> I agree that this is not an ideal solution but this is a fastest and simplest
> solution possible.

FWIW, the pinned memory request up through the vfio iommu driver count
against the user's locked memory limits, if that's the concern.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-20 17:03       ` Keith Busch
@ 2019-03-20 17:33         ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 17:33 UTC (permalink / raw)


On Wed, 2019-03-20@11:03 -0600, Keith Busch wrote:
> On Wed, Mar 20, 2019@06:30:29PM +0200, Maxim Levitsky wrote:
> > Or instead I can use the block backend, 
> > (but note that currently the block back-end doesn't support polling which is
> > critical for the performance).
> 
> Oh, I think you can do polling through there. For reference, fs/io_uring.c
> has a pretty good implementation that aligns with how you could use it.


That is exactly my thought. The polling recently got lot of improvements in the
block layer, which migh make this feasable.

I will give it a try.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-20 17:33         ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 17:33 UTC (permalink / raw)
  To: Keith Busch
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, Wolfram Sang,
	Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre, linux-kernel,
	linux-nvme, David S . Miller, Jens Axboe, Alex Williamson,
	Kirti Wankhede, Mauro Carvalho Chehab, Paolo Bonzini,
	Liu Changpeng, Paul E . McKenney, Amnon Ilan, Christoph Hellwig,
	John Ferlan

On Wed, 2019-03-20 at 11:03 -0600, Keith Busch wrote:
> On Wed, Mar 20, 2019 at 06:30:29PM +0200, Maxim Levitsky wrote:
> > Or instead I can use the block backend, 
> > (but note that currently the block back-end doesn't support polling which is
> > critical for the performance).
> 
> Oh, I think you can do polling through there. For reference, fs/io_uring.c
> has a pretty good implementation that aligns with how you could use it.


That is exactly my thought. The polling recently got lot of improvements in the
block layer, which migh make this feasable.

I will give it a try.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-20 11:03   ` Felipe Franciosi
@ 2019-03-20 19:08     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 19:08 UTC (permalink / raw)


On Wed, 2019-03-20@11:03 +0000, Felipe Franciosi wrote:
> > On Mar 19, 2019,@2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > 
> > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > 
> > Hi everyone!
> > 
> > In this patch series, I would like to introduce my take on the problem of
> > doing 
> > as fast as possible virtualization of storage with emphasis on low latency.
> > 
> > In this patch series I implemented a kernel vfio based, mediated device
> > that 
> > allows the user to pass through a partition and/or whole namespace to a
> > guest.
> 
> Hey Maxim!
> 
> I'm really excited to see this series, as it aligns to some extent with what
> we discussed in last year's KVM Forum VFIO BoF.
> 
> There's no arguing that we need a better story to efficiently virtualise NVMe
> devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best
> attempt at that. However, I seem to recall there was some pushback from qemu-
> devel in the sense that they would rather see investment in virtio-blk. I'm
> not sure what's the latest on that work and what are the next steps.
I agree with that. All my benchmarks were agains his vhost-user-nvme driver, and
I am able to get pretty much the same througput and latency.

The ssd I tested on died just recently (Murphy law), not due to bug in my driver
but some internal fault (even though most of my tests were reads, plus
occassional 'nvme format's.
We are in process of buying an replacement.

> 
> The pushback drove the discussion towards pursuing an mdev approach, which is
> why I'm excited to see your patches.
> 
> What I'm thinking is that passing through namespaces or partitions is very
> restrictive. It leaves no room to implement more elaborate virtualisation
> stacks like replicating data across multiple devices (local or remote),
> storage migration, software-managed thin provisioning, encryption,
> deduplication, compression, etc. In summary, anything that requires software
> intervention in the datapath. (Worth noting: vhost-user-nvme allows all of
> that to be easily done in SPDK's bdev layer.)

Hi Felipe!

I guess that my driver is not geared toward more complicated use cases like you
mentioned, but instead it is focused to get as fast as possible performance for
the common case.

One thing that I can do which would solve several of the above problems is to
accept an map betwent virtual and real logical blocks, pretty much in exactly
the same way as EPT does it.
Then userspace can map any portions of the device anywhere, while still keeping
the dataplane in the kernel, and having minimal overhead.

On top of that, note that the direction of IO virtualization is to do dataplane
in hardware, which will probably give you even worse partition granuality /
features but will be the fastest option aviable,
like for instance SR-IOV which alrady exists and just allows to split by
namespaces without any more fine grained control.

Think of nvme-mdev as a very low level driver, which currntly uses polling, but
eventually will use PASID based IOMMU to provide the guest with raw PCI device.
The userspace / qemu can build on top of that with varios software layers.

On top of that I am thinking to solve the problem of migration in Qemu, by
creating a 'vfio-nvme' driver which would bind vfio to bind to device exposed by
the kernel, and would pass through all the doorbells and queues to the guest,
while intercepting the admin queue. Such driver I think can be made to support
migration while beeing able to run on top both SR-IOV device, my vfio-nvme abit
with double admin queue emulation (its a bit ugly but won't affect performance
at all) and on top of even regular NVME device vfio assigned to guest.


Best regards,
	Maxim Levitsky

> 
> These complicated stacks should probably not be implemented in the kernel,
> though. So I'm wondering whether we could talk about mechanisms to allow
> efficient and performant userspace datapath intervention  in your approach or
> pursue a mechanism to completely offload the device emulation to userspace
> (and align with what SPDK has to offer).
> 
> Thoughts welcome!
> Felipe
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-20 19:08     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-20 19:08 UTC (permalink / raw)
  To: Felipe Franciosi
  Cc: Fam Zheng, kvm@vger.kernel.org, Wolfram Sang,
	linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Keith Busch, Kirti Wankhede, Mauro Carvalho Chehab,
	Paul E . McKenney, Christoph Hellwig, Sagi Grimberg,
	Harris, James R, Liang Cunming, Jens Axboe, Alex Williamson,
	Stefan Hajnoczi, Thanos Makatos, John Ferlan

On Wed, 2019-03-20 at 11:03 +0000, Felipe Franciosi wrote:
> > On Mar 19, 2019, at 2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > 
> > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > 
> > Hi everyone!
> > 
> > In this patch series, I would like to introduce my take on the problem of
> > doing 
> > as fast as possible virtualization of storage with emphasis on low latency.
> > 
> > In this patch series I implemented a kernel vfio based, mediated device
> > that 
> > allows the user to pass through a partition and/or whole namespace to a
> > guest.
> 
> Hey Maxim!
> 
> I'm really excited to see this series, as it aligns to some extent with what
> we discussed in last year's KVM Forum VFIO BoF.
> 
> There's no arguing that we need a better story to efficiently virtualise NVMe
> devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best
> attempt at that. However, I seem to recall there was some pushback from qemu-
> devel in the sense that they would rather see investment in virtio-blk. I'm
> not sure what's the latest on that work and what are the next steps.
I agree with that. All my benchmarks were agains his vhost-user-nvme driver, and
I am able to get pretty much the same througput and latency.

The ssd I tested on died just recently (Murphy law), not due to bug in my driver
but some internal fault (even though most of my tests were reads, plus
occassional 'nvme format's.
We are in process of buying an replacement.

> 
> The pushback drove the discussion towards pursuing an mdev approach, which is
> why I'm excited to see your patches.
> 
> What I'm thinking is that passing through namespaces or partitions is very
> restrictive. It leaves no room to implement more elaborate virtualisation
> stacks like replicating data across multiple devices (local or remote),
> storage migration, software-managed thin provisioning, encryption,
> deduplication, compression, etc. In summary, anything that requires software
> intervention in the datapath. (Worth noting: vhost-user-nvme allows all of
> that to be easily done in SPDK's bdev layer.)

Hi Felipe!

I guess that my driver is not geared toward more complicated use cases like you
mentioned, but instead it is focused to get as fast as possible performance for
the common case.

One thing that I can do which would solve several of the above problems is to
accept an map betwent virtual and real logical blocks, pretty much in exactly
the same way as EPT does it.
Then userspace can map any portions of the device anywhere, while still keeping
the dataplane in the kernel, and having minimal overhead.

On top of that, note that the direction of IO virtualization is to do dataplane
in hardware, which will probably give you even worse partition granuality /
features but will be the fastest option aviable,
like for instance SR-IOV which alrady exists and just allows to split by
namespaces without any more fine grained control.

Think of nvme-mdev as a very low level driver, which currntly uses polling, but
eventually will use PASID based IOMMU to provide the guest with raw PCI device.
The userspace / qemu can build on top of that with varios software layers.

On top of that I am thinking to solve the problem of migration in Qemu, by
creating a 'vfio-nvme' driver which would bind vfio to bind to device exposed by
the kernel, and would pass through all the doorbells and queues to the guest,
while intercepting the admin queue. Such driver I think can be made to support
migration while beeing able to run on top both SR-IOV device, my vfio-nvme abit
with double admin queue emulation (its a bit ugly but won't affect performance
at all) and on top of even regular NVME device vfio assigned to guest.


Best regards,
	Maxim Levitsky

> 
> These complicated stacks should probably not be implemented in the kernel,
> though. So I'm wondering whether we could talk about mechanisms to allow
> efficient and performant userspace datapath intervention  in your approach or
> pursue a mechanism to completely offload the device emulation to userspace
> (and align with what SPDK has to offer).
> 
> Thoughts welcome!
> Felipe
> _______________________________________________
> Linux-nvme mailing list
> Linux-nvme@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-20 19:08     ` Maxim Levitsky
@ 2019-03-21 16:12       ` Stefan Hajnoczi
  -1 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-21 16:12 UTC (permalink / raw)


On Wed, Mar 20, 2019@09:08:37PM +0200, Maxim Levitsky wrote:
> On Wed, 2019-03-20@11:03 +0000, Felipe Franciosi wrote:
> > > On Mar 19, 2019,@2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > > 
> > > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > > 
> > > Hi everyone!
> > > 
> > > In this patch series, I would like to introduce my take on the problem of
> > > doing 
> > > as fast as possible virtualization of storage with emphasis on low latency.
> > > 
> > > In this patch series I implemented a kernel vfio based, mediated device
> > > that 
> > > allows the user to pass through a partition and/or whole namespace to a
> > > guest.
> > 
> > Hey Maxim!
> > 
> > I'm really excited to see this series, as it aligns to some extent with what
> > we discussed in last year's KVM Forum VFIO BoF.
> > 
> > There's no arguing that we need a better story to efficiently virtualise NVMe
> > devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best
> > attempt at that. However, I seem to recall there was some pushback from qemu-
> > devel in the sense that they would rather see investment in virtio-blk. I'm
> > not sure what's the latest on that work and what are the next steps.
> I agree with that. All my benchmarks were agains his vhost-user-nvme driver, and
> I am able to get pretty much the same througput and latency.
> 
> The ssd I tested on died just recently (Murphy law), not due to bug in my driver
> but some internal fault (even though most of my tests were reads, plus
> occassional 'nvme format's.
> We are in process of buying an replacement.
> 
> > 
> > The pushback drove the discussion towards pursuing an mdev approach, which is
> > why I'm excited to see your patches.
> > 
> > What I'm thinking is that passing through namespaces or partitions is very
> > restrictive. It leaves no room to implement more elaborate virtualisation
> > stacks like replicating data across multiple devices (local or remote),
> > storage migration, software-managed thin provisioning, encryption,
> > deduplication, compression, etc. In summary, anything that requires software
> > intervention in the datapath. (Worth noting: vhost-user-nvme allows all of
> > that to be easily done in SPDK's bdev layer.)
> 
> Hi Felipe!
> 
> I guess that my driver is not geared toward more complicated use cases like you
> mentioned, but instead it is focused to get as fast as possible performance for
> the common case.
> 
> One thing that I can do which would solve several of the above problems is to
> accept an map betwent virtual and real logical blocks, pretty much in exactly
> the same way as EPT does it.
> Then userspace can map any portions of the device anywhere, while still keeping
> the dataplane in the kernel, and having minimal overhead.
> 
> On top of that, note that the direction of IO virtualization is to do dataplane
> in hardware, which will probably give you even worse partition granuality /
> features but will be the fastest option aviable,
> like for instance SR-IOV which alrady exists and just allows to split by
> namespaces without any more fine grained control.
> 
> Think of nvme-mdev as a very low level driver, which currntly uses polling, but
> eventually will use PASID based IOMMU to provide the guest with raw PCI device.
> The userspace / qemu can build on top of that with varios software layers.
> 
> On top of that I am thinking to solve the problem of migration in Qemu, by
> creating a 'vfio-nvme' driver which would bind vfio to bind to device exposed by
> the kernel, and would pass through all the doorbells and queues to the guest,
> while intercepting the admin queue. Such driver I think can be made to support
> migration while beeing able to run on top both SR-IOV device, my vfio-nvme abit
> with double admin queue emulation (its a bit ugly but won't affect performance
> at all) and on top of even regular NVME device vfio assigned to guest.

mdev-nvme seems like a duplication of SPDK.  The performance is not
better and the features are more limited, so why focus on this approach?

One argument might be that the kernel NVMe subsystem wants to offer this
functionality and loading the kernel module is more convenient than
managing SPDK to some users.

Thoughts?

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-nvme/attachments/20190321/8b770a99/attachment.sig>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-21 16:12       ` Stefan Hajnoczi
  0 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-21 16:12 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: Felipe Franciosi, Fam Zheng, kvm@vger.kernel.org, Wolfram Sang,
	linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Keith Busch, Kirti Wankhede, Mauro Carvalho Chehab,
	Paul E . McKenney, Christoph Hellwig, Sagi Grimberg,
	Harris, James R, Liang Cunming, Jens Axboe, Alex Williamson,
	Thanos Makatos, John Ferlan, Liu 

[-- Attachment #1: Type: text/plain, Size: 4404 bytes --]

On Wed, Mar 20, 2019 at 09:08:37PM +0200, Maxim Levitsky wrote:
> On Wed, 2019-03-20 at 11:03 +0000, Felipe Franciosi wrote:
> > > On Mar 19, 2019, at 2:41 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > > 
> > > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > > 
> > > Hi everyone!
> > > 
> > > In this patch series, I would like to introduce my take on the problem of
> > > doing 
> > > as fast as possible virtualization of storage with emphasis on low latency.
> > > 
> > > In this patch series I implemented a kernel vfio based, mediated device
> > > that 
> > > allows the user to pass through a partition and/or whole namespace to a
> > > guest.
> > 
> > Hey Maxim!
> > 
> > I'm really excited to see this series, as it aligns to some extent with what
> > we discussed in last year's KVM Forum VFIO BoF.
> > 
> > There's no arguing that we need a better story to efficiently virtualise NVMe
> > devices. So far, for Qemu-based VMs, Changpeng's vhost-user-nvme is the best
> > attempt at that. However, I seem to recall there was some pushback from qemu-
> > devel in the sense that they would rather see investment in virtio-blk. I'm
> > not sure what's the latest on that work and what are the next steps.
> I agree with that. All my benchmarks were agains his vhost-user-nvme driver, and
> I am able to get pretty much the same througput and latency.
> 
> The ssd I tested on died just recently (Murphy law), not due to bug in my driver
> but some internal fault (even though most of my tests were reads, plus
> occassional 'nvme format's.
> We are in process of buying an replacement.
> 
> > 
> > The pushback drove the discussion towards pursuing an mdev approach, which is
> > why I'm excited to see your patches.
> > 
> > What I'm thinking is that passing through namespaces or partitions is very
> > restrictive. It leaves no room to implement more elaborate virtualisation
> > stacks like replicating data across multiple devices (local or remote),
> > storage migration, software-managed thin provisioning, encryption,
> > deduplication, compression, etc. In summary, anything that requires software
> > intervention in the datapath. (Worth noting: vhost-user-nvme allows all of
> > that to be easily done in SPDK's bdev layer.)
> 
> Hi Felipe!
> 
> I guess that my driver is not geared toward more complicated use cases like you
> mentioned, but instead it is focused to get as fast as possible performance for
> the common case.
> 
> One thing that I can do which would solve several of the above problems is to
> accept an map betwent virtual and real logical blocks, pretty much in exactly
> the same way as EPT does it.
> Then userspace can map any portions of the device anywhere, while still keeping
> the dataplane in the kernel, and having minimal overhead.
> 
> On top of that, note that the direction of IO virtualization is to do dataplane
> in hardware, which will probably give you even worse partition granuality /
> features but will be the fastest option aviable,
> like for instance SR-IOV which alrady exists and just allows to split by
> namespaces without any more fine grained control.
> 
> Think of nvme-mdev as a very low level driver, which currntly uses polling, but
> eventually will use PASID based IOMMU to provide the guest with raw PCI device.
> The userspace / qemu can build on top of that with varios software layers.
> 
> On top of that I am thinking to solve the problem of migration in Qemu, by
> creating a 'vfio-nvme' driver which would bind vfio to bind to device exposed by
> the kernel, and would pass through all the doorbells and queues to the guest,
> while intercepting the admin queue. Such driver I think can be made to support
> migration while beeing able to run on top both SR-IOV device, my vfio-nvme abit
> with double admin queue emulation (its a bit ugly but won't affect performance
> at all) and on top of even regular NVME device vfio assigned to guest.

mdev-nvme seems like a duplication of SPDK.  The performance is not
better and the features are more limited, so why focus on this approach?

One argument might be that the kernel NVMe subsystem wants to offer this
functionality and loading the kernel module is more convenient than
managing SPDK to some users.

Thoughts?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 14:41 ` (unknown) Maxim Levitsky
@ 2019-03-21 16:13   ` Stefan Hajnoczi
  -1 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-21 16:13 UTC (permalink / raw)


On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.
> 
> The idea behind this driver is based on paper you can find at
> https://www.usenix.org/conference/atc18/presentation/peng,
> 
> Although note that I stared the development prior to reading this paper, 
> independently.
> 
> In addition to that implementation is not based on code used in the paper as 
> I wasn't being able at that time to make the source available to me.
> 
> ***Key points about the implementation:***
> 
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising results.
> 
> * Guest sees a standard NVME device - this allows to run guest with 
> unmodified drivers, for example windows guests.
> 
> * The NVMe device is shared between host and guest.
> That means that even a single namespace can be split between host 
> and guest based on different partitions.
> 
> * Simple configuration
> 
> *** Performance ***
> 
> Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> and both latency and throughput is very similar to SPDK.
> 
> Soon I will test this on a better server and nvme device and provide
> more formal performance numbers.
> 
> Latency numbers:
> ~80ms - spdk with fio plugin on the host.
> ~84ms - nvme driver on the host
> ~87ms - mdev-nvme + nvme driver in the guest

You mentioned the spdk numbers are with vhost-user-nvme.  Have you
measured SPDK's vhost-user-blk?

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-nvme/attachments/20190321/43a43762/attachment.sig>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-21 16:13   ` Stefan Hajnoczi
  0 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-21 16:13 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney , Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfe

[-- Attachment #1: Type: text/plain, Size: 2018 bytes --]

On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> Date: Tue, 19 Mar 2019 14:45:45 +0200
> Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> 
> Hi everyone!
> 
> In this patch series, I would like to introduce my take on the problem of doing 
> as fast as possible virtualization of storage with emphasis on low latency.
> 
> In this patch series I implemented a kernel vfio based, mediated device that 
> allows the user to pass through a partition and/or whole namespace to a guest.
> 
> The idea behind this driver is based on paper you can find at
> https://www.usenix.org/conference/atc18/presentation/peng,
> 
> Although note that I stared the development prior to reading this paper, 
> independently.
> 
> In addition to that implementation is not based on code used in the paper as 
> I wasn't being able at that time to make the source available to me.
> 
> ***Key points about the implementation:***
> 
> * Polling kernel thread is used. The polling is stopped after a 
> predefined timeout (1/2 sec by default).
> Support for all interrupt driven mode is planned, and it shows promising results.
> 
> * Guest sees a standard NVME device - this allows to run guest with 
> unmodified drivers, for example windows guests.
> 
> * The NVMe device is shared between host and guest.
> That means that even a single namespace can be split between host 
> and guest based on different partitions.
> 
> * Simple configuration
> 
> *** Performance ***
> 
> Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> and both latency and throughput is very similar to SPDK.
> 
> Soon I will test this on a better server and nvme device and provide
> more formal performance numbers.
> 
> Latency numbers:
> ~80ms - spdk with fio plugin on the host.
> ~84ms - nvme driver on the host
> ~87ms - mdev-nvme + nvme driver in the guest

You mentioned the spdk numbers are with vhost-user-nvme.  Have you
measured SPDK's vhost-user-blk?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-21 16:12       ` Stefan Hajnoczi
@ 2019-03-21 16:21         ` Keith Busch
  -1 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-21 16:21 UTC (permalink / raw)


On Thu, Mar 21, 2019@04:12:39PM +0000, Stefan Hajnoczi wrote:
> mdev-nvme seems like a duplication of SPDK.  The performance is not
> better and the features are more limited, so why focus on this approach?
> 
> One argument might be that the kernel NVMe subsystem wants to offer this
> functionality and loading the kernel module is more convenient than
> managing SPDK to some users.
> 
> Thoughts?

Doesn't SPDK bind a controller to a single process? mdev binds to
namespaces (or their partitions), so you could have many mdev's assigned
to many VMs accessing a single controller.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-21 16:21         ` Keith Busch
  0 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-21 16:21 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Maxim Levitsky, Fam Zheng, kvm@vger.kernel.org, Wolfram Sang,
	linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Keith Busch, Kirti Wankhede, Mauro Carvalho Chehab,
	Paul E . McKenney, Christoph Hellwig, Sagi Grimberg,
	Harris, James R, Felipe Franciosi, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos, Jo

On Thu, Mar 21, 2019 at 04:12:39PM +0000, Stefan Hajnoczi wrote:
> mdev-nvme seems like a duplication of SPDK.  The performance is not
> better and the features are more limited, so why focus on this approach?
> 
> One argument might be that the kernel NVMe subsystem wants to offer this
> functionality and loading the kernel module is more convenient than
> managing SPDK to some users.
> 
> Thoughts?

Doesn't SPDK bind a controller to a single process? mdev binds to
namespaces (or their partitions), so you could have many mdev's assigned
to many VMs accessing a single controller.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-21 16:21         ` Keith Busch
@ 2019-03-21 16:41           ` Felipe Franciosi
  -1 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-21 16:41 UTC (permalink / raw)




> On Mar 21, 2019,@4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> 
> On Thu, Mar 21, 2019@04:12:39PM +0000, Stefan Hajnoczi wrote:
>> mdev-nvme seems like a duplication of SPDK.  The performance is not
>> better and the features are more limited, so why focus on this approach?
>> 
>> One argument might be that the kernel NVMe subsystem wants to offer this
>> functionality and loading the kernel module is more convenient than
>> managing SPDK to some users.
>> 
>> Thoughts?
> 
> Doesn't SPDK bind a controller to a single process? mdev binds to
> namespaces (or their partitions), so you could have many mdev's assigned
> to many VMs accessing a single controller.

Yes, it binds to a single process which can drive the datapath of multiple virtual controllers for multiple VMs (similar to what you described for mdev). You can therefore efficiently poll multiple VM submission queues (and multiple device completion queues) from a single physical CPU.

The same could be done in the kernel, but the code gets complicated as you add more functionality to it. As this is a direct interface with an untrusted front-end (the guest), it's also arguably safer to do in userspace.

Worth noting: you can eventually have a single physical core polling all sorts of virtual devices (eg. virtual storage or network controllers) very efficiently. And this is quite configurable, too. In the interest of fairness, performance or efficiency, you can choose to dynamically add or remove queues to the poll thread or spawn more threads and redistribute the work.

F.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-21 16:41           ` Felipe Franciosi
  0 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-21 16:41 UTC (permalink / raw)
  To: Keith Busch
  Cc: Stefan Hajnoczi, Maxim Levitsky, Fam Zheng, kvm@vger.kernel.org,
	Wolfram Sang, linux-nvme@lists.infradead.org,
	linux-kernel@vger.kernel.org, Keith Busch, Kirti Wankhede,
	Mauro Carvalho Chehab, Paul E . McKenney, Christoph Hellwig,
	Sagi Grimberg, Harris, James R, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos



> On Mar 21, 2019, at 4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> 
> On Thu, Mar 21, 2019 at 04:12:39PM +0000, Stefan Hajnoczi wrote:
>> mdev-nvme seems like a duplication of SPDK.  The performance is not
>> better and the features are more limited, so why focus on this approach?
>> 
>> One argument might be that the kernel NVMe subsystem wants to offer this
>> functionality and loading the kernel module is more convenient than
>> managing SPDK to some users.
>> 
>> Thoughts?
> 
> Doesn't SPDK bind a controller to a single process? mdev binds to
> namespaces (or their partitions), so you could have many mdev's assigned
> to many VMs accessing a single controller.

Yes, it binds to a single process which can drive the datapath of multiple virtual controllers for multiple VMs (similar to what you described for mdev). You can therefore efficiently poll multiple VM submission queues (and multiple device completion queues) from a single physical CPU.

The same could be done in the kernel, but the code gets complicated as you add more functionality to it. As this is a direct interface with an untrusted front-end (the guest), it's also arguably safer to do in userspace.

Worth noting: you can eventually have a single physical core polling all sorts of virtual devices (eg. virtual storage or network controllers) very efficiently. And this is quite configurable, too. In the interest of fairness, performance or efficiency, you can choose to dynamically add or remove queues to the poll thread or spawn more threads and redistribute the work.

F.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-21 16:41           ` Felipe Franciosi
@ 2019-03-21 17:04             ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-21 17:04 UTC (permalink / raw)


On Thu, 2019-03-21@16:41 +0000, Felipe Franciosi wrote:
> > On Mar 21, 2019,@4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> > 
> > On Thu, Mar 21, 2019@04:12:39PM +0000, Stefan Hajnoczi wrote:
> > > mdev-nvme seems like a duplication of SPDK.  The performance is not
> > > better and the features are more limited, so why focus on this approach?
> > > 
> > > One argument might be that the kernel NVMe subsystem wants to offer this
> > > functionality and loading the kernel module is more convenient than
> > > managing SPDK to some users.
> > > 
> > > Thoughts?
> > 
> > Doesn't SPDK bind a controller to a single process? mdev binds to
> > namespaces (or their partitions), so you could have many mdev's assigned
> > to many VMs accessing a single controller.
> 
> Yes, it binds to a single process which can drive the datapath of multiple
> virtual controllers for multiple VMs (similar to what you described for mdev).
> You can therefore efficiently poll multiple VM submission queues (and multiple
> device completion queues) from a single physical CPU.
> 
> The same could be done in the kernel, but the code gets complicated as you add
> more functionality to it. As this is a direct interface with an untrusted
> front-end (the guest), it's also arguably safer to do in userspace.
> 
> Worth noting: you can eventually have a single physical core polling all sorts
> of virtual devices (eg. virtual storage or network controllers) very
> efficiently. And this is quite configurable, too. In the interest of fairness,
> performance or efficiency, you can choose to dynamically add or remove queues
> to the poll thread or spawn more threads and redistribute the work.
> 
> F.

Note though that SPDK doesn't support sharing the device between host and the
guests, it takes over the nvme device, thus it makes the kernel nvme driver
unbind from it.

My driver creates a polling thread per guest, but its trivial to add option to
use the same polling thread for many guests if there need for that.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-21 17:04             ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-21 17:04 UTC (permalink / raw)
  To: Felipe Franciosi, Keith Busch
  Cc: Stefan Hajnoczi, Fam Zheng, kvm@vger.kernel.org, Wolfram Sang,
	linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Keith Busch, Kirti Wankhede, Mauro Carvalho Chehab,
	Paul E . McKenney, Christoph Hellwig, Sagi Grimberg,
	Harris, James R, Liang Cunming, Jens Axboe, Alex Williamson,
	Thanos Makatos, John Ferlan, Liu 

On Thu, 2019-03-21 at 16:41 +0000, Felipe Franciosi wrote:
> > On Mar 21, 2019, at 4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> > 
> > On Thu, Mar 21, 2019 at 04:12:39PM +0000, Stefan Hajnoczi wrote:
> > > mdev-nvme seems like a duplication of SPDK.  The performance is not
> > > better and the features are more limited, so why focus on this approach?
> > > 
> > > One argument might be that the kernel NVMe subsystem wants to offer this
> > > functionality and loading the kernel module is more convenient than
> > > managing SPDK to some users.
> > > 
> > > Thoughts?
> > 
> > Doesn't SPDK bind a controller to a single process? mdev binds to
> > namespaces (or their partitions), so you could have many mdev's assigned
> > to many VMs accessing a single controller.
> 
> Yes, it binds to a single process which can drive the datapath of multiple
> virtual controllers for multiple VMs (similar to what you described for mdev).
> You can therefore efficiently poll multiple VM submission queues (and multiple
> device completion queues) from a single physical CPU.
> 
> The same could be done in the kernel, but the code gets complicated as you add
> more functionality to it. As this is a direct interface with an untrusted
> front-end (the guest), it's also arguably safer to do in userspace.
> 
> Worth noting: you can eventually have a single physical core polling all sorts
> of virtual devices (eg. virtual storage or network controllers) very
> efficiently. And this is quite configurable, too. In the interest of fairness,
> performance or efficiency, you can choose to dynamically add or remove queues
> to the poll thread or spawn more threads and redistribute the work.
> 
> F.

Note though that SPDK doesn't support sharing the device between host and the
guests, it takes over the nvme device, thus it makes the kernel nvme driver
unbind from it.

My driver creates a polling thread per guest, but its trivial to add option to
use the same polling thread for many guests if there need for that.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-21 16:13   ` Stefan Hajnoczi
@ 2019-03-21 17:07     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-21 17:07 UTC (permalink / raw)


On Thu, 2019-03-21@16:13 +0000, Stefan Hajnoczi wrote:
> On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > 
> > Hi everyone!
> > 
> > In this patch series, I would like to introduce my take on the problem of
> > doing 
> > as fast as possible virtualization of storage with emphasis on low latency.
> > 
> > In this patch series I implemented a kernel vfio based, mediated device
> > that 
> > allows the user to pass through a partition and/or whole namespace to a
> > guest.
> > 
> > The idea behind this driver is based on paper you can find at
> > https://www.usenix.org/conference/atc18/presentation/peng,
> > 
> > Although note that I stared the development prior to reading this paper, 
> > independently.
> > 
> > In addition to that implementation is not based on code used in the paper
> > as 
> > I wasn't being able at that time to make the source available to me.
> > 
> > ***Key points about the implementation:***
> > 
> > * Polling kernel thread is used. The polling is stopped after a 
> > predefined timeout (1/2 sec by default).
> > Support for all interrupt driven mode is planned, and it shows promising
> > results.
> > 
> > * Guest sees a standard NVME device - this allows to run guest with 
> > unmodified drivers, for example windows guests.
> > 
> > * The NVMe device is shared between host and guest.
> > That means that even a single namespace can be split between host 
> > and guest based on different partitions.
> > 
> > * Simple configuration
> > 
> > *** Performance ***
> > 
> > Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> > and both latency and throughput is very similar to SPDK.
> > 
> > Soon I will test this on a better server and nvme device and provide
> > more formal performance numbers.
> > 
> > Latency numbers:
> > ~80ms - spdk with fio plugin on the host.
> > ~84ms - nvme driver on the host
> > ~87ms - mdev-nvme + nvme driver in the guest
> 
> You mentioned the spdk numbers are with vhost-user-nvme.  Have you
> measured SPDK's vhost-user-blk?

I had lot of measuments of vhost-user-blk vs vhost-user-nvme.
vhost-user-nvme was always a bit faster but only a bit.
Thus I don't think it makes sense to benchamrk against vhost-user-blk.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-21 17:07     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-21 17:07 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney, Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfer

On Thu, 2019-03-21 at 16:13 +0000, Stefan Hajnoczi wrote:
> On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > 
> > Hi everyone!
> > 
> > In this patch series, I would like to introduce my take on the problem of
> > doing 
> > as fast as possible virtualization of storage with emphasis on low latency.
> > 
> > In this patch series I implemented a kernel vfio based, mediated device
> > that 
> > allows the user to pass through a partition and/or whole namespace to a
> > guest.
> > 
> > The idea behind this driver is based on paper you can find at
> > https://www.usenix.org/conference/atc18/presentation/peng,
> > 
> > Although note that I stared the development prior to reading this paper, 
> > independently.
> > 
> > In addition to that implementation is not based on code used in the paper
> > as 
> > I wasn't being able at that time to make the source available to me.
> > 
> > ***Key points about the implementation:***
> > 
> > * Polling kernel thread is used. The polling is stopped after a 
> > predefined timeout (1/2 sec by default).
> > Support for all interrupt driven mode is planned, and it shows promising
> > results.
> > 
> > * Guest sees a standard NVME device - this allows to run guest with 
> > unmodified drivers, for example windows guests.
> > 
> > * The NVMe device is shared between host and guest.
> > That means that even a single namespace can be split between host 
> > and guest based on different partitions.
> > 
> > * Simple configuration
> > 
> > *** Performance ***
> > 
> > Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> > and both latency and throughput is very similar to SPDK.
> > 
> > Soon I will test this on a better server and nvme device and provide
> > more formal performance numbers.
> > 
> > Latency numbers:
> > ~80ms - spdk with fio plugin on the host.
> > ~84ms - nvme driver on the host
> > ~87ms - mdev-nvme + nvme driver in the guest
> 
> You mentioned the spdk numbers are with vhost-user-nvme.  Have you
> measured SPDK's vhost-user-blk?

I had lot of measuments of vhost-user-blk vs vhost-user-nvme.
vhost-user-nvme was always a bit faster but only a bit.
Thus I don't think it makes sense to benchamrk against vhost-user-blk.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-21 17:04             ` Maxim Levitsky
@ 2019-03-22  7:54               ` Felipe Franciosi
  -1 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-22  7:54 UTC (permalink / raw)




> On Mar 21, 2019,@5:04 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> 
> On Thu, 2019-03-21@16:41 +0000, Felipe Franciosi wrote:
>>> On Mar 21, 2019,@4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
>>> 
>>> On Thu, Mar 21, 2019@04:12:39PM +0000, Stefan Hajnoczi wrote:
>>>> mdev-nvme seems like a duplication of SPDK.  The performance is not
>>>> better and the features are more limited, so why focus on this approach?
>>>> 
>>>> One argument might be that the kernel NVMe subsystem wants to offer this
>>>> functionality and loading the kernel module is more convenient than
>>>> managing SPDK to some users.
>>>> 
>>>> Thoughts?
>>> 
>>> Doesn't SPDK bind a controller to a single process? mdev binds to
>>> namespaces (or their partitions), so you could have many mdev's assigned
>>> to many VMs accessing a single controller.
>> 
>> Yes, it binds to a single process which can drive the datapath of multiple
>> virtual controllers for multiple VMs (similar to what you described for mdev).
>> You can therefore efficiently poll multiple VM submission queues (and multiple
>> device completion queues) from a single physical CPU.
>> 
>> The same could be done in the kernel, but the code gets complicated as you add
>> more functionality to it. As this is a direct interface with an untrusted
>> front-end (the guest), it's also arguably safer to do in userspace.
>> 
>> Worth noting: you can eventually have a single physical core polling all sorts
>> of virtual devices (eg. virtual storage or network controllers) very
>> efficiently. And this is quite configurable, too. In the interest of fairness,
>> performance or efficiency, you can choose to dynamically add or remove queues
>> to the poll thread or spawn more threads and redistribute the work.
>> 
>> F.
> 
> Note though that SPDK doesn't support sharing the device between host and the
> guests, it takes over the nvme device, thus it makes the kernel nvme driver
> unbind from it.

That is absolutely true. However, I find it not to be a problem in practice.

Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.

For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.

Cheers,
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-22  7:54               ` Felipe Franciosi
  0 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-22  7:54 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: Keith Busch, Stefan Hajnoczi, Fam Zheng, kvm@vger.kernel.org,
	Wolfram Sang, linux-nvme@lists.infradead.org,
	linux-kernel@vger.kernel.org, Keith Busch, Kirti Wankhede,
	Mauro Carvalho Chehab, Paul E . McKenney, Christoph Hellwig,
	Sagi Grimberg, Harris, James R, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos



> On Mar 21, 2019, at 5:04 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> 
> On Thu, 2019-03-21 at 16:41 +0000, Felipe Franciosi wrote:
>>> On Mar 21, 2019, at 4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
>>> 
>>> On Thu, Mar 21, 2019 at 04:12:39PM +0000, Stefan Hajnoczi wrote:
>>>> mdev-nvme seems like a duplication of SPDK.  The performance is not
>>>> better and the features are more limited, so why focus on this approach?
>>>> 
>>>> One argument might be that the kernel NVMe subsystem wants to offer this
>>>> functionality and loading the kernel module is more convenient than
>>>> managing SPDK to some users.
>>>> 
>>>> Thoughts?
>>> 
>>> Doesn't SPDK bind a controller to a single process? mdev binds to
>>> namespaces (or their partitions), so you could have many mdev's assigned
>>> to many VMs accessing a single controller.
>> 
>> Yes, it binds to a single process which can drive the datapath of multiple
>> virtual controllers for multiple VMs (similar to what you described for mdev).
>> You can therefore efficiently poll multiple VM submission queues (and multiple
>> device completion queues) from a single physical CPU.
>> 
>> The same could be done in the kernel, but the code gets complicated as you add
>> more functionality to it. As this is a direct interface with an untrusted
>> front-end (the guest), it's also arguably safer to do in userspace.
>> 
>> Worth noting: you can eventually have a single physical core polling all sorts
>> of virtual devices (eg. virtual storage or network controllers) very
>> efficiently. And this is quite configurable, too. In the interest of fairness,
>> performance or efficiency, you can choose to dynamically add or remove queues
>> to the poll thread or spawn more threads and redistribute the work.
>> 
>> F.
> 
> Note though that SPDK doesn't support sharing the device between host and the
> guests, it takes over the nvme device, thus it makes the kernel nvme driver
> unbind from it.

That is absolutely true. However, I find it not to be a problem in practice.

Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.

For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.

Cheers,
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-22  7:54               ` Felipe Franciosi
@ 2019-03-22 10:32                 ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-22 10:32 UTC (permalink / raw)


On Fri, 2019-03-22@07:54 +0000, Felipe Franciosi wrote:
> > On Mar 21, 2019,@5:04 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > 
> > On Thu, 2019-03-21@16:41 +0000, Felipe Franciosi wrote:
> > > > On Mar 21, 2019,@4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> > > > 
> > > > On Thu, Mar 21, 2019@04:12:39PM +0000, Stefan Hajnoczi wrote:
> > > > > mdev-nvme seems like a duplication of SPDK.  The performance is not
> > > > > better and the features are more limited, so why focus on this
> > > > > approach?
> > > > > 
> > > > > One argument might be that the kernel NVMe subsystem wants to offer
> > > > > this
> > > > > functionality and loading the kernel module is more convenient than
> > > > > managing SPDK to some users.
> > > > > 
> > > > > Thoughts?
> > > > 
> > > > Doesn't SPDK bind a controller to a single process? mdev binds to
> > > > namespaces (or their partitions), so you could have many mdev's assigned
> > > > to many VMs accessing a single controller.
> > > 
> > > Yes, it binds to a single process which can drive the datapath of multiple
> > > virtual controllers for multiple VMs (similar to what you described for
> > > mdev).
> > > You can therefore efficiently poll multiple VM submission queues (and
> > > multiple
> > > device completion queues) from a single physical CPU.
> > > 
> > > The same could be done in the kernel, but the code gets complicated as you
> > > add
> > > more functionality to it. As this is a direct interface with an untrusted
> > > front-end (the guest), it's also arguably safer to do in userspace.
> > > 
> > > Worth noting: you can eventually have a single physical core polling all
> > > sorts
> > > of virtual devices (eg. virtual storage or network controllers) very
> > > efficiently. And this is quite configurable, too. In the interest of
> > > fairness,
> > > performance or efficiency, you can choose to dynamically add or remove
> > > queues
> > > to the poll thread or spawn more threads and redistribute the work.
> > > 
> > > F.
> > 
> > Note though that SPDK doesn't support sharing the device between host and
> > the
> > guests, it takes over the nvme device, thus it makes the kernel nvme driver
> > unbind from it.
> 
> That is absolutely true. However, I find it not to be a problem in practice.
> 
> Hypervisor products, specially those caring about performance, efficiency and
> fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk
> storage, cache, metadata) and will not share these devices for other use
> cases. That's because these products want to deterministically control the
> performance aspects of the device, which you just cannot do if you are sharing
> the device with a subsystem you do not control.
> 
> For scenarios where the device must be shared and such fine grained control is
> not required, it looks like using the kernel driver with io_uring offers very
> good performance with flexibility


I see the host/guest parition in the following way:
The guest assigned partitions are for guests that need lowest possible latency,
and in between these guests it is possible to guarantee good enough level of
fairness in my driver.
For example, in the current implementation of my driver, each guest gets its own
host submission queue.

On the other hand, the host assigned partitions are for significantly higher
latency IO, with no guarantees, and/or for guests that need all the more
advanced features of full IO virtualization, for instance snapshots, thin
provisioning, replication/backup over network, etc.
io_uring can be used here to speed things up but it won't reach the nvme-mdev
levels of latency.

Furthermore on NVME drives that support WRRU, its possible to let queues of
guest's assigned partitions to belong to the high priority class and let the
host queues use the regular medium/low priority class.
For drives that don't support WRRU, the IO throttling can be done in software on
the host queues.

Host assigned partitions also don't need polling, thus allowing polling to be
used only for guests that actually need low latency IO.
This reduces the number of cores that would be otherwise lost to polling,
because the less work the polling core does, the less latency it contributes to
overall latency, thus with less users, you could use less cores to achieve the
same levels of latency.

For Stefan's argument, we can look at it in a slightly different way too:
While the nvme-mdev can be seen as a duplication of SPDK, the SPDK can also be
seen as duplication of an existing kernel functionality which nvme-mdev can
reuse for free.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-22 10:32                 ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-22 10:32 UTC (permalink / raw)
  To: Felipe Franciosi
  Cc: Keith Busch, Stefan Hajnoczi, Fam Zheng, kvm@vger.kernel.org,
	Wolfram Sang, linux-nvme@lists.infradead.org,
	linux-kernel@vger.kernel.org, Keith Busch, Kirti Wankhede,
	Mauro Carvalho Chehab, Paul E . McKenney, Christoph Hellwig,
	Sagi Grimberg, Harris, James R, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos

On Fri, 2019-03-22 at 07:54 +0000, Felipe Franciosi wrote:
> > On Mar 21, 2019, at 5:04 PM, Maxim Levitsky <mlevitsk@redhat.com> wrote:
> > 
> > On Thu, 2019-03-21 at 16:41 +0000, Felipe Franciosi wrote:
> > > > On Mar 21, 2019, at 4:21 PM, Keith Busch <kbusch@kernel.org> wrote:
> > > > 
> > > > On Thu, Mar 21, 2019 at 04:12:39PM +0000, Stefan Hajnoczi wrote:
> > > > > mdev-nvme seems like a duplication of SPDK.  The performance is not
> > > > > better and the features are more limited, so why focus on this
> > > > > approach?
> > > > > 
> > > > > One argument might be that the kernel NVMe subsystem wants to offer
> > > > > this
> > > > > functionality and loading the kernel module is more convenient than
> > > > > managing SPDK to some users.
> > > > > 
> > > > > Thoughts?
> > > > 
> > > > Doesn't SPDK bind a controller to a single process? mdev binds to
> > > > namespaces (or their partitions), so you could have many mdev's assigned
> > > > to many VMs accessing a single controller.
> > > 
> > > Yes, it binds to a single process which can drive the datapath of multiple
> > > virtual controllers for multiple VMs (similar to what you described for
> > > mdev).
> > > You can therefore efficiently poll multiple VM submission queues (and
> > > multiple
> > > device completion queues) from a single physical CPU.
> > > 
> > > The same could be done in the kernel, but the code gets complicated as you
> > > add
> > > more functionality to it. As this is a direct interface with an untrusted
> > > front-end (the guest), it's also arguably safer to do in userspace.
> > > 
> > > Worth noting: you can eventually have a single physical core polling all
> > > sorts
> > > of virtual devices (eg. virtual storage or network controllers) very
> > > efficiently. And this is quite configurable, too. In the interest of
> > > fairness,
> > > performance or efficiency, you can choose to dynamically add or remove
> > > queues
> > > to the poll thread or spawn more threads and redistribute the work.
> > > 
> > > F.
> > 
> > Note though that SPDK doesn't support sharing the device between host and
> > the
> > guests, it takes over the nvme device, thus it makes the kernel nvme driver
> > unbind from it.
> 
> That is absolutely true. However, I find it not to be a problem in practice.
> 
> Hypervisor products, specially those caring about performance, efficiency and
> fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk
> storage, cache, metadata) and will not share these devices for other use
> cases. That's because these products want to deterministically control the
> performance aspects of the device, which you just cannot do if you are sharing
> the device with a subsystem you do not control.
> 
> For scenarios where the device must be shared and such fine grained control is
> not required, it looks like using the kernel driver with io_uring offers very
> good performance with flexibility


I see the host/guest parition in the following way:
The guest assigned partitions are for guests that need lowest possible latency,
and in between these guests it is possible to guarantee good enough level of
fairness in my driver.
For example, in the current implementation of my driver, each guest gets its own
host submission queue.

On the other hand, the host assigned partitions are for significantly higher
latency IO, with no guarantees, and/or for guests that need all the more
advanced features of full IO virtualization, for instance snapshots, thin
provisioning, replication/backup over network, etc.
io_uring can be used here to speed things up but it won't reach the nvme-mdev
levels of latency.

Furthermore on NVME drives that support WRRU, its possible to let queues of
guest's assigned partitions to belong to the high priority class and let the
host queues use the regular medium/low priority class.
For drives that don't support WRRU, the IO throttling can be done in software on
the host queues.

Host assigned partitions also don't need polling, thus allowing polling to be
used only for guests that actually need low latency IO.
This reduces the number of cores that would be otherwise lost to polling,
because the less work the polling core does, the less latency it contributes to
overall latency, thus with less users, you could use less cores to achieve the
same levels of latency.

For Stefan's argument, we can look at it in a slightly different way too:
While the nvme-mdev can be seen as a duplication of SPDK, the SPDK can also be
seen as duplication of an existing kernel functionality which nvme-mdev can
reuse for free.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-22  7:54               ` Felipe Franciosi
@ 2019-03-22 15:30                 ` Keith Busch
  -1 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-22 15:30 UTC (permalink / raw)


On Fri, Mar 22, 2019@07:54:50AM +0000, Felipe Franciosi wrote:
> > 
> > Note though that SPDK doesn't support sharing the device between host and the
> > guests, it takes over the nvme device, thus it makes the kernel nvme driver
> > unbind from it.
> 
> That is absolutely true. However, I find it not to be a problem in practice.
> 
> Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.

I don't know, it sounds like you've traded kernel syscalls for IPC,
and I don't think one performs better than the other.

> For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.

NVMe's IO Determinism features provide fine grained control for shared
devices. It's still uncommon to find hardware supporting that, though.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-22 15:30                 ` Keith Busch
  0 siblings, 0 replies; 409+ messages in thread
From: Keith Busch @ 2019-03-22 15:30 UTC (permalink / raw)
  To: Felipe Franciosi
  Cc: Maxim Levitsky, Stefan Hajnoczi, Fam Zheng, kvm@vger.kernel.org,
	Wolfram Sang, linux-nvme@lists.infradead.org,
	linux-kernel@vger.kernel.org, Keith Busch, Kirti Wankhede,
	Mauro Carvalho Chehab, Paul E . McKenney, Christoph Hellwig,
	Sagi Grimberg, Harris, James R, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos

On Fri, Mar 22, 2019 at 07:54:50AM +0000, Felipe Franciosi wrote:
> > 
> > Note though that SPDK doesn't support sharing the device between host and the
> > guests, it takes over the nvme device, thus it makes the kernel nvme driver
> > unbind from it.
> 
> That is absolutely true. However, I find it not to be a problem in practice.
> 
> Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.

I don't know, it sounds like you've traded kernel syscalls for IPC,
and I don't think one performs better than the other.

> For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.

NVMe's IO Determinism features provide fine grained control for shared
devices. It's still uncommon to find hardware supporting that, though.

^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
  2019-03-22 15:30                 ` Keith Busch
@ 2019-03-25 15:44                   ` Felipe Franciosi
  -1 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-25 15:44 UTC (permalink / raw)


Hi Keith,

> On Mar 22, 2019,@3:30 PM, Keith Busch <kbusch@kernel.org> wrote:
> 
> On Fri, Mar 22, 2019@07:54:50AM +0000, Felipe Franciosi wrote:
>>> 
>>> Note though that SPDK doesn't support sharing the device between host and the
>>> guests, it takes over the nvme device, thus it makes the kernel nvme driver
>>> unbind from it.
>> 
>> That is absolutely true. However, I find it not to be a problem in practice.
>> 
>> Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.
> 
> I don't know, it sounds like you've traded kernel syscalls for IPC,
> and I don't think one performs better than the other.

Sorry, I'm not sure I understand. My point is that if you are packaging a distro to be a hypervisor and you want to use a storage device for VM data, you _most likely_ won't be using that device for anything else. To that end, driving the device directly from your application definitely gives you more deterministic control.

> 
>> For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.
> 
> NVMe's IO Determinism features provide fine grained control for shared
> devices. It's still uncommon to find hardware supporting that, though.

Sure, but then your hypervisor needs to certify devices that support that. This will limit your HCL. Moreover, unless the feature is solid, well-established and works reliably on all devices you support, it's arguably preferable to have an architecture which gives you that control in software.

Cheers,
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re:
@ 2019-03-25 15:44                   ` Felipe Franciosi
  0 siblings, 0 replies; 409+ messages in thread
From: Felipe Franciosi @ 2019-03-25 15:44 UTC (permalink / raw)
  To: Keith Busch
  Cc: Maxim Levitsky, Stefan Hajnoczi, Fam Zheng, kvm@vger.kernel.org,
	Wolfram Sang, linux-nvme@lists.infradead.org,
	linux-kernel@vger.kernel.org, Keith Busch, Kirti Wankhede,
	Mauro Carvalho Chehab, Paul E . McKenney, Christoph Hellwig,
	Sagi Grimberg, Harris, James R, Liang Cunming, Jens Axboe,
	Alex Williamson, Thanos Makatos

Hi Keith,

> On Mar 22, 2019, at 3:30 PM, Keith Busch <kbusch@kernel.org> wrote:
> 
> On Fri, Mar 22, 2019 at 07:54:50AM +0000, Felipe Franciosi wrote:
>>> 
>>> Note though that SPDK doesn't support sharing the device between host and the
>>> guests, it takes over the nvme device, thus it makes the kernel nvme driver
>>> unbind from it.
>> 
>> That is absolutely true. However, I find it not to be a problem in practice.
>> 
>> Hypervisor products, specially those caring about performance, efficiency and fairness, will dedicate NVMe devices for a particular purpose (eg. vDisk storage, cache, metadata) and will not share these devices for other use cases. That's because these products want to deterministically control the performance aspects of the device, which you just cannot do if you are sharing the device with a subsystem you do not control.
> 
> I don't know, it sounds like you've traded kernel syscalls for IPC,
> and I don't think one performs better than the other.

Sorry, I'm not sure I understand. My point is that if you are packaging a distro to be a hypervisor and you want to use a storage device for VM data, you _most likely_ won't be using that device for anything else. To that end, driving the device directly from your application definitely gives you more deterministic control.

> 
>> For scenarios where the device must be shared and such fine grained control is not required, it looks like using the kernel driver with io_uring offers very good performance with flexibility.
> 
> NVMe's IO Determinism features provide fine grained control for shared
> devices. It's still uncommon to find hardware supporting that, though.

Sure, but then your hypervisor needs to certify devices that support that. This will limit your HCL. Moreover, unless the feature is solid, well-established and works reliably on all devices you support, it's arguably preferable to have an architecture which gives you that control in software.

Cheers,
Felipe

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-21 17:07     ` Maxim Levitsky
@ 2019-03-25 16:46       ` Stefan Hajnoczi
  -1 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-25 16:46 UTC (permalink / raw)


On Thu, Mar 21, 2019@07:07:38PM +0200, Maxim Levitsky wrote:
> On Thu, 2019-03-21@16:13 +0000, Stefan Hajnoczi wrote:
> > On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> > > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > > 
> > > Hi everyone!
> > > 
> > > In this patch series, I would like to introduce my take on the problem of
> > > doing 
> > > as fast as possible virtualization of storage with emphasis on low latency.
> > > 
> > > In this patch series I implemented a kernel vfio based, mediated device
> > > that 
> > > allows the user to pass through a partition and/or whole namespace to a
> > > guest.
> > > 
> > > The idea behind this driver is based on paper you can find at
> > > https://www.usenix.org/conference/atc18/presentation/peng,
> > > 
> > > Although note that I stared the development prior to reading this paper, 
> > > independently.
> > > 
> > > In addition to that implementation is not based on code used in the paper
> > > as 
> > > I wasn't being able at that time to make the source available to me.
> > > 
> > > ***Key points about the implementation:***
> > > 
> > > * Polling kernel thread is used. The polling is stopped after a 
> > > predefined timeout (1/2 sec by default).
> > > Support for all interrupt driven mode is planned, and it shows promising
> > > results.
> > > 
> > > * Guest sees a standard NVME device - this allows to run guest with 
> > > unmodified drivers, for example windows guests.
> > > 
> > > * The NVMe device is shared between host and guest.
> > > That means that even a single namespace can be split between host 
> > > and guest based on different partitions.
> > > 
> > > * Simple configuration
> > > 
> > > *** Performance ***
> > > 
> > > Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> > > and both latency and throughput is very similar to SPDK.
> > > 
> > > Soon I will test this on a better server and nvme device and provide
> > > more formal performance numbers.
> > > 
> > > Latency numbers:
> > > ~80ms - spdk with fio plugin on the host.
> > > ~84ms - nvme driver on the host
> > > ~87ms - mdev-nvme + nvme driver in the guest
> > 
> > You mentioned the spdk numbers are with vhost-user-nvme.  Have you
> > measured SPDK's vhost-user-blk?
> 
> I had lot of measuments of vhost-user-blk vs vhost-user-nvme.
> vhost-user-nvme was always a bit faster but only a bit.
> Thus I don't think it makes sense to benchamrk against vhost-user-blk.

It's interesting because mdev-nvme is closest to the hardware while
vhost-user-blk is closest to software.  Doing things at the NVMe level
isn't buying much performance because it's still going through a
software path comparable to vhost-user-blk.


From what you say it sounds like there isn't much to optimize away :(.

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-nvme/attachments/20190325/f46e8674/attachment.sig>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-03-25 16:46       ` Stefan Hajnoczi
  0 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-25 16:46 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, linux-kernel, kvm, Jens Axboe, Alex Williamson,
	Keith Busch, Christoph Hellwig, Sagi Grimberg, Kirti Wankhede,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Wolfram Sang, Nicolas Ferre, Paul E . McKenney, Paolo Bonzini,
	Liang Cunming, Liu Changpeng, Fam Zheng, Amnon Ilan,
	John Ferlan <jfer

[-- Attachment #1: Type: text/plain, Size: 2913 bytes --]

On Thu, Mar 21, 2019 at 07:07:38PM +0200, Maxim Levitsky wrote:
> On Thu, 2019-03-21 at 16:13 +0000, Stefan Hajnoczi wrote:
> > On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> > > Date: Tue, 19 Mar 2019 14:45:45 +0200
> > > Subject: [PATCH 0/9] RFC: NVME VFIO mediated device
> > > 
> > > Hi everyone!
> > > 
> > > In this patch series, I would like to introduce my take on the problem of
> > > doing 
> > > as fast as possible virtualization of storage with emphasis on low latency.
> > > 
> > > In this patch series I implemented a kernel vfio based, mediated device
> > > that 
> > > allows the user to pass through a partition and/or whole namespace to a
> > > guest.
> > > 
> > > The idea behind this driver is based on paper you can find at
> > > https://www.usenix.org/conference/atc18/presentation/peng,
> > > 
> > > Although note that I stared the development prior to reading this paper, 
> > > independently.
> > > 
> > > In addition to that implementation is not based on code used in the paper
> > > as 
> > > I wasn't being able at that time to make the source available to me.
> > > 
> > > ***Key points about the implementation:***
> > > 
> > > * Polling kernel thread is used. The polling is stopped after a 
> > > predefined timeout (1/2 sec by default).
> > > Support for all interrupt driven mode is planned, and it shows promising
> > > results.
> > > 
> > > * Guest sees a standard NVME device - this allows to run guest with 
> > > unmodified drivers, for example windows guests.
> > > 
> > > * The NVMe device is shared between host and guest.
> > > That means that even a single namespace can be split between host 
> > > and guest based on different partitions.
> > > 
> > > * Simple configuration
> > > 
> > > *** Performance ***
> > > 
> > > Performance was tested on Intel DC P3700, With Xeon E5-2620 v2 
> > > and both latency and throughput is very similar to SPDK.
> > > 
> > > Soon I will test this on a better server and nvme device and provide
> > > more formal performance numbers.
> > > 
> > > Latency numbers:
> > > ~80ms - spdk with fio plugin on the host.
> > > ~84ms - nvme driver on the host
> > > ~87ms - mdev-nvme + nvme driver in the guest
> > 
> > You mentioned the spdk numbers are with vhost-user-nvme.  Have you
> > measured SPDK's vhost-user-blk?
> 
> I had lot of measuments of vhost-user-blk vs vhost-user-nvme.
> vhost-user-nvme was always a bit faster but only a bit.
> Thus I don't think it makes sense to benchamrk against vhost-user-blk.

It's interesting because mdev-nvme is closest to the hardware while
vhost-user-blk is closest to software.  Doing things at the NVMe level
isn't buying much performance because it's still going through a
software path comparable to vhost-user-blk.

From what you say it sounds like there isn't much to optimize away :(.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
  2019-03-19 14:58   ` Maxim Levitsky
@ 2019-03-25 18:52     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-25 18:52 UTC (permalink / raw)


Hi

This is first round of benchmarks.

The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz

The system has 2 numa nodes, but only cpus and memory from node 0 were used to
avoid noise from numa.

The SSD is Intel? Optane? SSD 900P Series, 280 GB version


https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html


** Latency benchmark with no interrupts at all **

spdk was complited with fio plugin in the host and in the guest.
spdk was first run in the host
then vm was started with one of spdk,pci passthrough, mdev and inside the
vm spdk was run with fio plugin.

spdk was taken from my branch on gitlab, and fio was complied from source for
3.4 branch as needed by the spdk fio plugin.

The following spdk command line was used:

$WORK/fio/fio \
	--name=job --runtime=40 --ramp_time=0 --time_based \
	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
	--iodepth=1 --thread

The average values for slat (submission latency), clat (completion latency) and
its sum (slat+clat) were noted.

The results:

spdk fio host: 
	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms


pci passthough host/
spdk fio guest
	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms

spdk host/
spdk fio guest:
	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms

mdev host/
spdk fio guest:
	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms


As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.

In addtion to that I added few 'rdtsc' into my mdev driver to strategically
capture the cycle count it takes it to do 3 things:

1. translate a just received command (till it is copied to the hardware
submission queue)

2. receive a completion (divided by the number of completion received in one
round of polling)

3. deliver an interupt to the guest (call to eventfd_signal)

This is not the whole latency as there is also a latency between the point the
submission entry is written and till it is visible on the polling cpu, plus
latency till polling cpu gets to the code which reads the submission entry,
and of course latency of interrupt delivery, but the above measurements mostly
capture the latency I can control.

The results are:

commands translated : avg cycles: 459.844     avg time(usec): 0.135        
commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174

avg time total: 0.413 usec

All measurmenets done in the host kernel. the time calculated using tsc_khz
kernel variable.

The biggest take from this is that both spdk and my driver are very fast and
overhead is just a  thousand of cpu cycles give it or take.

*** Throughput benchmarks ***

https://paste.fedoraproject.org/paste/ecijclLMG2B11MVCVIst-w

Here you can find the throughput benchmarks.

The biggest take is that when using no interrupts (spdk fio in guest or spdk fio
in host), the bottelneck is in the device, and througput is about 2290 Mib/s

And mdev vs spdk, with interrupts, my driver sligly wins by giving throughput of
about 2015 Mib/s while spdk is about 2005 Mib/s
mostly due to slightly different timings as the latency of both is about the
same.

Disabling meltdown mitigation didn't had much effect on the performance.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
@ 2019-03-25 18:52     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-25 18:52 UTC (permalink / raw)
  To: linux-nvme
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, Wolfram Sang,
	Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre, linux-kernel,
	Kirti Wankhede, David S . Miller, Jens Axboe, Alex Williamson,
	John Ferlan, Mauro Carvalho Chehab, Paolo Bonzini, Liu Changpeng,
	Paul E . McKenney, Amnon Ilan, Christoph Hellwig

Hi

This is first round of benchmarks.

The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz

The system has 2 numa nodes, but only cpus and memory from node 0 were used to
avoid noise from numa.

The SSD is Intel® Optane™ SSD 900P Series, 280 GB version


https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html


** Latency benchmark with no interrupts at all **

spdk was complited with fio plugin in the host and in the guest.
spdk was first run in the host
then vm was started with one of spdk,pci passthrough, mdev and inside the
vm spdk was run with fio plugin.

spdk was taken from my branch on gitlab, and fio was complied from source for
3.4 branch as needed by the spdk fio plugin.

The following spdk command line was used:

$WORK/fio/fio \
	--name=job --runtime=40 --ramp_time=0 --time_based \
	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
	--iodepth=1 --thread

The average values for slat (submission latency), clat (completion latency) and
its sum (slat+clat) were noted.

The results:

spdk fio host: 
	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms


pci passthough host/
spdk fio guest
	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms

spdk host/
spdk fio guest:
	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms

mdev host/
spdk fio guest:
	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms


As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.

In addtion to that I added few 'rdtsc' into my mdev driver to strategically
capture the cycle count it takes it to do 3 things:

1. translate a just received command (till it is copied to the hardware
submission queue)

2. receive a completion (divided by the number of completion received in one
round of polling)

3. deliver an interupt to the guest (call to eventfd_signal)

This is not the whole latency as there is also a latency between the point the
submission entry is written and till it is visible on the polling cpu, plus
latency till polling cpu gets to the code which reads the submission entry,
and of course latency of interrupt delivery, but the above measurements mostly
capture the latency I can control.

The results are:

commands translated : avg cycles: 459.844     avg time(usec): 0.135        
commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174

avg time total: 0.413 usec

All measurmenets done in the host kernel. the time calculated using tsc_khz
kernel variable.

The biggest take from this is that both spdk and my driver are very fast and
overhead is just a  thousand of cpu cycles give it or take.

*** Throughput benchmarks ***

https://paste.fedoraproject.org/paste/ecijclLMG2B11MVCVIst-w

Here you can find the throughput benchmarks.

The biggest take is that when using no interrupts (spdk fio in guest or spdk fio
in host), the bottelneck is in the device, and througput is about 2290 Mib/s

And mdev vs spdk, with interrupts, my driver sligly wins by giving throughput of
about 2015 Mib/s while spdk is about 2005 Mib/s
mostly due to slightly different timings as the latency of both is about the
same.

Disabling meltdown mitigation didn't had much effect on the performance.

Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
  2019-03-25 18:52     ` Maxim Levitsky
@ 2019-03-26  9:38       ` Stefan Hajnoczi
  -1 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-26  9:38 UTC (permalink / raw)


On Mon, Mar 25, 2019@08:52:32PM +0200, Maxim Levitsky wrote:
> Hi
> 
> This is first round of benchmarks.
> 
> The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz
> 
> The system has 2 numa nodes, but only cpus and memory from node 0 were used to
> avoid noise from numa.
> 
> The SSD is Intel? Optane? SSD 900P Series, 280 GB version
> 
> 
> https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html
> 
> 
> ** Latency benchmark with no interrupts at all **
> 
> spdk was complited with fio plugin in the host and in the guest.
> spdk was first run in the host
> then vm was started with one of spdk,pci passthrough, mdev and inside the
> vm spdk was run with fio plugin.
> 
> spdk was taken from my branch on gitlab, and fio was complied from source for
> 3.4 branch as needed by the spdk fio plugin.
> 
> The following spdk command line was used:
> 
> $WORK/fio/fio \
> 	--name=job --runtime=40 --ramp_time=0 --time_based \
> 	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
> 	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
> 	--iodepth=1 --thread
> 
> The average values for slat (submission latency), clat (completion latency) and
> its sum (slat+clat) were noted.
> 
> The results:
> 
> spdk fio host: 
> 	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
> 	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms
> 
> 
> pci passthough host/
> spdk fio guest
> 	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
> 	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
> 	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms
> 
> spdk host/
> spdk fio guest:
> 	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
> 	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
> 	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms
> 
> mdev host/
> spdk fio guest:
> 	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
> 	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
> 	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms
> 
> 
> As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
> while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.

Milliseconds is surprising.  The SSD's spec says 10us read/write
latency.  Did you mean microseconds?

> 
> In addtion to that I added few 'rdtsc' into my mdev driver to strategically
> capture the cycle count it takes it to do 3 things:
> 
> 1. translate a just received command (till it is copied to the hardware
> submission queue)
> 
> 2. receive a completion (divided by the number of completion received in one
> round of polling)
> 
> 3. deliver an interupt to the guest (call to eventfd_signal)
> 
> This is not the whole latency as there is also a latency between the point the
> submission entry is written and till it is visible on the polling cpu, plus
> latency till polling cpu gets to the code which reads the submission entry,
> and of course latency of interrupt delivery, but the above measurements mostly
> capture the latency I can control.
> 
> The results are:
> 
> commands translated : avg cycles: 459.844     avg time(usec): 0.135        
> commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
> interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174
> 
> avg time total: 0.413 usec
> 
> All measurmenets done in the host kernel. the time calculated using tsc_khz
> kernel variable.
> 
> The biggest take from this is that both spdk and my driver are very fast and
> overhead is just a  thousand of cpu cycles give it or take.

Nice!

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-nvme/attachments/20190326/4cc00df9/attachment.sig>

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
@ 2019-03-26  9:38       ` Stefan Hajnoczi
  0 siblings, 0 replies; 409+ messages in thread
From: Stefan Hajnoczi @ 2019-03-26  9:38 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: linux-nvme, Fam Zheng, Keith Busch, Sagi Grimberg, kvm,
	Wolfram Sang, Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre,
	linux-kernel, Kirti Wankhede, David S . Miller, Jens Axboe,
	Alex Williamson, John Ferlan, Mauro Carvalho Chehab,
	Paolo Bonzini, Liu Changpeng, Paul E . McKenney, Amnon Ilan,
	Christoph 

[-- Attachment #1: Type: text/plain, Size: 3718 bytes --]

On Mon, Mar 25, 2019 at 08:52:32PM +0200, Maxim Levitsky wrote:
> Hi
> 
> This is first round of benchmarks.
> 
> The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz
> 
> The system has 2 numa nodes, but only cpus and memory from node 0 were used to
> avoid noise from numa.
> 
> The SSD is Intel® Optane™ SSD 900P Series, 280 GB version
> 
> 
> https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html
> 
> 
> ** Latency benchmark with no interrupts at all **
> 
> spdk was complited with fio plugin in the host and in the guest.
> spdk was first run in the host
> then vm was started with one of spdk,pci passthrough, mdev and inside the
> vm spdk was run with fio plugin.
> 
> spdk was taken from my branch on gitlab, and fio was complied from source for
> 3.4 branch as needed by the spdk fio plugin.
> 
> The following spdk command line was used:
> 
> $WORK/fio/fio \
> 	--name=job --runtime=40 --ramp_time=0 --time_based \
> 	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
> 	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
> 	--iodepth=1 --thread
> 
> The average values for slat (submission latency), clat (completion latency) and
> its sum (slat+clat) were noted.
> 
> The results:
> 
> spdk fio host: 
> 	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
> 	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms
> 
> 
> pci passthough host/
> spdk fio guest
> 	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
> 	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
> 	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms
> 
> spdk host/
> spdk fio guest:
> 	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
> 	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
> 	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms
> 
> mdev host/
> spdk fio guest:
> 	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
> 	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
> 	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms
> 
> 
> As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
> while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.

Milliseconds is surprising.  The SSD's spec says 10us read/write
latency.  Did you mean microseconds?

> 
> In addtion to that I added few 'rdtsc' into my mdev driver to strategically
> capture the cycle count it takes it to do 3 things:
> 
> 1. translate a just received command (till it is copied to the hardware
> submission queue)
> 
> 2. receive a completion (divided by the number of completion received in one
> round of polling)
> 
> 3. deliver an interupt to the guest (call to eventfd_signal)
> 
> This is not the whole latency as there is also a latency between the point the
> submission entry is written and till it is visible on the polling cpu, plus
> latency till polling cpu gets to the code which reads the submission entry,
> and of course latency of interrupt delivery, but the above measurements mostly
> capture the latency I can control.
> 
> The results are:
> 
> commands translated : avg cycles: 459.844     avg time(usec): 0.135        
> commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
> interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174
> 
> avg time total: 0.413 usec
> 
> All measurmenets done in the host kernel. the time calculated using tsc_khz
> kernel variable.
> 
> The biggest take from this is that both spdk and my driver are very fast and
> overhead is just a  thousand of cpu cycles give it or take.

Nice!

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 409+ messages in thread

* [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
  2019-03-26  9:38       ` Stefan Hajnoczi
@ 2019-03-26  9:50         ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-26  9:50 UTC (permalink / raw)


On Tue, 2019-03-26@09:38 +0000, Stefan Hajnoczi wrote:
> On Mon, Mar 25, 2019@08:52:32PM +0200, Maxim Levitsky wrote:
> > Hi
> > 
> > This is first round of benchmarks.
> > 
> > The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz
> > 
> > The system has 2 numa nodes, but only cpus and memory from node 0 were used to
> > avoid noise from numa.
> > 
> > The SSD is Intel? Optane? SSD 900P Series, 280 GB version
> > 
> > 
> > https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html
> > 
> > 
> > ** Latency benchmark with no interrupts at all **
> > 
> > spdk was complited with fio plugin in the host and in the guest.
> > spdk was first run in the host
> > then vm was started with one of spdk,pci passthrough, mdev and inside the
> > vm spdk was run with fio plugin.
> > 
> > spdk was taken from my branch on gitlab, and fio was complied from source for
> > 3.4 branch as needed by the spdk fio plugin.
> > 
> > The following spdk command line was used:
> > 
> > $WORK/fio/fio \
> > 	--name=job --runtime=40 --ramp_time=0 --time_based \
> > 	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
> > 	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
> > 	--iodepth=1 --thread
> > 
> > The average values for slat (submission latency), clat (completion latency) and
> > its sum (slat+clat) were noted.
> > 
> > The results:
> > 
> > spdk fio host: 
> > 	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
> > 	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms
> > 
> > 
> > pci passthough host/
> > spdk fio guest
> > 	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
> > 	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
> > 	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms
> > 
> > spdk host/
> > spdk fio guest:
> > 	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
> > 	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
> > 	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms
> > 
> > mdev host/
> > spdk fio guest:
> > 	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
> > 	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
> > 	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms
> > 
> > 
> > As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
> > while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.
> 
> Milliseconds is surprising.  The SSD's spec says 10us read/write
> latency.  Did you mean microseconds?
Yea, this is typo - all of this is microseconds.


> 
> > 
> > In addtion to that I added few 'rdtsc' into my mdev driver to strategically
> > capture the cycle count it takes it to do 3 things:
> > 
> > 1. translate a just received command (till it is copied to the hardware
> > submission queue)
> > 
> > 2. receive a completion (divided by the number of completion received in one
> > round of polling)
> > 
> > 3. deliver an interupt to the guest (call to eventfd_signal)
> > 
> > This is not the whole latency as there is also a latency between the point the
> > submission entry is written and till it is visible on the polling cpu, plus
> > latency till polling cpu gets to the code which reads the submission entry,
> > and of course latency of interrupt delivery, but the above measurements mostly
> > capture the latency I can control.
> > 
> > The results are:
> > 
> > commands translated : avg cycles: 459.844     avg time(usec): 0.135        
> > commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
> > interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174
> > 
> > avg time total: 0.413 usec
> > 
> > All measurmenets done in the host kernel. the time calculated using tsc_khz
> > kernel variable.
> > 
> > The biggest take from this is that both spdk and my driver are very fast and
> > overhead is just a  thousand of cpu cycles give it or take.
> 
> Nice!
> 
> Stefan


Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS]
@ 2019-03-26  9:50         ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-03-26  9:50 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: linux-nvme, Fam Zheng, Keith Busch, Sagi Grimberg, kvm,
	Wolfram Sang, Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre,
	linux-kernel, Kirti Wankhede, David S . Miller, Jens Axboe,
	Alex Williamson, John Ferlan, Mauro Carvalho Chehab,
	Paolo Bonzini, Liu Changpeng, Paul E . McKenney, Amnon Ilan,
	Christoph 

On Tue, 2019-03-26 at 09:38 +0000, Stefan Hajnoczi wrote:
> On Mon, Mar 25, 2019 at 08:52:32PM +0200, Maxim Levitsky wrote:
> > Hi
> > 
> > This is first round of benchmarks.
> > 
> > The system is Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz
> > 
> > The system has 2 numa nodes, but only cpus and memory from node 0 were used to
> > avoid noise from numa.
> > 
> > The SSD is Intel® Optane™ SSD 900P Series, 280 GB version
> > 
> > 
> > https://ark.intel.com/content/www/us/en/ark/products/123628/intel-optane-ssd-900p-series-280gb-1-2-height-pcie-x4-20nm-3d-xpoint.html
> > 
> > 
> > ** Latency benchmark with no interrupts at all **
> > 
> > spdk was complited with fio plugin in the host and in the guest.
> > spdk was first run in the host
> > then vm was started with one of spdk,pci passthrough, mdev and inside the
> > vm spdk was run with fio plugin.
> > 
> > spdk was taken from my branch on gitlab, and fio was complied from source for
> > 3.4 branch as needed by the spdk fio plugin.
> > 
> > The following spdk command line was used:
> > 
> > $WORK/fio/fio \
> > 	--name=job --runtime=40 --ramp_time=0 --time_based \
> > 	 --filename="trtype=PCIe traddr=$DEVICE_FOR_FIO ns=1" --ioengine=spdk  \
> > 	--direct=1 --rw=randread --bs=4K --cpus_allowed=0 \
> > 	--iodepth=1 --thread
> > 
> > The average values for slat (submission latency), clat (completion latency) and
> > its sum (slat+clat) were noted.
> > 
> > The results:
> > 
> > spdk fio host: 
> > 	573 Mib/s - slat 112.00ns, clat 6.400us, lat 6.52ms
> > 	573 Mib/s - slat 111.50ns, clat 6.406us, lat 6.52ms
> > 
> > 
> > pci passthough host/
> > spdk fio guest
> > 	571 Mib/s - slat 124.56ns, clat 6.422us  lat 6.55ms
> > 	571 Mib/s - slat 122.86ns, clat 6.410us  lat 6.53ms
> > 	570 Mib/s - slat 124.95ns, clat 6.425us  lat 6.55ms
> > 
> > spdk host/
> > spdk fio guest:
> > 	535 Mib/s - slat 125.00ns, clat 6.895us  lat 7.02ms
> > 	534 Mib/s - slat 125.36ns, clat 6.896us  lat 7.02ms
> > 	534 Mib/s - slat 125.82ns, clat 6.892us  lat 7.02ms
> > 
> > mdev host/
> > spdk fio guest:
> > 	534 Mib/s - slat 128.04ns, clat 6.902us  lat 7.03ms
> > 	535 Mib/s - slat 126.97ns, clat 6.900us  lat 7.03ms
> > 	535 Mib/s - slat 127.00ns, clat 6.898us  lat 7.03ms
> > 
> > 
> > As you see, native latency is 6.52ms, pci passthrough barely adds any latency,
> > while both mdev/spdk added about (7.03/2 - 6.52) - 0.51ms/0.50ms of latency.
> 
> Milliseconds is surprising.  The SSD's spec says 10us read/write
> latency.  Did you mean microseconds?
Yea, this is typo - all of this is microseconds.


> 
> > 
> > In addtion to that I added few 'rdtsc' into my mdev driver to strategically
> > capture the cycle count it takes it to do 3 things:
> > 
> > 1. translate a just received command (till it is copied to the hardware
> > submission queue)
> > 
> > 2. receive a completion (divided by the number of completion received in one
> > round of polling)
> > 
> > 3. deliver an interupt to the guest (call to eventfd_signal)
> > 
> > This is not the whole latency as there is also a latency between the point the
> > submission entry is written and till it is visible on the polling cpu, plus
> > latency till polling cpu gets to the code which reads the submission entry,
> > and of course latency of interrupt delivery, but the above measurements mostly
> > capture the latency I can control.
> > 
> > The results are:
> > 
> > commands translated : avg cycles: 459.844     avg time(usec): 0.135        
> > commands completed  : avg cycles: 354.61      avg time(usec): 0.104        
> > interrupts sent     : avg cycles: 590.227     avg time(usec): 0.174
> > 
> > avg time total: 0.413 usec
> > 
> > All measurmenets done in the host kernel. the time calculated using tsc_khz
> > kernel variable.
> > 
> > The biggest take from this is that both spdk and my driver are very fast and
> > overhead is just a  thousand of cpu cycles give it or take.
> 
> Nice!
> 
> Stefan


Best regards,
	Maxim Levitsky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* your mail
  2019-03-19 15:22   ` Keith Busch
@ 2019-04-08 10:04     ` Maxim Levitsky
  -1 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-04-08 10:04 UTC (permalink / raw)


On Tue, 2019-03-19@09:22 -0600, Keith Busch wrote:
> On Tue, Mar 19, 2019@04:41:07PM +0200, Maxim Levitsky wrote:
> >   -> Share the NVMe device between host and guest. 
> >      Even in fully virtualized configurations,
> >      some partitions of nvme device could be used by guests as block
> > devices 
> >      while others passed through with nvme-mdev to achieve balance between
> >      all features of full IO stack emulation and performance.
> >   
> >   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
> >      can send interrupts to the guest directly without a context 
> >      switch that can be expensive due to meltdown mitigation.
> > 
> >   -> Is able to utilize interrupts to get reasonable performance. 
> >      This is only implemented
> >      as a proof of concept and not included in the patches, 
> >      but interrupt driven mode shows reasonable performance
> >      
> >   -> This is a framework that later can be used to support NVMe devices 
> >      with more of the IO virtualization built-in 
> >      (IOMMU with PASID support coupled with device that supports it)
> 
> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.
> 
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
> 
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).


Hi!

Sorry to bother you, but any update?

I was somewhat sick for the last week, now finally back in shape to continue
working on this and other tasks I have.

I am studing now the nvme target code and the io_uring to evaluate the
difficultiy of using something similiar to talk to the block device instead of /
in addtion to the  direct connection I implemented.

I would be glad to hear more feedback on this project.

I will also soon post the few fixes separately as you suggested.

Best regards,
    Maxim Levitskky

^ permalink raw reply	[flat|nested] 409+ messages in thread

* Re: your mail
@ 2019-04-08 10:04     ` Maxim Levitsky
  0 siblings, 0 replies; 409+ messages in thread
From: Maxim Levitsky @ 2019-04-08 10:04 UTC (permalink / raw)
  To: Keith Busch
  Cc: Fam Zheng, Keith Busch, Sagi Grimberg, kvm, Wolfram Sang,
	Greg Kroah-Hartman, Liang Cunming, Nicolas Ferre, linux-kernel,
	linux-nvme, David S . Miller, Jens Axboe, Alex Williamson,
	Kirti Wankhede, Mauro Carvalho Chehab, Paolo Bonzini,
	Liu Changpeng, Paul E . McKenney, Amnon Ilan, Christoph Hellwig,
	John Ferlan

On Tue, 2019-03-19 at 09:22 -0600, Keith Busch wrote:
> On Tue, Mar 19, 2019 at 04:41:07PM +0200, Maxim Levitsky wrote:
> >   -> Share the NVMe device between host and guest. 
> >      Even in fully virtualized configurations,
> >      some partitions of nvme device could be used by guests as block
> > devices 
> >      while others passed through with nvme-mdev to achieve balance between
> >      all features of full IO stack emulation and performance.
> >   
> >   -> NVME-MDEV is a bit faster due to the fact that in-kernel driver 
> >      can send interrupts to the guest directly without a context 
> >      switch that can be expensive due to meltdown mitigation.
> > 
> >   -> Is able to utilize interrupts to get reasonable performance. 
> >      This is only implemented
> >      as a proof of concept and not included in the patches, 
> >      but interrupt driven mode shows reasonable performance
> >      
> >   -> This is a framework that later can be used to support NVMe devices 
> >      with more of the IO virtualization built-in 
> >      (IOMMU with PASID support coupled with device that supports it)
> 
> Would be very interested to see the PASID support. You wouldn't even
> need to mediate the IO doorbells or translations if assigning entire
> namespaces, and should be much faster than the shadow doorbells.
> 
> I think you should send 6/9 "nvme/pci: init shadow doorbell after each
> reset" separately for immediate inclusion.
> 
> I like the idea in principle, but it will take me a little time to get
> through reviewing your implementation. I would have guessed we could
> have leveraged something from the existing nvme/target for the mediating
> controller register access and admin commands. Maybe even start with
> implementing an nvme passthrough namespace target type (we currently
> have block and file).


Hi!

Sorry to bother you, but any update?

I was somewhat sick for the last week, now finally back in shape to continue
working on this and other tasks I have.

I am studing now the nvme target code and the io_uring to evaluate the
difficultiy of using something similiar to talk to the block device instead of /
in addtion to the  direct connection I implemented.

I would be glad to hear more feedback on this project.

I will also soon post the few fixes separately as you suggested.

Best regards,
    Maxim Levitskky





^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2019-08-21 15:45 Ivan Mikhaylov
  0 siblings, 0 replies; 409+ messages in thread
From: Ivan Mikhaylov @ 2019-08-21 15:45 UTC (permalink / raw)
  To: linux-aspeed

From 1687adb615ceb7a4013712604f177dc906059667 Mon Sep 17 00:00:00 2001
From: Ivan Mikhaylov <i.mikhaylov@yadro.com>
Date: Wed, 21 Aug 2019 18:21:05 +
Subject: [PATCH 0/3] add dual-boot support

ASPEED SoCs support dual-boot feature for SPI Flash.
When strapped appropriately, the SoC starts wdt2 (/dev/watchdog1)
and if within a minute it is not disabled, it goes off and reboots
the SoC from an alternate SPI Flash chip by changing CS0 controls
to actually drive CS1 line.

When booted from alternate chip, in order to access the main chip
at CS0, the user must reset the appropriate bit in the watchdog
hardware. There is no interface that would allow to do that from
an embedded firmware startup script.

This commit implements support for that feature:

* Enable 'alt-boot' option for wdt2

* Enable secondary SPI flash chip

* Make it possible to get access to the primary SPI flash chip at CS0
  after booting from the alternate chip at CS1. A sysfs interface is added
  to provide an easy way for embedded firmware startup scripts to clear
  the chip select bit to gain access to the primary flash chip in order
  to allow for recovery of its contents.

Ivan Mikhaylov (3):
  vesnin: add wdt2 section with alt-boot option
  vesnin: add secondary SPI flash chip
  watchdog/aspeed: add support for dual boot

 arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 12 +++++++++
 drivers/watchdog/aspeed_wdt.c               | 30 +++++++++++++++++++++
 2 files changed, 42 insertions(+)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2022-06-21  9:06 ventas
  0 siblings, 0 replies; 409+ messages in thread
From: ventas @ 2022-06-21  9:06 UTC (permalink / raw)
  To: barebox

Hi!

I'm going to make you an offer you can't refuse. If reputation means anything to you.
I am a programmer who likes to dig into other people's dirty laundry and I hack into cell phones, laptops, computers, tablets of users like you in order to extract from them "interesting" photos, videos, recordings of conversations or correspondence.

I infected your device with a virus and have been watching you for over 2 months now. 
During these months, I have accumulated a lot of interesting information about you.
Not only do I have access to your phone book, correspondence, audio, but I also have information about the sites you visit. Can you guess what I'm talking about?

I collect a selection of photos and videos, audio recordings, correspondence from the devices of users like you with the help of viruses and copy them to my own server.
 
I've got some bad news for you. I can leak all of this online for general access, send it to your friends, relatives, acquaintances, send it to social networks and messengers. 
Trust me. This is something that can destroy your reputation once and for all!
The effect will be fantastic! They will see what you do in all its glory. It only takes one click for me to leak the information.
You have the power to stop it. 
What do you have to do to stop it? I'll tell you about that next.

You need to make a $1300 (US dollars) transfer to my bitcoin wallet. If you do not know how such transfers are made, just type in Google query: "Buy Bitcoin".
My bitcoin wallet (BTC Wallet): bc1q9zquts6kn9zm 9mxr4n06hwjqfxns05sex8nehj (without space in wallet)
Nothing complicated, right? 
After receiving the specified amount, I will immediately delete all the information and leave you alone forever!
But you need to hurry up. I don't like to wait long!
I'll give you 48 hours.
Don't think you can ignore me. After you read this message, I automatically get a notification about it. 
>From then on, you have two days to pay!
Yes. You don't need to try to apply for help to resolve this situation. Bitcoin wallet is untraceable, and the sender address is automatically created.
But if I happen to know that you share this email with someone else (and I will), I'll do a newsletter right away!
I hope you make the right choice!




^ permalink raw reply	[flat|nested] 409+ messages in thread

* No subject
@ 2023-08-31  7:20 Peter Yin
  0 siblings, 0 replies; 409+ messages in thread
From: Peter Yin @ 2023-08-31  7:20 UTC (permalink / raw)
  To: linux-aspeed

Subject: [PATCH v6 0/2] *** Add Facebook Minerva (AST2600) BMC ***

v1 link : https://lore.kernel.org/all/fb09f5e6-8381-312f-2f1e-f2b471cec68a at linaro.org/
v2 link : https://lore.kernel.org/lkml/9f499fe5-db59-f4c8-6a50-93725b7287fd at linaro.org/
v3 link : https://lore.kernel.org/lkml/20230830025133.3756506-1-peteryin.openbmc at gmail.com/
v4 link : https://lore.kernel.org/all/1d531692-5455-fbfd-0775-50856bf0fbc7 at linaro.org/
v5 link : https://lore.kernel.org/all/5347163b-c225-d805-d851-fe28e6b57c56 at gmail.com/

Change log:
v6: 1.Correcting the arrangement order in Makefile.

v5: 1.remove redundant blank line.
    2.Correcting the arrangement order in document.

v4:
    1.seprate dts document.

v3:
    1.Fixed commit description.
    2.Add sgpio line name to sgpioP.
    3.Add ipmb debug card bus.

v2:
    1.Add facebook,minerva-bmc in aspeed.yaml
    2.Use stdout-path
    3.Add Makefile

v1:
    1. Create minerva dts file.
*** BLURB HERE ***

Peter Yin (2):
  ARM: dts: aspeed: Minerva: Add Facebook Minerva (AST2600) BMC
  dt-bindings: arm: aspeed: add Meta Minerva board

 .../bindings/arm/aspeed/aspeed.yaml           |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/aspeed-bmc-facebook-minerva.dts  | 377 ++++++++++++++++++
 3 files changed, 379 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-minerva.dts

-- 
2.25.1


^ permalink raw reply	[flat|nested] 409+ messages in thread

end of thread, other threads:[~2023-08-31  7:20 UTC | newest]

Thread overview: 409+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-03-19 14:41 No subject Maxim Levitsky
2019-03-19 14:41 ` (unknown) Maxim Levitsky
2019-03-19 14:41 ` [PATCH 1/9] vfio/mdev: add .request callback Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 2/9] nvme/core: add some more values from the spec Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 3/9] nvme/core: add NVME_CTRL_SUSPENDED controller state Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 4/9] nvme/pci: use the NVME_CTRL_SUSPENDED state Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-20  2:54   ` Fam Zheng
2019-03-20  2:54     ` Fam Zheng
2019-03-19 14:41 ` [PATCH 5/9] nvme/pci: add known admin effects to augument admin effects log page Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 6/9] nvme/pci: init shadow doorbell after each reset Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 7/9] nvme/core: add mdev interfaces Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-20 11:46   ` Stefan Hajnoczi
2019-03-20 11:46     ` Stefan Hajnoczi
2019-03-20 12:50     ` Maxim Levitsky
2019-03-20 12:50       ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 8/9] nvme/core: add nvme-mdev core driver Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:41 ` [PATCH 9/9] nvme/pci: implement the mdev external queue allocation interface Maxim Levitsky
2019-03-19 14:41   ` Maxim Levitsky
2019-03-19 14:58 ` [PATCH 0/9] RFC: NVME VFIO mediated device Maxim Levitsky
2019-03-19 14:58   ` Maxim Levitsky
2019-03-25 18:52   ` [PATCH 0/9] RFC: NVME VFIO mediated device [BENCHMARKS] Maxim Levitsky
2019-03-25 18:52     ` Maxim Levitsky
2019-03-26  9:38     ` Stefan Hajnoczi
2019-03-26  9:38       ` Stefan Hajnoczi
2019-03-26  9:50       ` Maxim Levitsky
2019-03-26  9:50         ` Maxim Levitsky
2019-03-19 15:22 ` your mail Keith Busch
2019-03-19 15:22   ` Keith Busch
2019-03-19 23:49   ` Chaitanya Kulkarni
2019-03-19 23:49     ` Chaitanya Kulkarni
2019-03-20 16:44     ` Maxim Levitsky
2019-03-20 16:44       ` Maxim Levitsky
2019-03-20 16:30   ` Maxim Levitsky
2019-03-20 16:30     ` Maxim Levitsky
2019-03-20 17:03     ` Keith Busch
2019-03-20 17:03       ` Keith Busch
2019-03-20 17:33       ` Maxim Levitsky
2019-03-20 17:33         ` Maxim Levitsky
2019-04-08 10:04   ` Maxim Levitsky
2019-04-08 10:04     ` Maxim Levitsky
2019-03-20 11:03 ` No subject Felipe Franciosi
2019-03-20 11:03   ` Felipe Franciosi
2019-03-20 19:08   ` No subject Maxim Levitsky
2019-03-20 19:08     ` Maxim Levitsky
2019-03-21 16:12     ` No subject Stefan Hajnoczi
2019-03-21 16:12       ` Stefan Hajnoczi
2019-03-21 16:21       ` No subject Keith Busch
2019-03-21 16:21         ` Keith Busch
2019-03-21 16:41         ` No subject Felipe Franciosi
2019-03-21 16:41           ` Felipe Franciosi
2019-03-21 17:04           ` No subject Maxim Levitsky
2019-03-21 17:04             ` Maxim Levitsky
2019-03-22  7:54             ` No subject Felipe Franciosi
2019-03-22  7:54               ` Felipe Franciosi
2019-03-22 10:32               ` No subject Maxim Levitsky
2019-03-22 10:32                 ` Maxim Levitsky
2019-03-22 15:30               ` No subject Keith Busch
2019-03-22 15:30                 ` Keith Busch
2019-03-25 15:44                 ` No subject Felipe Franciosi
2019-03-25 15:44                   ` Felipe Franciosi
2019-03-20 15:08 ` [PATCH 0/9] RFC: NVME VFIO mediated device Bart Van Assche
2019-03-20 15:08   ` Bart Van Assche
2019-03-20 16:48   ` Maxim Levitsky
2019-03-20 16:48     ` Maxim Levitsky
2019-03-20 15:28 ` Bart Van Assche
2019-03-20 15:28   ` Bart Van Assche
2019-03-20 16:42   ` Maxim Levitsky
2019-03-20 16:42     ` Maxim Levitsky
2019-03-20 17:03     ` Alex Williamson
2019-03-20 17:03       ` Alex Williamson
2019-03-21 16:13 ` your mail Stefan Hajnoczi
2019-03-21 16:13   ` Stefan Hajnoczi
2019-03-21 17:07   ` Maxim Levitsky
2019-03-21 17:07     ` Maxim Levitsky
2019-03-25 16:46     ` Stefan Hajnoczi
2019-03-25 16:46       ` Stefan Hajnoczi
  -- strict thread matches above, loose matches on Subject: below --
2023-08-31  7:20 No subject Peter Yin
2022-06-21  9:06 ventas
2019-08-21 15:45 Ivan Mikhaylov
2019-03-16 11:17 Bharath Vedartham
2018-10-05 13:39 Christoph Hellwig
2018-08-02 10:48 TU PHUNG VAN
2018-07-06 21:16 Santosh Shilimkar
2018-07-06 21:16 ` Santosh Shilimkar
2018-07-06 21:16 ` Santosh Shilimkar
2018-07-06 21:18   ` Santosh Shilimkar
2018-07-06  5:52 inventsekar
2018-06-23 21:08 David Lechner
2018-05-08  6:10 Vishnu Gopinath
2018-05-04 20:06 Bjorn Helgaas
2018-04-20  8:02 Christoph Hellwig
2018-04-20  8:02 ` Christoph Hellwig
2018-04-16  1:22 Andrew Worsley
2018-02-25  0:39 J Freyensee
2018-02-02  6:54 Jianchao Wang
2017-11-30 10:25 Mary Cuevas
2017-09-13 18:15 unmesh rathi
2017-08-22  1:38 Nicholas Piggin
2017-06-26 13:16 [PATCH] arm64: use readq() instead of readl() to read 64bit entry_point Luc Van Oostenryck
2017-07-03 23:46 ` No subject Khuong Dinh
2017-06-06  7:19 From Lori J. Robinson
2017-06-04 11:59 Yury Norov
     [not found] <CAMj-D2DO_CfvD77izsGfggoKP45HSC9aD6auUPAYC9Yeq_aX7w@mail.gmail.com>
2017-05-04 16:44 ` gengdongjiu
2017-04-21 23:23 Sandeep Mann
2017-04-21  4:59 wendyqzx at gmail.com
2017-04-16 15:11 wendyqzx at gmail.com
2017-04-09 10:46 76564 at max.arc.nasa.gov
2017-02-07  0:22 Scott Bauer
2017-02-07  0:46 ` Jens Axboe
2017-01-31  7:58 Andy Gross
2017-01-09 11:33 [PATCH v2 0/7] uapi: export all headers under uapi directories Arnd Bergmann
2017-01-13 10:46 ` [PATCH v3 0/8] " Nicolas Dichtel
2017-01-13 10:46   ` [PATCH v3 1/8] arm: put types.h in uapi Nicolas Dichtel
2017-01-13 15:36     ` No subject David Howells
2017-01-13 10:46   ` [PATCH v3 4/8] x86: stop exporting msr-index.h to userland Nicolas Dichtel
2017-01-13 15:43     ` No subject David Howells
2016-12-01 10:00 Ramana Radhakrishnan
2016-11-19 18:31 bogus
2016-11-19 18:31 bogus
2016-11-19 18:31 bogus
2016-11-19 18:31 bogus
2016-11-11  3:38 Chunyan Zhang
2016-09-30 14:37 Maxime Ripard
2016-07-10  9:24 Neil Armstrong
2016-07-10  9:24 ` Neil Armstrong
2016-06-13  6:24 bogus
2016-06-13  6:24 bogus
2016-04-22  8:25 Daniel Lezcano
2016-04-22  8:27 ` Daniel Lezcano
2016-04-11  7:51 Paul Walmsley
2016-03-07 17:52 nunojsa
2016-02-09  7:29 bogus
2015-12-13 21:57 何旦洁
2015-11-16 16:13 bogus
2015-10-27  0:44 xuyiping
     [not found] <E1ZqY3A-0004Mt-KH@feisty.vs19.net>
2015-10-26  3:21 ` Jiada Wang
2015-10-21  6:17 Rock Lee
2015-10-12 17:26 bogus
2015-09-18 17:23 Shraddha Barke
2015-09-18  4:49 Shraddha Barke
2015-09-01 14:14 Mika Penttilä
2015-09-01 15:22 ` Fabio Estevam
2015-07-22 14:05 Chunfeng Yun
2015-07-15  9:32 Yuan Yao
2015-05-18 20:00 raghu MG
2015-04-21 10:18 Ard Biesheuvel
2015-03-30  4:56 Woody Wu
2015-02-26 16:56 Jorge Ramirez-Ortiz
2015-02-18 16:14 Lee Jones
2015-01-27 16:49 Grzegorz Dwornicki
2014-11-10  6:39 Libo Chen
2014-11-10  3:11 Libo Chen
2014-10-28 14:13 Mark Rutland
2014-09-22 19:41 Santosh Shilimkar
2014-09-22  7:45 Jingchang Lu
2014-09-13 19:40 bogus
2014-09-13 19:40 bogus
2014-09-13 19:40 bogus
2014-09-13 19:40 bogus
2014-09-13 19:40 bogus
2014-08-29 14:22 Ravi Raj
2014-08-29 14:47 ` Valdis.Kletnieks at vt.edu
2014-08-29 14:58   ` Ravi Raj
2014-08-29 15:32     ` No subject Valdis.Kletnieks at vt.edu
2014-08-29 15:34     ` Valdis.Kletnieks at vt.edu
2014-07-09 17:49 Sebastian Andrzej Siewior
2014-05-24  1:21 Loc Ho
2014-05-12 16:40 Santosh Shilimkar
2014-05-12 16:38 Santosh Shilimkar
2014-05-12  4:37 Sivakumar V
2014-04-21  2:59 Amber Thrall
2014-02-22 15:53 Hans de Goede
2014-01-21  4:09 John Tobias
2014-01-16 16:11 Loc Ho
2014-01-16 16:09 Loc Ho
2014-01-13 10:32 Lothar Waßmann
2014-01-13 10:29 Lothar Waßmann
2013-12-12  7:30 Loc Ho
2013-11-01  7:04 Xiubo Li
2013-09-24  3:13 Rohit Vaswani
2013-09-15  9:49 bogus
2013-09-15  9:49 bogus
2013-09-15  9:49 bogus
2013-09-02 17:01 Drasko DRASKOVIC
2013-08-24  9:29 Haojian Zhuang
2013-07-30  4:09 PV Juliet
2013-07-26 10:05 Haojian Zhuang
2013-06-28  5:49 Wang, Yalin
2013-06-19 10:57 Ben Dooks
2013-04-24 18:07 Viral Mehta
2013-04-12  7:08 Callum Hutchinson
2013-04-03 10:31 bogus
2013-04-03 10:31 bogus
2013-04-03 10:31 bogus
2013-04-03 10:31 bogus
2013-02-25  7:24 Prasad Lakshman
2013-02-15  5:48 Kaushal Billore
2013-02-06 22:30 Jimmy Pan
2013-01-16 21:46 bogus
2013-01-16 21:46 bogus
2012-12-29  9:17 steve.zhan
2012-12-05 13:48 Niroj Pokhrel
2012-11-19 11:41 唐忠诚
2012-11-11 14:16 Sammy Chan
2012-11-08  9:33 bogus
2012-11-08  8:07 Abhimanyu Kapur
2012-11-02 10:46 Pritam Bankar
2012-10-15  9:24 Niroj Pokhrel
2012-10-14 10:05 Alexey Dobriyan
2012-08-27  6:40 Simon Horman
2012-08-13 10:09 Vivek Panwar
2012-08-06 10:43 =?gb18030?B?wObC5A==?=
2012-07-30 19:04 siddhesh phadke
2012-06-21 18:26 Paul Walmsley
2012-06-06 10:33 Sascha Hauer
2012-05-25 15:26 bogus
2012-05-25 15:26 bogus
2012-05-18 12:27 Sascha Hauer
2012-04-09 17:56 Martynov Semen
2012-04-10  2:26 ` Vladimir Murzin
2012-04-10  4:03   ` Martynov Semen
2012-04-10  4:48   ` Martynov Semen
2012-04-10 16:08     ` Vladimir Murzin
2012-04-10 17:00       ` Semen Martynov
2012-04-05  7:54 bogus
2012-04-05  7:54 bogus
2012-03-20 18:28 John Szakmeister
2012-02-27  5:00 bogus
2012-02-27  5:00 bogus
2012-02-27  5:00 bogus
2012-01-15  8:24 bogus
2011-12-30 17:16 Philip Anil-QBW348
2011-12-28 14:01 Shawn Guo
2011-12-16  2:18 Swapnil Gaikwad
2011-12-02 16:01 Will Deacon
2011-11-28  2:35 Jett.Zhou
2011-11-21 15:22 Jimmy Pan
2011-11-12 14:39 bogus
2011-11-12 14:39 bogus
2011-09-23  3:42 毕春雷
2011-09-19  1:45 Saleem Abdulrasool
2011-09-15  2:03 Jongpill Lee
2011-08-05  3:08 bogus
2011-08-05  3:08 bogus
2011-08-05  3:08 bogus
2011-08-05  3:08 bogus
2011-08-05  3:08 bogus
2011-07-21 11:12 Padmavathi Venna
2011-06-27 20:47 Jongpill Lee
2011-06-27 20:47 John Ogness
2011-06-16 11:41 Venkateswarlu P
2011-06-14 12:20 Venkateswarlu P
2011-06-13 17:29 Andre Silva
2011-06-05 18:33 Hector Oron
2011-06-04 23:16 bogus
2011-06-04 23:16 bogus
2011-05-17  9:28 Javier Martin
2011-05-13 19:35 Vadim Bendebury
2011-04-07  5:55 bogus
2011-04-07  5:55 bogus
2011-04-07  5:55 bogus
2011-04-07  5:55 bogus
2011-04-07  5:55 bogus
2011-03-22 18:13 nijil yes
2011-03-01 14:02 Javier Martin
2011-02-26  6:20 Aldyth Maharsha
2011-01-13  9:13 Uwe Kleine-König
2011-01-05 11:39 davidgg
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-19 23:59 bogus
2010-12-03  1:08 tarek attia
2010-10-08  6:02 Daein Moon
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-24 14:53 bogus
2010-09-09  3:33 tarek attia
2010-08-30  5:02 auto595907
2010-08-23 14:32 auto595907
2010-07-23 10:05 bogus
2010-06-24 13:48 Uwe Kleine-König
2010-06-07 17:58 Dave Hylands
2010-05-18 10:38 Marek Szyprowski
2010-04-17 21:43 nelakurthi koteswararao
2010-03-25 17:02 bogus
2010-03-25 17:02 bogus
2010-02-25  9:36 Thomas Weber
2009-11-19 13:58 Vimal Singh
2009-09-17  9:37 Marc Kleine-Budde
2009-09-07 14:07 Somshekar ChandrashekarKadam
2009-08-25 10:34 Syed Rafiuddin
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-27 19:01 bogus
2009-02-15  8:49 bogus
2009-01-04 17:33 bogus
2009-01-04 17:33 bogus
2008-12-07 21:22 bogus
2008-11-21  1:22 bogus
2008-10-23 17:17 bogus
2008-10-23 17:17 bogus
2008-10-23 17:17 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-10-14 11:50 bogus
2008-09-15 17:22 bogus
2008-09-15 17:22 bogus
2008-07-28  4:41 bogus
2008-07-14 13:16 bogus
2008-07-14 13:16 bogus
2008-07-14 13:16 bogus
2008-07-14 13:16 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-04-23 14:39 bogus
2008-03-17 22:01 bogus
2007-12-01  7:52 bogus
2007-12-01  7:52 bogus
2007-10-06 20:13 bogus
2007-10-06 20:13 bogus
2007-10-06 20:13 bogus
2007-07-23 18:04 bogus
2007-07-23 18:04 bogus
2007-06-23 20:07 bogus
2007-02-14  8:32 bogus
2007-02-14  8:32 bogus
2007-02-14  8:32 bogus
2007-02-14  8:32 bogus
2007-02-06  7:08 bogus
2007-02-06  7:08 bogus
2007-02-06  7:08 bogus
2007-02-06  7:08 bogus
2007-02-01  7:54 kou.ishizaki
2007-02-04  4:37 ` No Subject Benjamin Herrenschmidt
2006-10-09 23:13 (no subject) albox
2006-10-09 23:31 ` No Subject Tobin Davis
2006-08-17  1:58 No subject bogus
2006-08-17  1:58 bogus
2006-08-17  1:58 bogus
2006-08-17  1:58 bogus
2006-08-17  1:58 bogus
2006-08-17  1:58 bogus
2006-08-17  1:58 bogus
     [not found] <Pine.LNX.4.33.0111200151170.1364-100000@home.apu.edu>
2005-05-19  6:23 ` SACAH
2005-05-19  6:23 ` Chen, Zhen Y (Zhen)
2005-05-19  6:23 ` Gyimesi Attila
2005-05-19  6:23 ` Minesh Khatri
2005-05-19  6:24 ` Bryan Call
2005-05-19  6:24 ` Kirby Dotson
2005-05-19  6:24 ` Zaffar Khalid
2005-05-19  6:24 ` cst01074
2005-05-19  6:24 ` spreckel
2005-05-19  6:24 ` jmp
2005-05-19  6:25 ` no subject firase kaled
2005-05-19  6:25 ` No subject andreas
2005-05-19  6:25 ` Rudolf Marek
2005-05-19  6:25 ` Tomáš Thiemel
2004-12-14 16:49 Andi Kleen
2004-12-15 23:50 ` No Subject Alan Cox
2004-07-16 16:54 Hermann Gottschalk
2004-07-16 16:59 ` No Subject Jesse Stockall
2004-02-22 17:51 redzic fadil
2004-02-22 20:54 ` No Subject Ludootje
     [not found] <Pine.GSO.4.58.0401251223440.20527@waterleaf.sonytel.be>
2004-01-25 13:02 ` Benjamin Herrenschmidt
2003-02-21 13:43 News Admin
2003-02-21 15:01 ` No Subject Alan Cox
2002-08-05 13:08 Christos Kartsaklis
2002-08-05 14:53 ` No Subject Alan Cox
2002-08-03 19:26 Pawel Kot
2002-08-03 21:45 ` No Subject Alan Cox
2002-08-03 21:58   ` Bartlomiej Zolnierkiewicz
2002-08-03 22:16     ` Bartlomiej Zolnierkiewicz
2002-08-03 23:38       ` Alan Cox
2002-08-03 22:53         ` Bartlomiej Zolnierkiewicz
2002-08-04 13:28           ` Henning P. Schmiedehausen
2002-08-04 15:40             ` Daniela Engert
2002-08-03 23:27         ` Petr Vandrovec
2001-08-24 22:16 abraxas2
2000-11-19 20:02 jingai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.