Skip to content

Commit 7efe5d7

Browse files
author
Linus Torvalds
committed
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
2 parents dbe0580 + f8977d0 commit 7efe5d7

37 files changed

+739
-6349
lines changed

Documentation/DocBook/kernel-api.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ X!Edrivers/pci/search.c
286286
-->
287287
!Edrivers/pci/msi.c
288288
!Edrivers/pci/bus.c
289-
!Edrivers/pci/hotplug.c
289+
<!-- FIXME: Removed for now since no structured comments in source
290+
X!Edrivers/pci/hotplug.c
291+
-->
290292
!Edrivers/pci/probe.c
291293
!Edrivers/pci/rom.c
292294
</sect1>

arch/i386/pci/fixup.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
33
*/
44

5+
#include <linux/delay.h>
6+
#include <linux/dmi.h>
57
#include <linux/pci.h>
68
#include <linux/init.h>
79
#include "pci.h"
@@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
384386
}
385387
}
386388
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
389+
390+
/*
391+
* Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
392+
*
393+
* We pretend to bring them out of full D3 state, and restore the proper
394+
* IRQ, PCI cache line size, and BARs, otherwise the device won't function
395+
* properly. In some cases, the device will generate an interrupt on
396+
* the wrong IRQ line, causing any devices sharing the the line it's
397+
* *supposed* to use to be disabled by the kernel's IRQ debug code.
398+
*/
399+
static u16 toshiba_line_size;
400+
401+
static struct dmi_system_id __devinit toshiba_ohci1394_dmi_table[] = {
402+
{
403+
.ident = "Toshiba PS5 based laptop",
404+
.matches = {
405+
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
406+
DMI_MATCH(DMI_PRODUCT_VERSION, "PS5"),
407+
},
408+
},
409+
{
410+
.ident = "Toshiba PSM4 based laptop",
411+
.matches = {
412+
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
413+
DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"),
414+
},
415+
},
416+
{ }
417+
};
418+
419+
static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
420+
{
421+
if (!dmi_check_system(toshiba_ohci1394_dmi_table))
422+
return; /* only applies to certain Toshibas (so far) */
423+
424+
dev->current_state = PCI_D3cold;
425+
pci_read_config_word(dev, PCI_CACHE_LINE_SIZE, &toshiba_line_size);
426+
}
427+
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032,
428+
pci_pre_fixup_toshiba_ohci1394);
429+
430+
static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
431+
{
432+
if (!dmi_check_system(toshiba_ohci1394_dmi_table))
433+
return; /* only applies to certain Toshibas (so far) */
434+
435+
/* Restore config space on Toshiba laptops */
436+
mdelay(10);
437+
pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
438+
pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq);
439+
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
440+
pci_resource_start(dev, 0));
441+
pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
442+
pci_resource_start(dev, 1));
443+
}
444+
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
445+
pci_post_fixup_toshiba_ohci1394);

drivers/pci/access.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,92 @@ EXPORT_SYMBOL(pci_bus_read_config_dword);
6060
EXPORT_SYMBOL(pci_bus_write_config_byte);
6161
EXPORT_SYMBOL(pci_bus_write_config_word);
6262
EXPORT_SYMBOL(pci_bus_write_config_dword);
63+
64+
static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
65+
{
66+
u32 data;
67+
68+
data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
69+
data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
70+
return data;
71+
}
72+
73+
#define PCI_USER_READ_CONFIG(size,type) \
74+
int pci_user_read_config_##size \
75+
(struct pci_dev *dev, int pos, type *val) \
76+
{ \
77+
unsigned long flags; \
78+
int ret = 0; \
79+
u32 data = -1; \
80+
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
81+
spin_lock_irqsave(&pci_lock, flags); \
82+
if (likely(!dev->block_ucfg_access)) \
83+
ret = dev->bus->ops->read(dev->bus, dev->devfn, \
84+
pos, sizeof(type), &data); \
85+
else if (pos < sizeof(dev->saved_config_space)) \
86+
data = pci_user_cached_config(dev, pos); \
87+
spin_unlock_irqrestore(&pci_lock, flags); \
88+
*val = (type)data; \
89+
return ret; \
90+
}
91+
92+
#define PCI_USER_WRITE_CONFIG(size,type) \
93+
int pci_user_write_config_##size \
94+
(struct pci_dev *dev, int pos, type val) \
95+
{ \
96+
unsigned long flags; \
97+
int ret = -EIO; \
98+
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
99+
spin_lock_irqsave(&pci_lock, flags); \
100+
if (likely(!dev->block_ucfg_access)) \
101+
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
102+
pos, sizeof(type), val); \
103+
spin_unlock_irqrestore(&pci_lock, flags); \
104+
return ret; \
105+
}
106+
107+
PCI_USER_READ_CONFIG(byte, u8)
108+
PCI_USER_READ_CONFIG(word, u16)
109+
PCI_USER_READ_CONFIG(dword, u32)
110+
PCI_USER_WRITE_CONFIG(byte, u8)
111+
PCI_USER_WRITE_CONFIG(word, u16)
112+
PCI_USER_WRITE_CONFIG(dword, u32)
113+
114+
/**
115+
* pci_block_user_cfg_access - Block userspace PCI config reads/writes
116+
* @dev: pci device struct
117+
*
118+
* This function blocks any userspace PCI config accesses from occurring.
119+
* When blocked, any writes will be bit bucketed and reads will return the
120+
* data saved using pci_save_state for the first 64 bytes of config
121+
* space and return 0xff for all other config reads.
122+
**/
123+
void pci_block_user_cfg_access(struct pci_dev *dev)
124+
{
125+
unsigned long flags;
126+
127+
pci_save_state(dev);
128+
129+
/* spinlock to synchronize with anyone reading config space now */
130+
spin_lock_irqsave(&pci_lock, flags);
131+
dev->block_ucfg_access = 1;
132+
spin_unlock_irqrestore(&pci_lock, flags);
133+
}
134+
EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
135+
136+
/**
137+
* pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
138+
* @dev: pci device struct
139+
*
140+
* This function allows userspace PCI config accesses to resume.
141+
**/
142+
void pci_unblock_user_cfg_access(struct pci_dev *dev)
143+
{
144+
unsigned long flags;
145+
146+
/* spinlock to synchronize with anyone reading saved config space */
147+
spin_lock_irqsave(&pci_lock, flags);
148+
dev->block_ucfg_access = 0;
149+
spin_unlock_irqrestore(&pci_lock, flags);
150+
}
151+
EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);

drivers/pci/hotplug/acpiphp_glue.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list);
5858

5959
static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
6060
static void handle_hotplug_event_func (acpi_handle, u32, void *);
61+
static void acpiphp_sanitize_bus(struct pci_bus *bus);
62+
static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
63+
6164

6265
/*
6366
* initialization & terminatation routines
@@ -796,8 +799,13 @@ static int enable_device(struct acpiphp_slot *slot)
796799
}
797800
}
798801

802+
pci_bus_size_bridges(bus);
799803
pci_bus_assign_resources(bus);
804+
acpiphp_sanitize_bus(bus);
805+
pci_enable_bridges(bus);
800806
pci_bus_add_devices(bus);
807+
acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus);
808+
acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev));
801809

802810
/* associate pci_dev to our representation */
803811
list_for_each (l, &slot->funcs) {

drivers/pci/hotplug/cpcihp_zt5550.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,20 @@ static void __iomem *csr_int_mask;
7878

7979
static int zt5550_hc_config(struct pci_dev *pdev)
8080
{
81+
int ret;
82+
8183
/* Since we know that no boards exist with two HC chips, treat it as an error */
8284
if(hc_dev) {
8385
err("too many host controller devices?");
8486
return -EBUSY;
8587
}
88+
89+
ret = pci_enable_device(pdev);
90+
if(ret) {
91+
err("cannot enable %s\n", pci_name(pdev));
92+
return ret;
93+
}
94+
8695
hc_dev = pdev;
8796
dbg("hc_dev = %p", hc_dev);
8897
dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
@@ -91,17 +100,17 @@ static int zt5550_hc_config(struct pci_dev *pdev)
91100
if(!request_mem_region(pci_resource_start(hc_dev, 1),
92101
pci_resource_len(hc_dev, 1), MY_NAME)) {
93102
err("cannot reserve MMIO region");
94-
return -ENOMEM;
103+
ret = -ENOMEM;
104+
goto exit_disable_device;
95105
}
96106

97107
hc_registers =
98108
ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
99109
if(!hc_registers) {
100110
err("cannot remap MMIO region %lx @ %lx",
101111
pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
102-
release_mem_region(pci_resource_start(hc_dev, 1),
103-
pci_resource_len(hc_dev, 1));
104-
return -ENODEV;
112+
ret = -ENODEV;
113+
goto exit_release_region;
105114
}
106115

107116
csr_hc_index = hc_registers + CSR_HCINDEX;
@@ -124,6 +133,13 @@ static int zt5550_hc_config(struct pci_dev *pdev)
124133
writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
125134
dbg("disabled timer0, timer1 and ENUM interrupts");
126135
return 0;
136+
137+
exit_release_region:
138+
release_mem_region(pci_resource_start(hc_dev, 1),
139+
pci_resource_len(hc_dev, 1));
140+
exit_disable_device:
141+
pci_disable_device(hc_dev);
142+
return ret;
127143
}
128144

129145
static int zt5550_hc_cleanup(void)
@@ -134,6 +150,7 @@ static int zt5550_hc_cleanup(void)
134150
iounmap(hc_registers);
135151
release_mem_region(pci_resource_start(hc_dev, 1),
136152
pci_resource_len(hc_dev, 1));
153+
pci_disable_device(hc_dev);
137154
return 0;
138155
}
139156

drivers/pci/hotplug/cpqphp_core.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -794,20 +794,30 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
794794
u32 rc;
795795
struct controller *ctrl;
796796
struct pci_func *func;
797+
int err;
798+
799+
err = pci_enable_device(pdev);
800+
if (err) {
801+
printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
802+
pci_name(pdev), err);
803+
return err;
804+
}
797805

798806
// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
799807
rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
800808
if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
801809
err(msg_HPC_non_compaq_or_intel);
802-
return -ENODEV;
810+
rc = -ENODEV;
811+
goto err_disable_device;
803812
}
804813
dbg("Vendor ID: %x\n", vendor_id);
805814

806815
rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
807816
dbg("revision: %d\n", rev);
808817
if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
809818
err(msg_HPC_rev_error);
810-
return -ENODEV;
819+
rc = -ENODEV;
820+
goto err_disable_device;
811821
}
812822

813823
/* Check for the proper subsytem ID's
@@ -820,18 +830,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
820830
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
821831
if (rc) {
822832
err("%s : pci_read_config_word failed\n", __FUNCTION__);
823-
return rc;
833+
goto err_disable_device;
824834
}
825835
dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
826836
if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
827837
err(msg_HPC_non_compaq_or_intel);
828-
return -ENODEV;
838+
rc = -ENODEV;
839+
goto err_disable_device;
829840
}
830841

831842
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
832843
if (!ctrl) {
833844
err("%s : out of memory\n", __FUNCTION__);
834-
return -ENOMEM;
845+
rc = -ENOMEM;
846+
goto err_disable_device;
835847
}
836848
memset(ctrl, 0, sizeof(struct controller));
837849

@@ -1264,6 +1276,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
12641276
kfree(ctrl->pci_bus);
12651277
err_free_ctrl:
12661278
kfree(ctrl);
1279+
err_disable_device:
1280+
pci_disable_device(pdev);
12671281
return rc;
12681282
}
12691283

drivers/pci/hotplug/rpaphp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,10 @@ extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn);
9292
extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
9393
extern int rpaphp_enable_pci_slot(struct slot *slot);
9494
extern int register_pci_slot(struct slot *slot);
95-
extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
9695
extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
96+
9797
extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
98+
extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
9899

99100
/* rpaphp_core.c */
100101
extern int rpaphp_add_slot(struct device_node *dn);

drivers/pci/hotplug/rpaphp_core.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,11 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
426426

427427
dbg("DISABLING SLOT %s\n", slot->name);
428428
down(&rpaphp_sem);
429-
retval = rpaphp_unconfig_pci_adapter(slot);
429+
retval = rpaphp_unconfig_pci_adapter(slot->bus);
430430
up(&rpaphp_sem);
431+
slot->state = NOT_CONFIGURED;
432+
info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
433+
slot->name);
431434
exit:
432435
dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
433436
return retval;

drivers/pci/hotplug/rpaphp_pci.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,20 +319,15 @@ static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
319319
return;
320320
}
321321

322-
int rpaphp_unconfig_pci_adapter(struct slot *slot)
322+
int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
323323
{
324324
struct pci_dev *dev, *tmp;
325-
int retval = 0;
326325

327-
list_for_each_entry_safe(dev, tmp, slot->pci_devs, bus_list) {
326+
list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
328327
rpaphp_eeh_remove_bus_device(dev);
329328
pci_remove_bus_device(dev);
330329
}
331-
332-
slot->state = NOT_CONFIGURED;
333-
info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
334-
slot->name);
335-
return retval;
330+
return 0;
336331
}
337332

338333
static int setup_pci_hotplug_slot_info(struct slot *slot)

0 commit comments

Comments
 (0)