Revision 93d2175d3d31f11ba04fcfa0e9a496a1b4bc8b34 authored by Yinghai Lu on 14 May 2011, 01:06:17 UTC, committed by Linus Torvalds on 17 May 2011, 01:33:35 UTC
During pci remove/rescan testing found:

  pci 0000:c0:03.0: PCI bridge to [bus c4-c9]
  pci 0000:c0:03.0:   bridge window [io  0x1000-0x0fff]
  pci 0000:c0:03.0:   bridge window [mem 0xf0000000-0xf00fffff]
  pci 0000:c0:03.0:   bridge window [mem 0xfc180000000-0xfc197ffffff 64bit pref]
  pci 0000:c0:03.0: device not available (can't reserve [io  0x1000-0x0fff])
  pci 0000:c0:03.0: Error enabling bridge (-22), continuing
  pci 0000:c0:03.0: enabling bus mastering
  pci 0000:c0:03.0: setting latency timer to 64
  pcieport 0000:c0:03.0: device not available (can't reserve [io  0x1000-0x0fff])
  pcieport: probe of 0000:c0:03.0 failed with error -22

This bug was caused by commit c8adf9a3e873 ("PCI: pre-allocate
additional resources to devices only after successful allocation of
essential resources.")

After that commit, pci_hotplug_io_size is changed to additional_io_size
from minium size.  So it will not go through resource_size(res) != 0
path, and will not be reset.

The root cause is: pci_bridge_check_ranges will set RESOURCE_IO flag for
pci bridge, and later if children do not need IO resource.  those bridge
resources will not need to be allocated.  but flags is still there.
that will confuse the the pci_enable_bridges later.

related code:

   static void assign_requested_resources_sorted(struct resource_list *head,
                                    struct resource_list_x *fail_head)
   {
           struct resource *res;
           struct resource_list *list;
           int idx;

           for (list = head->next; list; list = list->next) {
                   res = list->res;
                   idx = res - &list->dev->resource[0];
                   if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
   ...
                           reset_resource(res);
                   }
           }
   }

At last, We have to clear the flags in pbus_size_mem/io when requested
size == 0 and !add_head.  becasue this case it will not go through
adjust_resources_sorted().

Just make size1 = size0 when !add_head. it will make flags get cleared.

At the same time when requested size == 0, add_size != 0, will still
have in head and add_list.  because we do not clear the flags for it.

After this, we will get right result:

  pci 0000:c0:03.0: PCI bridge to [bus c4-c9]
  pci 0000:c0:03.0:   bridge window [io  disabled]
  pci 0000:c0:03.0:   bridge window [mem 0xf0000000-0xf00fffff]
  pci 0000:c0:03.0:   bridge window [mem 0xfc180000000-0xfc197ffffff 64bit pref]
  pci 0000:c0:03.0: enabling bus mastering
  pci 0000:c0:03.0: setting latency timer to 64
  pcieport 0000:c0:03.0: setting latency timer to 64
  pcieport 0000:c0:03.0: irq 160 for MSI/MSI-X
  pcieport 0000:c0:03.0: Signaling PME through PCIe PME interrupt
  pci 0000:c4:00.0: Signaling PME through PCIe PME interrupt
  pcie_pme 0000:c0:03.0:pcie01: service driver pcie_pme loaded
  aer 0000:c0:03.0:pcie02: service driver aer loaded
  pciehp 0000:c0:03.0:pcie04: Hotplug Controller:

v3: more simple fix. also fix one typo in pbus_size_mem

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent df8d06a
Raw File
gdb-io-ttysm-low.S
###############################################################################
#
# MN10300 On-chip serial Rx interrupt handler for GDB stub I/O
#
# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public Licence
# as published by the Free Software Foundation; either version
# 2 of the Licence, or (at your option) any later version.
#
###############################################################################
#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/smp.h>
#include <asm/thread_info.h>
#include <asm/cpu-regs.h>
#include <asm/frame.inc>
#include <asm/intctl-regs.h>
#include <unit/serial.h>
#include "mn10300-serial.h"

	.text

###############################################################################
#
# GDB stub serial receive interrupt entry point
# - intended to run at interrupt priority 0
#
###############################################################################
	.globl	gdbstub_io_rx_handler
	.type	gdbstub_io_rx_handler,@function
gdbstub_io_rx_handler:
	movm	[d2,d3,a2,a3],(sp)

	mov	(gdbstub_rx_inp),a3
gdbstub_io_rx_more:
	mov	a3,a2
	add	2,a3
	and	PAGE_SIZE_asm-1,a3
	mov	(gdbstub_rx_outp),d3
	cmp	a3,d3
	beq	gdbstub_io_rx_overflow

	movbu	(SCgSTR),d3
	btst	SC01STR_RBF,d3
	beq	gdbstub_io_rx_done
	movbu	(SCgRXB),d2
	movbu	d3,(gdbstub_rx_buffer+1,a2)
	movbu	d2,(gdbstub_rx_buffer,a2)
	mov	a3,(gdbstub_rx_inp)
	bra	gdbstub_io_rx_more

gdbstub_io_rx_done:
	mov	GxICR_DETECT,d2
	movbu	d2,(GxICR(SCgRXIRQ))	# ACK the interrupt
	movhu	(GxICR(SCgRXIRQ)),d2	# flush

	movm	(sp),[d2,d3,a2,a3]
	bset	0x01,(gdbstub_busy)
	beq	gdbstub_io_rx_enter
	rti

gdbstub_io_rx_overflow:
	bset	0x01,(gdbstub_rx_overflow)
	bra	gdbstub_io_rx_done

###############################################################################
#
# debugging interrupt - enter the GDB stub proper
#
###############################################################################
gdbstub_io_rx_enter:
	or	EPSW_IE|EPSW_IM_1,epsw
	add	-4,sp
	SAVE_ALL

	mov	0xffffffff,d0
	mov	d0,(REG_ORIG_D0,fp)
	mov	0x280,d1

	mov	fp,d0
	call	gdbstub_rx_irq[],0	# gdbstub_io_rx_irq(regs,excep)

	and	~EPSW_IE,epsw
	bclr	0x01,(gdbstub_busy)

	.globl gdbstub_return
gdbstub_return:
	RESTORE_ALL

	.size	gdbstub_io_rx_handler,.-gdbstub_io_rx_handler
back to top