resource, PNPACPI: add bus number and window support
Subsystems (4)
cover resource, PNPACPI: add bus number and window support
These patches add a new resource type, IORESOURCE_BUS, and a new resource flag, IORESOURCE_WINDOW, and PNPACPI support that uses them.
IORESOURCE_BUS is for PCI bus number ranges. For bridge devices, ACPI reports secondary bus number ranges in _CRS descriptors, but we currently ignore them. Adding this resource type will allow us to handle those descriptors in PNPACPI.
IORESOURCE_WINDOW is also for bridges: ACPI reports the regions that the bridge forwards to its secondary bus. We have _CRS parsing code in pci_root.c that handles these window descriptors, but PNPACPI currently ignores them. Adding this flag bit will allow PNPACPI to deal with the windows correctly.
No drivers use PNP bus or window resources yet, but ultimately, I would like to drop the _CRS parsing code from pci_root.c and rely on PNPACPI to do it for us. The current effect of this series is to change /sys/bus/pnp/.../resources (and "lspnp -v" output) from this:
00:00 PNP0a03 PCI bus
state = active
to this:
00:00 PNP0a03 PCI bus state = active bus 0x0-0x0 io 0x0-0xcff window io 0x0-0x2cfe window io 0x3b0-0x3bb window io 0x3c0-0x3df window mem 0xf5d00000-0xf6ffffff window mem disabled mem 0xa0000-0xbffff window
---
Bjorn Helgaas (7):
resource: expand IORESOURCE_TYPE_BITS to make room for bus resource type
vsprintf: clarify comments for printf_spec flags
vsprintf: move %pR resource printf_specs off the stack
resource: add bus number support
resource: add window support
PNPACPI: add window support
PNPACPI: add bus number support
drivers/pnp/base.h | 3 ++ drivers/pnp/interface.c | 7 +++-- drivers/pnp/pnpacpi/rsparser.c | 49 ++++++++++++++++++++++---------- drivers/pnp/resource.c | 27 +++++++++++++++++ drivers/pnp/support.c | 4 ++- include/linux/ioport.h | 18 ++++++------ lib/vsprintf.c | 62 +++++++++++++++++++++++++--------------- 7 files changed, 119 insertions(+), 51 deletions(-)
PATCH 1/7 resource: expand IORESOURCE_TYPE_BITS to make room for bus resource type
No functional change; this just makes room for another resource type.
---
include/linux/ioport.h | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-)
include/linux/ioport.h +8 -8
@@ -34,20 +34,20 @@ struct resource_list {*/ #define IORESOURCE_BITS 0x000000ff/* Bus-specific bits */ -#define IORESOURCE_TYPE_BITS 0x00000f00/* Resource type */ +#define IORESOURCE_TYPE_BITS 0x00001f00/* Resource type */ #define IORESOURCE_IO 0x00000100#define IORESOURCE_MEM 0x00000200#define IORESOURCE_IRQ 0x00000400#define IORESOURCE_DMA 0x00000800 -#define IORESOURCE_PREFETCH 0x00001000/* No side effects */ -#define IORESOURCE_READONLY 0x00002000 -#define IORESOURCE_CACHEABLE 0x00004000 -#define IORESOURCE_RANGELENGTH 0x00008000 -#define IORESOURCE_SHADOWABLE 0x00010000 +#define IORESOURCE_PREFETCH 0x00002000/* No side effects */ +#define IORESOURCE_READONLY 0x00004000 +#define IORESOURCE_CACHEABLE 0x00008000 +#define IORESOURCE_RANGELENGTH 0x00010000 +#define IORESOURCE_SHADOWABLE 0x00020000 -#define IORESOURCE_SIZEALIGN 0x00020000/* size indicates alignment */ -#define IORESOURCE_STARTALIGN 0x00040000/* start field is alignment */ +#define IORESOURCE_SIZEALIGN 0x00040000/* size indicates alignment */ +#define IORESOURCE_STARTALIGN 0x00080000/* start field is alignment */ #define IORESOURCE_MEM_64 0x00100000
PATCH 2/7 vsprintf: clarify comments for printf_spec flags
In reply to Bjorn HelgaasAdd clues about what the SMALL and SPECIAL flags do.
---
lib/vsprintf.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
lib/vsprintf.c +2 -2
@@ -381,8 +381,8 @@ static noinline char *put_dec(char *buf, unsigned long long num)#define PLUS 4/* show plus */ #define SPACE 8/* space if plus */ #define LEFT 16/* left justified */ -#define SMALL 32/* Must be 32 == 0x20 */ -#define SPECIAL 64/* 0x */ +#define SMALL 32/* use lowercase in hex (must be 32 == 0x20) */ +#define SPECIAL 64/* prefix hex with "0x", octal with "0 */ enum format_type {FORMAT_TYPE_NONE ,/* Just a string part */
Re: [PATCH v1 2/7] vsprintf: clarify comments for printf_spec flags
Quoted 15 lines · Bjorn Helgaas
Add clues about what the SMALL and SPECIAL flags do.
Signed-off-by Bjorn Helgaas <[email protected]>---
lib/vsprintf.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)lib/vsprintf.c +0
-0
lib/vsprintf.c static noinline char *put_dec(char *buf, unsigned long long num) · line 385
Quoted 7 lines
lib/vsprintf.c +2
-2@@ -381,8 +381,8 @@ static noinline char *put_dec(char *buf, unsigned long long num)#define PLUS 4/* show plus */ #define SPACE 8/* space if plus */ #define LEFT 16/* left justified */ -#define SMALL 32/* Must be 32 == 0x20 */ -#define SPECIAL 64/* 0x */ +#define SMALL 32/* use lowercase in hex (must be 32 == 0x20) */ +#define SPECIAL 64/* prefix hex with "0x", octal with "0 */
might as well do: octal with "0" */
Quoted 3 lines
lib/vsprintf.c +0
-0enum format_type {FORMAT_TYPE_NONE ,/* Just a string part */
Signature · 1 line
~Randy
PATCH 3/7 vsprintf: move %pR resource printf_specs off the stack
In reply to Bjorn HelgaasThis adds separate I/O and memory specs, so we don't have to change the field width in a shared spec, which then lets us make all the specs const and static, since they never change.
---
lib/vsprintf.c | 45 ++++++++++++++++++++++++--------------------- 1 files changed, 24 insertions(+), 21 deletions(-)
lib/vsprintf.c +24 -21
@@ -597,22 +597,29 @@ static char *resource_string(char *buf, char *end, struct resource *res,#ifndef MEM_RSRC_PRINTK_SIZE #define MEM_RSRC_PRINTK_SIZE 10#endif -struct printf_spec hex_spec = { +static const struct printf_spec io_spec = { .base =16 , + .field_width =IO_RSRC_PRINTK_SIZE , .precision =-1 , .flags =SPECIAL |SMALL |ZEROPAD , }; -struct printf_spec dec_spec = { +static const struct printf_spec mem_spec = { + .base =16 , + .field_width =MEM_RSRC_PRINTK_SIZE , + .precision =-1 , + .flags =SPECIAL |SMALL |ZEROPAD , + }; +static const struct printf_spec dec_spec = { .base =10 , .precision =-1 , .flags =0 , }; -struct printf_spec str_spec = { +static const struct printf_spec str_spec = { .field_width =-1 , .precision =10 , .flags =LEFT , }; -struct printf_spec flag_spec = { +static const struct printf_spec flag_spec = { .base =16 , .precision =-1 , .flags =SPECIAL |SMALL ,
@@ -628,35 +635,31 @@ static char *resource_string(char *buf, char *end, struct resource *res, 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];char *p = sym, *pend = sym +sizeof (sym); -int size =-1 , addr =0 ;int decode = (fmt[0 ] =='R' ) ?1 :0 ; - -if (res->flags &IORESOURCE_IO ) { - size =IO_RSRC_PRINTK_SIZE ; - addr =1 ; - }else if (res->flags &IORESOURCE_MEM ) { - size =MEM_RSRC_PRINTK_SIZE ; - addr =1 ; - } +const struct printf_spec *specp; *p++ ='[' ; -if (res->flags &IORESOURCE_IO ) +if (res->flags &IORESOURCE_IO ) { p =string (p, pend,"io " , str_spec); -else if (res->flags &IORESOURCE_MEM ) + specp = &io_spec; + }else if (res->flags &IORESOURCE_MEM ) { p =string (p, pend,"mem " , str_spec); -else if (res->flags &IORESOURCE_IRQ ) + specp = &mem_spec; + }else if (res->flags &IORESOURCE_IRQ ) { p =string (p, pend,"irq " , str_spec); -else if (res->flags &IORESOURCE_DMA ) + specp = &dec_spec; + }else if (res->flags &IORESOURCE_DMA ) { p =string (p, pend,"dma " , str_spec); -else { + specp = &dec_spec; + }else { p =string (p, pend,"??? " , str_spec); + specp = &mem_spec; decode =0 ; } - hex_spec.field_width = size; - p =number (p, pend, res->start, addr ? hex_spec : dec_spec); + p =number (p, pend, res->start, *specp);if (res->start != res->end) { *p++ ='-' ; - p =number (p, pend, res->end, addr ? hex_spec : dec_spec); + p =number (p, pend, res->end, *specp); }if (decode) {if (res->flags &IORESOURCE_MEM_64 )
PATCH 4/7 resource: add bus number support
In reply to Bjorn HelgaasAdd support for bus number resources. This is for bridges with a range of bus numbers behind them.
---
include/linux/ioport.h | 1 + lib/vsprintf.c | 9 +++++++++ 2 files changed, 10 insertions(+), 0 deletions(-)
include/linux/ioport.h +1 -0
@@ -39,6 +39,7 @@ struct resource_list {#define IORESOURCE_MEM 0x00000200#define IORESOURCE_IRQ 0x00000400#define IORESOURCE_DMA 0x00000800 +#define IORESOURCE_BUS 0x00001000#define IORESOURCE_PREFETCH 0x00002000/* No side effects */ #define IORESOURCE_READONLY 0x00004000
lib/vsprintf.c +9 -0
@@ -609,6 +609,12 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; +static const struct printf_spec bus_spec = { + .base =16 , + .field_width =2 , + .precision =-1 , + .flags =SMALL |ZEROPAD , + };static const struct printf_spec dec_spec = { .base =10 , .precision =-1 ,
@@ -651,6 +657,9 @@ static char *resource_string(char *buf, char *end, struct resource *res, }else if (res->flags &IORESOURCE_DMA ) { p =string (p, pend,"dma " , str_spec); specp = &dec_spec; + }else if (res->flags &IORESOURCE_BUS ) { + p =string (p, pend,"bus " , str_spec); + specp = &bus_spec; }else { p =string (p, pend,"??? " , str_spec); specp = &mem_spec;
PATCH 5/7 resource: add window support
In reply to Bjorn HelgaasAdd support for resource windows. This is for bridge resources, i.e., regions where a bridge forwards transactions from the primary to the secondary side.
---
include/linux/ioport.h | 1 + lib/vsprintf.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletions(-)
include/linux/ioport.h +1 -0
@@ -51,6 +51,7 @@ struct resource_list {#define IORESOURCE_STARTALIGN 0x00080000/* start field is alignment */ #define IORESOURCE_MEM_64 0x00100000 +#define IORESOURCE_WINDOW 0x00200000/* forwarded by bridge */ #define IORESOURCE_EXCLUSIVE 0x08000000/* Userland may not map this resource */ #define IORESOURCE_DISABLED 0x10000000
lib/vsprintf.c +3 -1
@@ -635,7 +635,7 @@ static char *resource_string(char *buf, char *end, struct resource *res,* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4)#define FLAG_BUF_SIZE (2 * sizeof(res->flags)) -#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") +#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]")#define RAW_BUF_SIZE sizeof("[mem - flags 0x]")char sym[max (2 *RSRC_BUF_SIZE +DECODED_BUF_SIZE ,2 *RSRC_BUF_SIZE +FLAG_BUF_SIZE +RAW_BUF_SIZE )];
@@ -675,6 +675,8 @@ static char *resource_string(char *buf, char *end, struct resource *res, p =string (p, pend," 64bit" , str_spec);if (res->flags &IORESOURCE_PREFETCH ) p =string (p, pend," pref" , str_spec); +if (res->flags &IORESOURCE_WINDOW ) + p =string (p, pend," window" , str_spec);if (res->flags &IORESOURCE_DISABLED ) p =string (p, pend," disabled" , str_spec); }else {
PATCH 6/7 PNPACPI: add window support
In reply to Bjorn HelgaasAdd support for resource windows. This is for bridge resources, i.e., regions where a bridge forwards transactions from the primary to the secondary side. This does not add support for *setting* windows via the /proc interface.
---
drivers/pnp/interface.c | 6 ++++-- drivers/pnp/pnpacpi/rsparser.c | 35 ++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 17 deletions(-)
drivers/pnp/interface.c +4 -2
@@ -278,9 +278,11 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,switch (pnp_resource_type (res)) {case IORESOURCE_IO :case IORESOURCE_MEM : -pnp_printf (buffer," %#llx-%#llx\n" , +pnp_printf (buffer," %#llx-%#llx%s\n" , (unsigned long long ) res->start, - (unsigned long long ) res->end); + (unsigned long long ) res->end, + res->flags &IORESOURCE_WINDOW ? +" window" :"" );break ;case IORESOURCE_IRQ :case IORESOURCE_DMA :
drivers/pnp/pnpacpi/rsparser.c +20 -15
@@ -177,7 +177,8 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master, }static void pnpacpi_parse_allocated_ioresource (struct pnp_dev *dev,u64 start, -u64 len,int io_decode) +u64 len,int io_decode, +int window) {int flags =0 ;u64 end = start + len -1 ;
@@ -186,6 +187,8 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, flags |=IORESOURCE_IO_16BIT_ADDR ;if (len ==0 || end >=0x10003 ) flags |=IORESOURCE_DISABLED ; +if (window) + flags |=IORESOURCE_WINDOW ;pnp_add_io_resource (dev, start, end, flags); }
@@ -247,7 +250,7 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,static void pnpacpi_parse_allocated_memresource (struct pnp_dev *dev,u64 start,u64 len, -int write_protect) +int write_protect,int window) {int flags =0 ;u64 end = start + len -1 ;
@@ -256,6 +259,8 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, flags |=IORESOURCE_DISABLED ;if (write_protect ==ACPI_READ_WRITE_MEMORY ) flags |=IORESOURCE_MEM_WRITEABLE ; +if (window) + flags |=IORESOURCE_WINDOW ;pnp_add_mem_resource (dev, start, end, flags); }
@@ -265,6 +270,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, {struct acpi_resource_address64 addr, *p = &addr;acpi_status status; +int window; status =acpi_resource_to_address64 (res, p);if (!ACPI_SUCCESS (status)) {
@@ -273,37 +279,36 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,return ; } -if (p->producer_consumer ==ACPI_PRODUCER ) -return ; + window = (p->producer_consumer ==ACPI_PRODUCER ) ?1 :0 ;if (p->resource_type ==ACPI_MEMORY_RANGE )pnpacpi_parse_allocated_memresource (dev, p->minimum, p->address_length, - p->info.mem.write_protect); + p->info.mem.write_protect, window);else if (p->resource_type ==ACPI_IO_RANGE )pnpacpi_parse_allocated_ioresource (dev, p->minimum, p->address_length, p->granularity ==0xfff ?ACPI_DECODE_10 : -ACPI_DECODE_16 ); +ACPI_DECODE_16 , window); }static void pnpacpi_parse_allocated_ext_address_space (struct pnp_dev *dev,struct acpi_resource *res) {struct acpi_resource_extended_address64 *p = &res->data.ext_address64; +int window; -if (p->producer_consumer ==ACPI_PRODUCER ) -return ; + window = (p->producer_consumer ==ACPI_PRODUCER ) ?1 :0 ;if (p->resource_type ==ACPI_MEMORY_RANGE )pnpacpi_parse_allocated_memresource (dev, p->minimum, p->address_length, - p->info.mem.write_protect); + p->info.mem.write_protect, window);else if (p->resource_type ==ACPI_IO_RANGE )pnpacpi_parse_allocated_ioresource (dev, p->minimum, p->address_length, p->granularity ==0xfff ?ACPI_DECODE_10 : -ACPI_DECODE_16 ); +ACPI_DECODE_16 , window); } static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
@@ -368,7 +373,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,pnpacpi_parse_allocated_ioresource (dev, io->minimum, io->address_length, - io->io_decode); + io->io_decode,0 );break ;case ACPI_RESOURCE_TYPE_START_DEPENDENT :
@@ -380,7 +385,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,pnpacpi_parse_allocated_ioresource (dev, fixed_io->address, fixed_io->address_length, -ACPI_DECODE_10 ); +ACPI_DECODE_10 ,0 );break ;case ACPI_RESOURCE_TYPE_VENDOR :
@@ -396,21 +401,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,pnpacpi_parse_allocated_memresource (dev, memory24->minimum, memory24->address_length, - memory24->write_protect); + memory24->write_protect,0 );break ;case ACPI_RESOURCE_TYPE_MEMORY32 : memory32 = &res->data.memory32;pnpacpi_parse_allocated_memresource (dev, memory32->minimum, memory32->address_length, - memory32->write_protect); + memory32->write_protect,0 );break ;case ACPI_RESOURCE_TYPE_FIXED_MEMORY32 : fixed_memory32 = &res->data.fixed_memory32;pnpacpi_parse_allocated_memresource (dev, fixed_memory32->address, fixed_memory32->address_length, - fixed_memory32->write_protect); + fixed_memory32->write_protect,0 );break ;case ACPI_RESOURCE_TYPE_ADDRESS16 :case ACPI_RESOURCE_TYPE_ADDRESS32 :
PATCH 7/7 PNPACPI: add bus number support
In reply to Bjorn HelgaasAdd support for bus number resources. This is for bridges with a range of bus numbers behind them. Previously, PNP ignored bus number resources.
---
drivers/pnp/base.h | 3 +++ drivers/pnp/interface.c | 1 + drivers/pnp/pnpacpi/rsparser.c | 14 ++++++++++++++ drivers/pnp/resource.c | 27 ++++++++++++++++++++++++++- drivers/pnp/support.c | 4 +++- 5 files changed, 47 insertions(+), 2 deletions(-)
drivers/pnp/base.h +3 -0
@@ -166,6 +166,9 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,struct pnp_resource *pnp_add_mem_resource (struct pnp_dev *dev,resource_size_t start,resource_size_t end,int flags); +struct pnp_resource *pnp_add_bus_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end);extern int pnp_debug;
drivers/pnp/interface.c +1 -0
@@ -278,6 +278,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,switch (pnp_resource_type (res)) {case IORESOURCE_IO :case IORESOURCE_MEM : +case IORESOURCE_BUS : pnp_printf(buffer, " %#llx-%#llx%s\n", (unsigned long long) res->start, (unsigned long long) res->end,
drivers/pnp/pnpacpi/rsparser.c +14 -0
@@ -265,6 +265,14 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,pnp_add_mem_resource (dev, start, end, flags); } +static void pnpacpi_parse_allocated_busresource (struct pnp_dev *dev, +u64 start,u64 len) +{ +u64 end = start + len -1 ; + +pnp_add_bus_resource (dev, start, end); +} +static void pnpacpi_parse_allocated_address_space (struct pnp_dev *dev,struct acpi_resource *res) {
@@ -290,6 +298,9 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, p->minimum, p->address_length, p->granularity ==0xfff ?ACPI_DECODE_10 : ACPI_DECODE_16, window); + else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) + pnpacpi_parse_allocated_busresource(dev, p->minimum, + p->address_length); } static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
@@ -309,6 +320,9 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, p->minimum, p->address_length, p->granularity ==0xfff ?ACPI_DECODE_10 : ACPI_DECODE_16, window); + else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) + pnpacpi_parse_allocated_busresource(dev, p->minimum, + p->address_length); } static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
drivers/pnp/resource.c +26 -1
@@ -470,7 +470,8 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)unsigned long pnp_resource_type (struct resource *res) {return res->flags & (IORESOURCE_IO |IORESOURCE_MEM | -IORESOURCE_IRQ |IORESOURCE_DMA ); +IORESOURCE_IRQ |IORESOURCE_DMA | +IORESOURCE_BUS ); } struct resource *pnp_get_resource(struct pnp_dev *dev,
@@ -590,6 +591,30 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,return pnp_res; } +struct pnp_resource *pnp_add_bus_resource (struct pnp_dev *dev, +resource_size_t start, +resource_size_t end) +{ +struct pnp_resource *pnp_res; +struct resource *res; + + pnp_res =pnp_new_resource (dev); +if (!pnp_res) { +dev_err (&dev->dev,"can't add resource for BUS %#llx-%#llx\n" , + (unsigned long long ) start, + (unsigned long long ) end); +return NULL ; + } + + res = &pnp_res->res; + res->flags =IORESOURCE_BUS ; + res->start = start; + res->end = end; + +pnp_dbg (&dev->dev," add %pr\n" , res); +return pnp_res; +} +/* * Determine whether the specified resource is a possible configuration * for this device.
drivers/pnp/support.c +3 -1
@@ -69,8 +69,10 @@ char *pnp_resource_type_name(struct resource *res)return "irq" ;case IORESOURCE_DMA :return "dma" ; +case IORESOURCE_BUS : +return "bus" ; } -return NULL ; +return "unknown" ; }void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc)