diff mbox

PCI BAR1 Unassigned

Message ID BANLkTi=jTKp9+_KDmTxYfGXe6Ln02GLmDA@mail.gmail.com (mailing list archive)
State RFC, archived
Headers show

Commit Message

Bjorn Helgaas May 20, 2011, 2:53 p.m. UTC
On Fri, May 20, 2011 at 1:42 AM, Jan Zwiegers <jan@radicalsystems.co.za> wrote:
> On 2011-05-19 10:50 PM, Xianghua Xiao wrote:
>>
>> On Thu, May 19, 2011 at 3:27 PM, Jan Zwiegers<jan@radicalsystems.co.za>
>>  wrote:
>>>
>>> On 2011-05-19 08:50 PM, Bjorn Helgaas wrote:
>>>>
>>>> On Thu, May 19, 2011 at 10:28 AM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>>  wrote:
>>>>>
>>>>> I have the problem below where my PCI card's second BAR does not get
>>>>> assigned.
>>>>> What can be the cause of this problem?
>>>>> The last kernel I tested on which worked OK was 2.6.27.
>>>>> My current problematic kernel 2.6.35.
>>>>>
>>>>> 05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>>>>> Card
>>>>> (rev 5c)
>>>>>    Flags: bus master, slow devsel, latency 32, IRQ 22
>>>>>    Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>>>>    Memory at<unassigned>    (type 3, prefetchable)
>>>>>    Capabilities: [80] #00 [0600]
>>>>>    Kernel modules: pci703drv
>>>>
>>>> Could be resource exhaustion or, more likely, we ran out because we
>>>> now assign resource to things that don't need them, leaving none for
>>>> things that *do* need them.  This sounds like a regression, so we
>>>> should open a bugzilla for it and attach dmesg logs from 2.6.27 and
>>>> 2.6.35.
>>>>
>>>> Does this problem keep the driver from working?  (Sometimes drivers
>>>> don't actually use all the BARs a device supports.)
>>>>
>>>> Bjorn
>>>>
>>>
>>> I'm the maintainer of the driver and was involved in the development of
>>> the
>>> board as well in 2003. The board uses two BARS and the second BAR is the
>>> most important. The board worked fine since the 2.4 days and only
>>> recently
>>> became problematic. I suspect it works on even later kernels than 27,
>>> maybe
>>> 2.6.32.
>>>
>>> My knowledge is too little to actually determine if the problem is
>>> because
>>> the FPGA based PCI interface is not within spec or something that changed
>>> in
>>> the kernel, because of the post .30 releases becoming more strict to PCI
>>> specification, i.e. BIOS / Kernel interaction.
>>>
>>> Jan
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>> What's the size for BAR1? one reason is that no more space to
>> align/allocate BAR1.
>>
>> If the board stays the same then your FPGA might be the cause, I have
>> seen similar issues and they ended up in FPGA implementation.
>>
>
> I have submitted the difference in iomem, lspci and dmesg of 2.6.27 & 2.6.35
> kernels from the same machine. The BAR size is 2K. As above BAR0 is at
> 93b0000 and BAR1 should be at 93b00800.

Thanks for the data.

I think your FPGA is "unusual" after all.  lspci says this:

  05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
Card (rev 5c)
       Flags: bus master, slow devsel, latency 32, IRQ 22
       Memory at 93b00000 (type 3, prefetchable) [size=2K]
       Memory at <unassigned> (type 3, prefetchable)

The "type 3" means the BAR has both type bits set (bits 1 and 2).  The
spec (PCI 3.0 sec 6.2.5.1) says the type field means:

  00 - Locate anywhere in 32-bit access space
  01 - Reserved
  10 - Locate anywhere in 64-bit access space
  11 - Reserved

I think your BARs are using the "11 - Reserved" setting when they
should be "00".  The way Linux handles this did change between 2.6.27
and 2.6.35, and I think the change was unintentional, so we might
consider changing it back.

Commit e354597cce8d219d made this change to decode_bar():

          res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;

  -       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
  +       if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
                  return pci_bar_mem64;
          return pci_bar_mem32;

In 2.6.27, we treated the BAR as 64-bit only if the low four bits were
0100 (non-prefetchable, 64-bit type, memory).  That was incorrect,
because we should ignore the prefetchable bit.  The fix was to look
*only* at bit 2, so now we decide the BAR is 64-bit if the low four
bits are x1xx.

Your BARs contain 1110 in the low four bits.  This is invalid but was
treated as 32-bit by 2.6.27 and as 64-bit by 2.6.35.

Here's an untested Linux change I think we might consider making to
restore the previous behavior.  Can you try it (gmail will probably
mangle it, so you'll have to apply it by hand)?

the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Jan Zwiegers May 20, 2011, 3:09 p.m. UTC | #1
On 2011-05-20 04:53 PM, Bjorn Helgaas wrote:
> On Fri, May 20, 2011 at 1:42 AM, Jan Zwiegers<jan@radicalsystems.co.za>  wrote:
>> On 2011-05-19 10:50 PM, Xianghua Xiao wrote:
>>>
>>> On Thu, May 19, 2011 at 3:27 PM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>   wrote:
>>>>
>>>> On 2011-05-19 08:50 PM, Bjorn Helgaas wrote:
>>>>>
>>>>> On Thu, May 19, 2011 at 10:28 AM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>>>   wrote:
>>>>>>
>>>>>> I have the problem below where my PCI card's second BAR does not get
>>>>>> assigned.
>>>>>> What can be the cause of this problem?
>>>>>> The last kernel I tested on which worked OK was 2.6.27.
>>>>>> My current problematic kernel 2.6.35.
>>>>>>
>>>>>> 05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>>>>>> Card
>>>>>> (rev 5c)
>>>>>>     Flags: bus master, slow devsel, latency 32, IRQ 22
>>>>>>     Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>>>>>     Memory at<unassigned>      (type 3, prefetchable)
>>>>>>     Capabilities: [80] #00 [0600]
>>>>>>     Kernel modules: pci703drv
>>>>>
>>>>> Could be resource exhaustion or, more likely, we ran out because we
>>>>> now assign resource to things that don't need them, leaving none for
>>>>> things that *do* need them.  This sounds like a regression, so we
>>>>> should open a bugzilla for it and attach dmesg logs from 2.6.27 and
>>>>> 2.6.35.
>>>>>
>>>>> Does this problem keep the driver from working?  (Sometimes drivers
>>>>> don't actually use all the BARs a device supports.)
>>>>>
>>>>> Bjorn
>>>>>
>>>>
>>>> I'm the maintainer of the driver and was involved in the development of
>>>> the
>>>> board as well in 2003. The board uses two BARS and the second BAR is the
>>>> most important. The board worked fine since the 2.4 days and only
>>>> recently
>>>> became problematic. I suspect it works on even later kernels than 27,
>>>> maybe
>>>> 2.6.32.
>>>>
>>>> My knowledge is too little to actually determine if the problem is
>>>> because
>>>> the FPGA based PCI interface is not within spec or something that changed
>>>> in
>>>> the kernel, because of the post .30 releases becoming more strict to PCI
>>>> specification, i.e. BIOS / Kernel interaction.
>>>>
>>>> Jan
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>>
>>> What's the size for BAR1? one reason is that no more space to
>>> align/allocate BAR1.
>>>
>>> If the board stays the same then your FPGA might be the cause, I have
>>> seen similar issues and they ended up in FPGA implementation.
>>>
>>
>> I have submitted the difference in iomem, lspci and dmesg of 2.6.27&  2.6.35
>> kernels from the same machine. The BAR size is 2K. As above BAR0 is at
>> 93b0000 and BAR1 should be at 93b00800.
>
> Thanks for the data.
>
> I think your FPGA is "unusual" after all.  lspci says this:
>
>    05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
> Card (rev 5c)
>         Flags: bus master, slow devsel, latency 32, IRQ 22
>         Memory at 93b00000 (type 3, prefetchable) [size=2K]
>         Memory at<unassigned>  (type 3, prefetchable)
>
> The "type 3" means the BAR has both type bits set (bits 1 and 2).  The
> spec (PCI 3.0 sec 6.2.5.1) says the type field means:
>
>    00 - Locate anywhere in 32-bit access space
>    01 - Reserved
>    10 - Locate anywhere in 64-bit access space
>    11 - Reserved
>
> I think your BARs are using the "11 - Reserved" setting when they
> should be "00".  The way Linux handles this did change between 2.6.27
> and 2.6.35, and I think the change was unintentional, so we might
> consider changing it back.
>
> Commit e354597cce8d219d made this change to decode_bar():
>
>            res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>
>    -       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
>    +       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>                    return pci_bar_mem64;
>            return pci_bar_mem32;
>
> In 2.6.27, we treated the BAR as 64-bit only if the low four bits were
> 0100 (non-prefetchable, 64-bit type, memory).  That was incorrect,
> because we should ignore the prefetchable bit.  The fix was to look
> *only* at bit 2, so now we decide the BAR is 64-bit if the low four
> bits are x1xx.
>
> Your BARs contain 1110 in the low four bits.  This is invalid but was
> treated as 32-bit by 2.6.27 and as 64-bit by 2.6.35.
>
> Here's an untested Linux change I think we might consider making to
> restore the previous behavior.  Can you try it (gmail will probably
> mangle it, so you'll have to apply it by hand)?
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 44cbbba..33894ba 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -138,15 +138,20 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
>
>   static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
>   {
> +       u32 mem_type;
> +
>          if ((bar&  PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
>                  res->flags = bar&  ~PCI_BASE_ADDRESS_IO_MASK;
>                  return pci_bar_io;
>          }
>
> -       res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
> +       res->flags = bar&  PCI_BASE_ADDRESS_MEM_PREFETCH;
>
> -       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
> +       mem_type = bar&  PCI_BASE_ADDRESS_MEM_TYPE_MASK;
> +       if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
> +               res->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>                  return pci_bar_mem64;
> +       }
>          return pci_bar_mem32;
>   }
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Hi Bjorn

I will tested it next week and let you know. I'll also get the FPGA code 
fixed up to conform to the PCI 3.0 spec. I know back in 2003 the board 
only conformed to PCI spec 2.1. Has this maybe changed since then or was 
it the same for 2.1?

Thanks
Jan
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas May 20, 2011, 3:57 p.m. UTC | #2
On Fri, May 20, 2011 at 9:09 AM, Jan Zwiegers <jan@radicalsystems.co.za> wrote:
> On 2011-05-20 04:53 PM, Bjorn Helgaas wrote:
>>
>> On Fri, May 20, 2011 at 1:42 AM, Jan Zwiegers<jan@radicalsystems.co.za>
>>  wrote:
>>>
>>> On 2011-05-19 10:50 PM, Xianghua Xiao wrote:
>>>>
>>>> On Thu, May 19, 2011 at 3:27 PM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>>  wrote:
>>>>>
>>>>> On 2011-05-19 08:50 PM, Bjorn Helgaas wrote:
>>>>>>
>>>>>> On Thu, May 19, 2011 at 10:28 AM, Jan
>>>>>> Zwiegers<jan@radicalsystems.co.za>
>>>>>>  wrote:
>>>>>>>
>>>>>>> I have the problem below where my PCI card's second BAR does not get
>>>>>>> assigned.
>>>>>>> What can be the cause of this problem?
>>>>>>> The last kernel I tested on which worked OK was 2.6.27.
>>>>>>> My current problematic kernel 2.6.35.
>>>>>>>
>>>>>>> 05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>>>>>>> Card
>>>>>>> (rev 5c)
>>>>>>>    Flags: bus master, slow devsel, latency 32, IRQ 22
>>>>>>>    Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>>>>>>    Memory at<unassigned>      (type 3, prefetchable)
>>>>>>>    Capabilities: [80] #00 [0600]
>>>>>>>    Kernel modules: pci703drv
>>>>>>
>>>>>> Could be resource exhaustion or, more likely, we ran out because we
>>>>>> now assign resource to things that don't need them, leaving none for
>>>>>> things that *do* need them.  This sounds like a regression, so we
>>>>>> should open a bugzilla for it and attach dmesg logs from 2.6.27 and
>>>>>> 2.6.35.
>>>>>>
>>>>>> Does this problem keep the driver from working?  (Sometimes drivers
>>>>>> don't actually use all the BARs a device supports.)
>>>>>>
>>>>>> Bjorn
>>>>>>
>>>>>
>>>>> I'm the maintainer of the driver and was involved in the development of
>>>>> the
>>>>> board as well in 2003. The board uses two BARS and the second BAR is
>>>>> the
>>>>> most important. The board worked fine since the 2.4 days and only
>>>>> recently
>>>>> became problematic. I suspect it works on even later kernels than 27,
>>>>> maybe
>>>>> 2.6.32.
>>>>>
>>>>> My knowledge is too little to actually determine if the problem is
>>>>> because
>>>>> the FPGA based PCI interface is not within spec or something that
>>>>> changed
>>>>> in
>>>>> the kernel, because of the post .30 releases becoming more strict to
>>>>> PCI
>>>>> specification, i.e. BIOS / Kernel interaction.
>>>>>
>>>>> Jan
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>
>>>>
>>>> What's the size for BAR1? one reason is that no more space to
>>>> align/allocate BAR1.
>>>>
>>>> If the board stays the same then your FPGA might be the cause, I have
>>>> seen similar issues and they ended up in FPGA implementation.
>>>>
>>>
>>> I have submitted the difference in iomem, lspci and dmesg of 2.6.27&
>>>  2.6.35
>>> kernels from the same machine. The BAR size is 2K. As above BAR0 is at
>>> 93b0000 and BAR1 should be at 93b00800.
>>
>> Thanks for the data.
>>
>> I think your FPGA is "unusual" after all.  lspci says this:
>>
>>   05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>> Card (rev 5c)
>>        Flags: bus master, slow devsel, latency 32, IRQ 22
>>        Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>        Memory at<unassigned>  (type 3, prefetchable)
>>
>> The "type 3" means the BAR has both type bits set (bits 1 and 2).  The
>> spec (PCI 3.0 sec 6.2.5.1) says the type field means:
>>
>>   00 - Locate anywhere in 32-bit access space
>>   01 - Reserved
>>   10 - Locate anywhere in 64-bit access space
>>   11 - Reserved
>>
>> I think your BARs are using the "11 - Reserved" setting when they
>> should be "00".  The way Linux handles this did change between 2.6.27
>> and 2.6.35, and I think the change was unintentional, so we might
>> consider changing it back.
>>
>> Commit e354597cce8d219d made this change to decode_bar():
>>
>>           res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>>
>>   -       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
>>   +       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>>                   return pci_bar_mem64;
>>           return pci_bar_mem32;
>>
>> In 2.6.27, we treated the BAR as 64-bit only if the low four bits were
>> 0100 (non-prefetchable, 64-bit type, memory).  That was incorrect,
>> because we should ignore the prefetchable bit.  The fix was to look
>> *only* at bit 2, so now we decide the BAR is 64-bit if the low four
>> bits are x1xx.
>>
>> Your BARs contain 1110 in the low four bits.  This is invalid but was
>> treated as 32-bit by 2.6.27 and as 64-bit by 2.6.35.
>>
>> Here's an untested Linux change I think we might consider making to
>> restore the previous behavior.  Can you try it (gmail will probably
>> mangle it, so you'll have to apply it by hand)?
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 44cbbba..33894ba 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -138,15 +138,20 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
>>
>>  static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
>>  {
>> +       u32 mem_type;
>> +
>>         if ((bar&  PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
>>                 res->flags = bar&  ~PCI_BASE_ADDRESS_IO_MASK;
>>                 return pci_bar_io;
>>         }
>>
>> -       res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>> +       res->flags = bar&  PCI_BASE_ADDRESS_MEM_PREFETCH;
>>
>> -       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>> +       mem_type = bar&  PCI_BASE_ADDRESS_MEM_TYPE_MASK;
>> +       if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
>> +               res->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>>                 return pci_bar_mem64;
>> +       }
>>         return pci_bar_mem32;
>>  }
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> I will tested it next week and let you know. I'll also get the FPGA code
> fixed up to conform to the PCI 3.0 spec. I know back in 2003 the board only
> conformed to PCI spec 2.1. Has this maybe changed since then or was it the
> same for 2.1?

As far as I know, the "11" type has always been reserved, but I don't
have a copy of the 2.1 spec.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Zwiegers May 24, 2011, 10:22 a.m. UTC | #3
On 2011-05-20 04:53 PM, Bjorn Helgaas wrote:
> On Fri, May 20, 2011 at 1:42 AM, Jan Zwiegers<jan@radicalsystems.co.za>  wrote:
>> On 2011-05-19 10:50 PM, Xianghua Xiao wrote:
>>>
>>> On Thu, May 19, 2011 at 3:27 PM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>   wrote:
>>>>
>>>> On 2011-05-19 08:50 PM, Bjorn Helgaas wrote:
>>>>>
>>>>> On Thu, May 19, 2011 at 10:28 AM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>>>   wrote:
>>>>>>
>>>>>> I have the problem below where my PCI card's second BAR does not get
>>>>>> assigned.
>>>>>> What can be the cause of this problem?
>>>>>> The last kernel I tested on which worked OK was 2.6.27.
>>>>>> My current problematic kernel 2.6.35.
>>>>>>
>>>>>> 05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>>>>>> Card
>>>>>> (rev 5c)
>>>>>>     Flags: bus master, slow devsel, latency 32, IRQ 22
>>>>>>     Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>>>>>     Memory at<unassigned>      (type 3, prefetchable)
>>>>>>     Capabilities: [80] #00 [0600]
>>>>>>     Kernel modules: pci703drv
>>>>>
>>>>> Could be resource exhaustion or, more likely, we ran out because we
>>>>> now assign resource to things that don't need them, leaving none for
>>>>> things that *do* need them.  This sounds like a regression, so we
>>>>> should open a bugzilla for it and attach dmesg logs from 2.6.27 and
>>>>> 2.6.35.
>>>>>
>>>>> Does this problem keep the driver from working?  (Sometimes drivers
>>>>> don't actually use all the BARs a device supports.)
>>>>>
>>>>> Bjorn
>>>>>
>>>>
>>>> I'm the maintainer of the driver and was involved in the development of
>>>> the
>>>> board as well in 2003. The board uses two BARS and the second BAR is the
>>>> most important. The board worked fine since the 2.4 days and only
>>>> recently
>>>> became problematic. I suspect it works on even later kernels than 27,
>>>> maybe
>>>> 2.6.32.
>>>>
>>>> My knowledge is too little to actually determine if the problem is
>>>> because
>>>> the FPGA based PCI interface is not within spec or something that changed
>>>> in
>>>> the kernel, because of the post .30 releases becoming more strict to PCI
>>>> specification, i.e. BIOS / Kernel interaction.
>>>>
>>>> Jan
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>>
>>> What's the size for BAR1? one reason is that no more space to
>>> align/allocate BAR1.
>>>
>>> If the board stays the same then your FPGA might be the cause, I have
>>> seen similar issues and they ended up in FPGA implementation.
>>>
>>
>> I have submitted the difference in iomem, lspci and dmesg of 2.6.27&  2.6.35
>> kernels from the same machine. The BAR size is 2K. As above BAR0 is at
>> 93b0000 and BAR1 should be at 93b00800.
>
> Thanks for the data.
>
> I think your FPGA is "unusual" after all.  lspci says this:
>
>    05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
> Card (rev 5c)
>         Flags: bus master, slow devsel, latency 32, IRQ 22
>         Memory at 93b00000 (type 3, prefetchable) [size=2K]
>         Memory at<unassigned>  (type 3, prefetchable)
>
> The "type 3" means the BAR has both type bits set (bits 1 and 2).  The
> spec (PCI 3.0 sec 6.2.5.1) says the type field means:
>
>    00 - Locate anywhere in 32-bit access space
>    01 - Reserved
>    10 - Locate anywhere in 64-bit access space
>    11 - Reserved
>
> I think your BARs are using the "11 - Reserved" setting when they
> should be "00".  The way Linux handles this did change between 2.6.27
> and 2.6.35, and I think the change was unintentional, so we might
> consider changing it back.
>
> Commit e354597cce8d219d made this change to decode_bar():
>
>            res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>
>    -       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
>    +       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>                    return pci_bar_mem64;
>            return pci_bar_mem32;
>
> In 2.6.27, we treated the BAR as 64-bit only if the low four bits were
> 0100 (non-prefetchable, 64-bit type, memory).  That was incorrect,
> because we should ignore the prefetchable bit.  The fix was to look
> *only* at bit 2, so now we decide the BAR is 64-bit if the low four
> bits are x1xx.
>
> Your BARs contain 1110 in the low four bits.  This is invalid but was
> treated as 32-bit by 2.6.27 and as 64-bit by 2.6.35.
>
> Here's an untested Linux change I think we might consider making to
> restore the previous behavior.  Can you try it (gmail will probably
> mangle it, so you'll have to apply it by hand)?
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 44cbbba..33894ba 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -138,15 +138,20 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
>
>   static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
>   {
> +       u32 mem_type;
> +
>          if ((bar&  PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
>                  res->flags = bar&  ~PCI_BASE_ADDRESS_IO_MASK;
>                  return pci_bar_io;
>          }
>
> -       res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
> +       res->flags = bar&  PCI_BASE_ADDRESS_MEM_PREFETCH;
>
> -       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
> +       mem_type = bar&  PCI_BASE_ADDRESS_MEM_TYPE_MASK;
> +       if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
> +               res->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>                  return pci_bar_mem64;
> +       }
>          return pci_bar_mem32;
>   }
>

Hi Bjorn

I have tested your suggested implementation and this definitely solved 
my problem. Both of my BARs are now mapped as they should.

Please indicate if the changed will be reverted. In the meantime I will 
try and get this corrected in newer versions of the Eagle Technology 
PCI703 FPGA's.

Thanks again for the help.
Jan


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas May 24, 2011, 12:35 p.m. UTC | #4
On Tue, May 24, 2011 at 4:22 AM, Jan Zwiegers <jan@radicalsystems.co.za> wrote:
> On 2011-05-20 04:53 PM, Bjorn Helgaas wrote:
>>
>> On Fri, May 20, 2011 at 1:42 AM, Jan Zwiegers<jan@radicalsystems.co.za>
>>  wrote:
>>>
>>> On 2011-05-19 10:50 PM, Xianghua Xiao wrote:
>>>>
>>>> On Thu, May 19, 2011 at 3:27 PM, Jan Zwiegers<jan@radicalsystems.co.za>
>>>>  wrote:
>>>>>
>>>>> On 2011-05-19 08:50 PM, Bjorn Helgaas wrote:
>>>>>>
>>>>>> On Thu, May 19, 2011 at 10:28 AM, Jan
>>>>>> Zwiegers<jan@radicalsystems.co.za>
>>>>>>  wrote:
>>>>>>>
>>>>>>> I have the problem below where my PCI card's second BAR does not get
>>>>>>> assigned.
>>>>>>> What can be the cause of this problem?
>>>>>>> The last kernel I tested on which worked OK was 2.6.27.
>>>>>>> My current problematic kernel 2.6.35.
>>>>>>>
>>>>>>> 05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>>>>>>> Card
>>>>>>> (rev 5c)
>>>>>>>    Flags: bus master, slow devsel, latency 32, IRQ 22
>>>>>>>    Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>>>>>>    Memory at<unassigned>      (type 3, prefetchable)
>>>>>>>    Capabilities: [80] #00 [0600]
>>>>>>>    Kernel modules: pci703drv
>>>>>>
>>>>>> Could be resource exhaustion or, more likely, we ran out because we
>>>>>> now assign resource to things that don't need them, leaving none for
>>>>>> things that *do* need them.  This sounds like a regression, so we
>>>>>> should open a bugzilla for it and attach dmesg logs from 2.6.27 and
>>>>>> 2.6.35.
>>>>>>
>>>>>> Does this problem keep the driver from working?  (Sometimes drivers
>>>>>> don't actually use all the BARs a device supports.)
>>>>>>
>>>>>> Bjorn
>>>>>>
>>>>>
>>>>> I'm the maintainer of the driver and was involved in the development of
>>>>> the
>>>>> board as well in 2003. The board uses two BARS and the second BAR is
>>>>> the
>>>>> most important. The board worked fine since the 2.4 days and only
>>>>> recently
>>>>> became problematic. I suspect it works on even later kernels than 27,
>>>>> maybe
>>>>> 2.6.32.
>>>>>
>>>>> My knowledge is too little to actually determine if the problem is
>>>>> because
>>>>> the FPGA based PCI interface is not within spec or something that
>>>>> changed
>>>>> in
>>>>> the kernel, because of the post .30 releases becoming more strict to
>>>>> PCI
>>>>> specification, i.e. BIOS / Kernel interaction.
>>>>>
>>>>> Jan
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>
>>>>
>>>> What's the size for BAR1? one reason is that no more space to
>>>> align/allocate BAR1.
>>>>
>>>> If the board stays the same then your FPGA might be the cause, I have
>>>> seen similar issues and they ended up in FPGA implementation.
>>>>
>>>
>>> I have submitted the difference in iomem, lspci and dmesg of 2.6.27&
>>>  2.6.35
>>> kernels from the same machine. The BAR size is 2K. As above BAR0 is at
>>> 93b0000 and BAR1 should be at 93b00800.
>>
>> Thanks for the data.
>>
>> I think your FPGA is "unusual" after all.  lspci says this:
>>
>>   05:01.0 Unassigned class [ff00]: Eagle Technology PCI-703 Analog I/O
>> Card (rev 5c)
>>        Flags: bus master, slow devsel, latency 32, IRQ 22
>>        Memory at 93b00000 (type 3, prefetchable) [size=2K]
>>        Memory at<unassigned>  (type 3, prefetchable)
>>
>> The "type 3" means the BAR has both type bits set (bits 1 and 2).  The
>> spec (PCI 3.0 sec 6.2.5.1) says the type field means:
>>
>>   00 - Locate anywhere in 32-bit access space
>>   01 - Reserved
>>   10 - Locate anywhere in 64-bit access space
>>   11 - Reserved
>>
>> I think your BARs are using the "11 - Reserved" setting when they
>> should be "00".  The way Linux handles this did change between 2.6.27
>> and 2.6.35, and I think the change was unintentional, so we might
>> consider changing it back.
>>
>> Commit e354597cce8d219d made this change to decode_bar():
>>
>>           res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>>
>>   -       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
>>   +       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>>                   return pci_bar_mem64;
>>           return pci_bar_mem32;
>>
>> In 2.6.27, we treated the BAR as 64-bit only if the low four bits were
>> 0100 (non-prefetchable, 64-bit type, memory).  That was incorrect,
>> because we should ignore the prefetchable bit.  The fix was to look
>> *only* at bit 2, so now we decide the BAR is 64-bit if the low four
>> bits are x1xx.
>>
>> Your BARs contain 1110 in the low four bits.  This is invalid but was
>> treated as 32-bit by 2.6.27 and as 64-bit by 2.6.35.
>>
>> Here's an untested Linux change I think we might consider making to
>> restore the previous behavior.  Can you try it (gmail will probably
>> mangle it, so you'll have to apply it by hand)?
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 44cbbba..33894ba 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -138,15 +138,20 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
>>
>>  static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
>>  {
>> +       u32 mem_type;
>> +
>>         if ((bar&  PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
>>                 res->flags = bar&  ~PCI_BASE_ADDRESS_IO_MASK;
>>                 return pci_bar_io;
>>         }
>>
>> -       res->flags = bar&  ~PCI_BASE_ADDRESS_MEM_MASK;
>> +       res->flags = bar&  PCI_BASE_ADDRESS_MEM_PREFETCH;
>>
>> -       if (res->flags&  PCI_BASE_ADDRESS_MEM_TYPE_64)
>> +       mem_type = bar&  PCI_BASE_ADDRESS_MEM_TYPE_MASK;
>> +       if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
>> +               res->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>>                 return pci_bar_mem64;
>> +       }
>>         return pci_bar_mem32;
>>  }
>>
>
> Hi Bjorn
>
> I have tested your suggested implementation and this definitely solved my
> problem. Both of my BARs are now mapped as they should.
>
> Please indicate if the changed will be reverted. In the meantime I will try
> and get this corrected in newer versions of the Eagle Technology PCI703
> FPGA's.

I will clean up that patch a bit and propose it for mainline.  Thanks
for testing it.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas May 26, 2011, 8:38 p.m. UTC | #5
Jan, would you mind testing the attached patch?  This is against
current upstream, but I think it will apply without much trouble to
2.6.35; I don't think there have been many changes in that area.
Thanks.
Bjorn Helgaas May 31, 2011, 3:02 a.m. UTC | #6
On Thu, May 26, 2011 at 2:38 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Jan, would you mind testing the attached patch?  This is against
> current upstream, but I think it will apply without much trouble to
> 2.6.35; I don't think there have been many changes in that area.
> Thanks.

Hi Jan,

If you haven't tested the patch yet, can you substitute this one?  It
should be functionally equivalent, but I did tweak it a bit.

Bjorn
Jan Zwiegers June 1, 2011, 2:36 p.m. UTC | #7
On 2011-05-31 05:02 AM, Bjorn Helgaas wrote:
> On Thu, May 26, 2011 at 2:38 PM, Bjorn Helgaas<bhelgaas@google.com>  wrote:
>> Jan, would you mind testing the attached patch?  This is against
>> current upstream, but I think it will apply without much trouble to
>> 2.6.35; I don't think there have been many changes in that area.
>> Thanks.
>
> Hi Jan,
>
> If you haven't tested the patch yet, can you substitute this one?  It
> should be functionally equivalent, but I did tweak it a bit.
>
> Bjorn
Yes, I'll test this one.
Not a problem!
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 44cbbba..33894ba 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -138,15 +138,20 @@  static u64 pci_size(u64 base, u64 maxbase, u64 mask)

 static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
 {
+       u32 mem_type;
+
        if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
                res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK;
                return pci_bar_io;
        }

-       res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
+       res->flags = bar & PCI_BASE_ADDRESS_MEM_PREFETCH;

-       if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+       mem_type = bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
+       if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+               res->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
                return pci_bar_mem64;
+       }
        return pci_bar_mem32;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in