diff options
-rw-r--r-- | CREDITS | 5 | ||||
-rw-r--r-- | arch/i386/pci/fixup.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 2 | ||||
-rw-r--r-- | drivers/char/raw.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug.c | 119 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug.h | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 169 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 352 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 156 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 30 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 12 | ||||
-rw-r--r-- | drivers/pci/pci.h | 27 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_bus.c | 3 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 12 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 5 | ||||
-rw-r--r-- | drivers/scsi/sata_svw.c | 2 | ||||
-rw-r--r-- | fs/ext3/super.c | 10 | ||||
-rw-r--r-- | include/linux/libata.h | 7 |
21 files changed, 267 insertions, 655 deletions
@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061 | |||
882 | S: USA | 882 | S: USA |
883 | 883 | ||
884 | N: Randy Dunlap | 884 | N: Randy Dunlap |
885 | E: rddunlap@osdl.org | 885 | E: rdunlap@xenotime.net |
886 | W: http://www.xenotime.net/linux/linux.html | 886 | W: http://www.xenotime.net/linux/linux.html |
887 | W: http://www.linux-usb.org | 887 | W: http://www.linux-usb.org |
888 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers | 888 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers |
889 | D: x86 SMP, ACPI, bootflag hacking | 889 | D: x86 SMP, ACPI, bootflag hacking |
890 | S: 12725 SW Millikan Way, Suite 400 | 890 | S: (ask for current address) |
891 | S: Beaverton, Oregon 97005 | ||
892 | S: USA | 891 | S: USA |
893 | 892 | ||
894 | N: Bob Dunlop | 893 | N: Bob Dunlop |
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index be52c5ac4e05..8e8e895e1b5a 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci | |||
253 | #define MAX_PCIEROOT 6 | 253 | #define MAX_PCIEROOT 6 |
254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; | 254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; |
255 | 255 | ||
256 | #define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b) | 256 | #define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7)) |
257 | 257 | ||
258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
259 | { | 259 | { |
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 5dfb42f1a152..309797d7f96d 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -753,6 +753,8 @@ void __init setup_arch(char **cmdline_p) | |||
753 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | 753 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); |
754 | *cmdline_p = cmd_line; | 754 | *cmdline_p = cmd_line; |
755 | 755 | ||
756 | parse_early_param(); | ||
757 | |||
756 | /* set up the bootmem stuff with available memory */ | 758 | /* set up the bootmem stuff with available memory */ |
757 | do_init_bootmem(); | 759 | do_init_bootmem(); |
758 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); | 760 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 131465e8de5a..ca5f42bcaad9 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, | |||
122 | { | 122 | { |
123 | struct block_device *bdev = filp->private_data; | 123 | struct block_device *bdev = filp->private_data; |
124 | 124 | ||
125 | return blkdev_ioctl(bdev->bd_inode, filp, command, arg); | 125 | return blkdev_ioctl(bdev->bd_inode, NULL, command, arg); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void bind_device(struct raw_config_request *rq) | 128 | static void bind_device(struct raw_config_request *rq) |
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 021d0f76bc4c..3903f8c559b6 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c | |||
@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, | |||
52 | if ((buffer_size - length <= 0) || (i >= num_envp)) | 52 | if ((buffer_size - length <= 0) || (i >= num_envp)) |
53 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | 54 | ||
55 | envp[i++] = scratch; | ||
56 | length += scnprintf (scratch, buffer_size - length, | ||
57 | "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", | ||
58 | pdev->vendor, pdev->device, | ||
59 | pdev->subsystem_vendor, pdev->subsystem_device, | ||
60 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), | ||
61 | (u8)(pdev->class)); | ||
62 | if ((buffer_size - length <= 0) || (i >= num_envp)) | ||
63 | return -ENOMEM; | ||
64 | |||
55 | envp[i] = NULL; | 65 | envp[i] = NULL; |
56 | 66 | ||
57 | return 0; | 67 | return 0; |
58 | } | 68 | } |
59 | |||
60 | static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent) | ||
61 | { | ||
62 | struct list_head *ln; | ||
63 | struct pci_dev *dev; | ||
64 | struct pci_dev_wrapped wrapped_dev; | ||
65 | int result = 0; | ||
66 | |||
67 | pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus), | ||
68 | wrapped_bus->bus->number); | ||
69 | |||
70 | if (fn->pre_visit_pci_bus) { | ||
71 | result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent); | ||
72 | if (result) | ||
73 | return result; | ||
74 | } | ||
75 | |||
76 | ln = wrapped_bus->bus->devices.next; | ||
77 | while (ln != &wrapped_bus->bus->devices) { | ||
78 | dev = pci_dev_b(ln); | ||
79 | ln = ln->next; | ||
80 | |||
81 | memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); | ||
82 | wrapped_dev.dev = dev; | ||
83 | |||
84 | result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus); | ||
85 | if (result) | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | if (fn->post_visit_pci_bus) | ||
90 | result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent); | ||
91 | |||
92 | return result; | ||
93 | } | ||
94 | |||
95 | static int pci_visit_bridge (struct pci_visit * fn, | ||
96 | struct pci_dev_wrapped *wrapped_dev, | ||
97 | struct pci_bus_wrapped *wrapped_parent) | ||
98 | { | ||
99 | struct pci_bus *bus; | ||
100 | struct pci_bus_wrapped wrapped_bus; | ||
101 | int result = 0; | ||
102 | |||
103 | pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev)); | ||
104 | |||
105 | if (fn->visit_pci_dev) { | ||
106 | result = fn->visit_pci_dev(wrapped_dev, wrapped_parent); | ||
107 | if (result) | ||
108 | return result; | ||
109 | } | ||
110 | |||
111 | bus = wrapped_dev->dev->subordinate; | ||
112 | if (bus) { | ||
113 | memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); | ||
114 | wrapped_bus.bus = bus; | ||
115 | |||
116 | result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev); | ||
117 | } | ||
118 | return result; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * pci_visit_dev - scans the pci buses. | ||
123 | * @fn: callback functions that are called while visiting | ||
124 | * @wrapped_dev: the device to scan | ||
125 | * @wrapped_parent: the bus where @wrapped_dev is connected to | ||
126 | * | ||
127 | * Every bus and every function is presented to a custom | ||
128 | * function that can act upon it. | ||
129 | */ | ||
130 | int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, | ||
131 | struct pci_bus_wrapped *wrapped_parent) | ||
132 | { | ||
133 | struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL; | ||
134 | int result = 0; | ||
135 | |||
136 | if (!dev) | ||
137 | return 0; | ||
138 | |||
139 | if (fn->pre_visit_pci_dev) { | ||
140 | result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent); | ||
141 | if (result) | ||
142 | return result; | ||
143 | } | ||
144 | |||
145 | switch (dev->class >> 8) { | ||
146 | case PCI_CLASS_BRIDGE_PCI: | ||
147 | result = pci_visit_bridge(fn, wrapped_dev, | ||
148 | wrapped_parent); | ||
149 | if (result) | ||
150 | return result; | ||
151 | break; | ||
152 | default: | ||
153 | pr_debug("PCI: Scanning device %s\n", pci_name(dev)); | ||
154 | if (fn->visit_pci_dev) { | ||
155 | result = fn->visit_pci_dev (wrapped_dev, | ||
156 | wrapped_parent); | ||
157 | if (result) | ||
158 | return result; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (fn->post_visit_pci_dev) | ||
163 | result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent); | ||
164 | |||
165 | return result; | ||
166 | } | ||
167 | EXPORT_SYMBOL(pci_visit_dev); | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 3ddd75937a40..d9769b30be9a 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | 33 | ||
34 | /* PICMG 2.12 R2.0 HS CSR bits: */ | 34 | /* PICMG 2.1 R2.0 HS CSR bits: */ |
35 | #define HS_CSR_INS 0x0080 | 35 | #define HS_CSR_INS 0x0080 |
36 | #define HS_CSR_EXT 0x0040 | 36 | #define HS_CSR_EXT 0x0040 |
37 | #define HS_CSR_PI 0x0030 | 37 | #define HS_CSR_PI 0x0030 |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index ed243605dc7b..9e9dab7fe86a 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <asm/atomic.h> | ||
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
37 | #include "pci_hotplug.h" | 38 | #include "pci_hotplug.h" |
38 | #include "cpci_hotplug.h" | 39 | #include "cpci_hotplug.h" |
39 | 40 | ||
40 | #define DRIVER_VERSION "0.2" | ||
41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
42 | #define DRIVER_DESC "CompactPCI Hot Plug Core" | 42 | #define DRIVER_DESC "CompactPCI Hot Plug Core" |
43 | 43 | ||
@@ -54,9 +54,10 @@ | |||
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
55 | 55 | ||
56 | /* local variables */ | 56 | /* local variables */ |
57 | static spinlock_t list_lock; | 57 | static DECLARE_RWSEM(list_rwsem); |
58 | static LIST_HEAD(slot_list); | 58 | static LIST_HEAD(slot_list); |
59 | static int slots; | 59 | static int slots; |
60 | static atomic_t extracting; | ||
60 | int cpci_debug; | 61 | int cpci_debug; |
61 | static struct cpci_hp_controller *controller; | 62 | static struct cpci_hp_controller *controller; |
62 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | 63 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ |
@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot); | |||
68 | static int set_attention_status(struct hotplug_slot *slot, u8 value); | 69 | static int set_attention_status(struct hotplug_slot *slot, u8 value); |
69 | static int get_power_status(struct hotplug_slot *slot, u8 * value); | 70 | static int get_power_status(struct hotplug_slot *slot, u8 * value); |
70 | static int get_attention_status(struct hotplug_slot *slot, u8 * value); | 71 | static int get_attention_status(struct hotplug_slot *slot, u8 * value); |
72 | static int get_adapter_status(struct hotplug_slot *slot, u8 * value); | ||
73 | static int get_latch_status(struct hotplug_slot *slot, u8 * value); | ||
71 | 74 | ||
72 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { | 75 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { |
73 | .owner = THIS_MODULE, | 76 | .owner = THIS_MODULE, |
@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = { | |||
76 | .set_attention_status = set_attention_status, | 79 | .set_attention_status = set_attention_status, |
77 | .get_power_status = get_power_status, | 80 | .get_power_status = get_power_status, |
78 | .get_attention_status = get_attention_status, | 81 | .get_attention_status = get_attention_status, |
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_latch_status = get_latch_status, | ||
79 | }; | 84 | }; |
80 | 85 | ||
81 | static int | 86 | static int |
@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
148 | warn("failure to update adapter file"); | 153 | warn("failure to update adapter file"); |
149 | } | 154 | } |
150 | 155 | ||
151 | slot->extracting = 0; | 156 | if(slot->extracting) { |
152 | 157 | slot->extracting = 0; | |
158 | atomic_dec(&extracting); | ||
159 | } | ||
153 | return retval; | 160 | return retval; |
154 | } | 161 | } |
155 | 162 | ||
@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
188 | return cpci_set_attention_status(hotplug_slot->private, status); | 195 | return cpci_set_attention_status(hotplug_slot->private, status); |
189 | } | 196 | } |
190 | 197 | ||
198 | static int | ||
199 | get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) | ||
200 | { | ||
201 | *value = hotplug_slot->info->adapter_status; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int | ||
206 | get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) | ||
207 | { | ||
208 | *value = hotplug_slot->info->latch_status; | ||
209 | return 0; | ||
210 | } | ||
211 | |||
191 | static void release_slot(struct hotplug_slot *hotplug_slot) | 212 | static void release_slot(struct hotplug_slot *hotplug_slot) |
192 | { | 213 | { |
193 | struct slot *slot = hotplug_slot->private; | 214 | struct slot *slot = hotplug_slot->private; |
@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) | |||
273 | } | 294 | } |
274 | 295 | ||
275 | /* Add slot to our internal list */ | 296 | /* Add slot to our internal list */ |
276 | spin_lock(&list_lock); | 297 | down_write(&list_rwsem); |
277 | list_add(&slot->slot_list, &slot_list); | 298 | list_add(&slot->slot_list, &slot_list); |
278 | slots++; | 299 | slots++; |
279 | spin_unlock(&list_lock); | 300 | up_write(&list_rwsem); |
280 | } | 301 | } |
281 | return 0; | 302 | return 0; |
282 | error_name: | 303 | error_name: |
@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus) | |||
299 | struct list_head *next; | 320 | struct list_head *next; |
300 | int status; | 321 | int status; |
301 | 322 | ||
302 | spin_lock(&list_lock); | 323 | down_write(&list_rwsem); |
303 | if(!slots) { | 324 | if(!slots) { |
304 | spin_unlock(&list_lock); | 325 | up_write(&list_rwsem); |
305 | return -1; | 326 | return -1; |
306 | } | 327 | } |
307 | list_for_each_safe(tmp, next, &slot_list) { | 328 | list_for_each_safe(tmp, next, &slot_list) { |
@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) | |||
319 | slots--; | 340 | slots--; |
320 | } | 341 | } |
321 | } | 342 | } |
322 | spin_unlock(&list_lock); | 343 | up_write(&list_rwsem); |
323 | return 0; | 344 | return 0; |
324 | } | 345 | } |
325 | 346 | ||
@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
347 | } | 368 | } |
348 | 369 | ||
349 | /* | 370 | /* |
350 | * According to PICMG 2.12 R2.0, section 6.3.2, upon | 371 | * According to PICMG 2.1 R2.0, section 6.3.2, upon |
351 | * initialization, the system driver shall clear the | 372 | * initialization, the system driver shall clear the |
352 | * INS bits of the cold-inserted devices. | 373 | * INS bits of the cold-inserted devices. |
353 | */ | 374 | */ |
@@ -359,9 +380,9 @@ init_slots(void) | |||
359 | struct pci_dev* dev; | 380 | struct pci_dev* dev; |
360 | 381 | ||
361 | dbg("%s - enter", __FUNCTION__); | 382 | dbg("%s - enter", __FUNCTION__); |
362 | spin_lock(&list_lock); | 383 | down_read(&list_rwsem); |
363 | if(!slots) { | 384 | if(!slots) { |
364 | spin_unlock(&list_lock); | 385 | up_read(&list_rwsem); |
365 | return -1; | 386 | return -1; |
366 | } | 387 | } |
367 | list_for_each(tmp, &slot_list) { | 388 | list_for_each(tmp, &slot_list) { |
@@ -386,7 +407,7 @@ init_slots(void) | |||
386 | } | 407 | } |
387 | } | 408 | } |
388 | } | 409 | } |
389 | spin_unlock(&list_lock); | 410 | up_read(&list_rwsem); |
390 | dbg("%s - exit", __FUNCTION__); | 411 | dbg("%s - exit", __FUNCTION__); |
391 | return 0; | 412 | return 0; |
392 | } | 413 | } |
@@ -398,10 +419,11 @@ check_slots(void) | |||
398 | struct list_head *tmp; | 419 | struct list_head *tmp; |
399 | int extracted; | 420 | int extracted; |
400 | int inserted; | 421 | int inserted; |
422 | u16 hs_csr; | ||
401 | 423 | ||
402 | spin_lock(&list_lock); | 424 | down_read(&list_rwsem); |
403 | if(!slots) { | 425 | if(!slots) { |
404 | spin_unlock(&list_lock); | 426 | up_read(&list_rwsem); |
405 | err("no slots registered, shutting down"); | 427 | err("no slots registered, shutting down"); |
406 | return -1; | 428 | return -1; |
407 | } | 429 | } |
@@ -411,8 +433,6 @@ check_slots(void) | |||
411 | dbg("%s - looking at slot %s", | 433 | dbg("%s - looking at slot %s", |
412 | __FUNCTION__, slot->hotplug_slot->name); | 434 | __FUNCTION__, slot->hotplug_slot->name); |
413 | if(cpci_check_and_clear_ins(slot)) { | 435 | if(cpci_check_and_clear_ins(slot)) { |
414 | u16 hs_csr; | ||
415 | |||
416 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ | 436 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ |
417 | if(slot->dev) { | 437 | if(slot->dev) { |
418 | warn("slot %s already inserted", slot->hotplug_slot->name); | 438 | warn("slot %s already inserted", slot->hotplug_slot->name); |
@@ -462,8 +482,6 @@ check_slots(void) | |||
462 | 482 | ||
463 | inserted++; | 483 | inserted++; |
464 | } else if(cpci_check_ext(slot)) { | 484 | } else if(cpci_check_ext(slot)) { |
465 | u16 hs_csr; | ||
466 | |||
467 | /* Process extraction request */ | 485 | /* Process extraction request */ |
468 | dbg("%s - slot %s extracted", | 486 | dbg("%s - slot %s extracted", |
469 | __FUNCTION__, slot->hotplug_slot->name); | 487 | __FUNCTION__, slot->hotplug_slot->name); |
@@ -476,20 +494,40 @@ check_slots(void) | |||
476 | if(!slot->extracting) { | 494 | if(!slot->extracting) { |
477 | if(update_latch_status(slot->hotplug_slot, 0)) { | 495 | if(update_latch_status(slot->hotplug_slot, 0)) { |
478 | warn("failure to update latch file"); | 496 | warn("failure to update latch file"); |
497 | |||
479 | } | 498 | } |
499 | atomic_inc(&extracting); | ||
480 | slot->extracting = 1; | 500 | slot->extracting = 1; |
481 | } | 501 | } |
482 | extracted++; | 502 | extracted++; |
503 | } else if(slot->extracting) { | ||
504 | hs_csr = cpci_get_hs_csr(slot); | ||
505 | if(hs_csr == 0xffff) { | ||
506 | /* | ||
507 | * Hmmm, we're likely hosed at this point, should we | ||
508 | * bother trying to tell the driver or not? | ||
509 | */ | ||
510 | err("card in slot %s was improperly removed", | ||
511 | slot->hotplug_slot->name); | ||
512 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
513 | warn("failure to update adapter file"); | ||
514 | } | ||
515 | slot->extracting = 0; | ||
516 | atomic_dec(&extracting); | ||
517 | } | ||
483 | } | 518 | } |
484 | } | 519 | } |
485 | spin_unlock(&list_lock); | 520 | up_read(&list_rwsem); |
521 | dbg("inserted=%d, extracted=%d, extracting=%d", | ||
522 | inserted, extracted, atomic_read(&extracting)); | ||
486 | if(inserted || extracted) { | 523 | if(inserted || extracted) { |
487 | return extracted; | 524 | return extracted; |
488 | } | 525 | } |
489 | else { | 526 | else if(!atomic_read(&extracting)) { |
490 | err("cannot find ENUM# source, shutting down"); | 527 | err("cannot find ENUM# source, shutting down"); |
491 | return -1; | 528 | return -1; |
492 | } | 529 | } |
530 | return 0; | ||
493 | } | 531 | } |
494 | 532 | ||
495 | /* This is the interrupt mode worker thread body */ | 533 | /* This is the interrupt mode worker thread body */ |
@@ -497,8 +535,6 @@ static int | |||
497 | event_thread(void *data) | 535 | event_thread(void *data) |
498 | { | 536 | { |
499 | int rc; | 537 | int rc; |
500 | struct slot *slot; | ||
501 | struct list_head *tmp; | ||
502 | 538 | ||
503 | lock_kernel(); | 539 | lock_kernel(); |
504 | daemonize("cpci_hp_eventd"); | 540 | daemonize("cpci_hp_eventd"); |
@@ -512,39 +548,22 @@ event_thread(void *data) | |||
512 | thread_finished); | 548 | thread_finished); |
513 | if(thread_finished || signal_pending(current)) | 549 | if(thread_finished || signal_pending(current)) |
514 | break; | 550 | break; |
515 | while(controller->ops->query_enum()) { | 551 | do { |
516 | rc = check_slots(); | 552 | rc = check_slots(); |
517 | if (rc > 0) | 553 | if (rc > 0) { |
518 | /* Give userspace a chance to handle extraction */ | 554 | /* Give userspace a chance to handle extraction */ |
519 | msleep(500); | 555 | msleep(500); |
520 | else if (rc < 0) { | 556 | } else if (rc < 0) { |
521 | dbg("%s - error checking slots", __FUNCTION__); | 557 | dbg("%s - error checking slots", __FUNCTION__); |
522 | thread_finished = 1; | 558 | thread_finished = 1; |
523 | break; | 559 | break; |
524 | } | 560 | } |
525 | } | 561 | } while(atomic_read(&extracting) != 0); |
526 | /* Check for someone yanking out a board */ | ||
527 | list_for_each(tmp, &slot_list) { | ||
528 | slot = list_entry(tmp, struct slot, slot_list); | ||
529 | if(slot->extracting) { | ||
530 | /* | ||
531 | * Hmmm, we're likely hosed at this point, should we | ||
532 | * bother trying to tell the driver or not? | ||
533 | */ | ||
534 | err("card in slot %s was improperly removed", | ||
535 | slot->hotplug_slot->name); | ||
536 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
537 | warn("failure to update adapter file"); | ||
538 | } | ||
539 | slot->extracting = 0; | ||
540 | } | ||
541 | } | ||
542 | 562 | ||
543 | /* Re-enable ENUM# interrupt */ | 563 | /* Re-enable ENUM# interrupt */ |
544 | dbg("%s - re-enabling irq", __FUNCTION__); | 564 | dbg("%s - re-enabling irq", __FUNCTION__); |
545 | controller->ops->enable_irq(); | 565 | controller->ops->enable_irq(); |
546 | } | 566 | } |
547 | |||
548 | dbg("%s - event thread signals exit", __FUNCTION__); | 567 | dbg("%s - event thread signals exit", __FUNCTION__); |
549 | up(&thread_exit); | 568 | up(&thread_exit); |
550 | return 0; | 569 | return 0; |
@@ -555,8 +574,6 @@ static int | |||
555 | poll_thread(void *data) | 574 | poll_thread(void *data) |
556 | { | 575 | { |
557 | int rc; | 576 | int rc; |
558 | struct slot *slot; | ||
559 | struct list_head *tmp; | ||
560 | 577 | ||
561 | lock_kernel(); | 578 | lock_kernel(); |
562 | daemonize("cpci_hp_polld"); | 579 | daemonize("cpci_hp_polld"); |
@@ -565,35 +582,19 @@ poll_thread(void *data) | |||
565 | while(1) { | 582 | while(1) { |
566 | if(thread_finished || signal_pending(current)) | 583 | if(thread_finished || signal_pending(current)) |
567 | break; | 584 | break; |
568 | 585 | if(controller->ops->query_enum()) { | |
569 | while(controller->ops->query_enum()) { | 586 | do { |
570 | rc = check_slots(); | 587 | rc = check_slots(); |
571 | if(rc > 0) | 588 | if(rc > 0) { |
572 | /* Give userspace a chance to handle extraction */ | 589 | /* Give userspace a chance to handle extraction */ |
573 | msleep(500); | 590 | msleep(500); |
574 | else if (rc < 0) { | 591 | } else if(rc < 0) { |
575 | dbg("%s - error checking slots", __FUNCTION__); | 592 | dbg("%s - error checking slots", __FUNCTION__); |
576 | thread_finished = 1; | 593 | thread_finished = 1; |
577 | break; | 594 | break; |
578 | } | ||
579 | } | ||
580 | /* Check for someone yanking out a board */ | ||
581 | list_for_each(tmp, &slot_list) { | ||
582 | slot = list_entry(tmp, struct slot, slot_list); | ||
583 | if(slot->extracting) { | ||
584 | /* | ||
585 | * Hmmm, we're likely hosed at this point, should we | ||
586 | * bother trying to tell the driver or not? | ||
587 | */ | ||
588 | err("card in slot %s was improperly removed", | ||
589 | slot->hotplug_slot->name); | ||
590 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
591 | warn("failure to update adapter file"); | ||
592 | } | 595 | } |
593 | slot->extracting = 0; | 596 | } while(atomic_read(&extracting) != 0); |
594 | } | ||
595 | } | 597 | } |
596 | |||
597 | msleep(100); | 598 | msleep(100); |
598 | } | 599 | } |
599 | dbg("poll thread signals exit"); | 600 | dbg("poll thread signals exit"); |
@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) | |||
667 | int status = 0; | 668 | int status = 0; |
668 | 669 | ||
669 | if(controller) { | 670 | if(controller) { |
671 | if(atomic_read(&extracting) != 0) { | ||
672 | return -EBUSY; | ||
673 | } | ||
670 | if(!thread_finished) { | 674 | if(!thread_finished) { |
671 | cpci_stop_thread(); | 675 | cpci_stop_thread(); |
672 | } | 676 | } |
@@ -691,12 +695,12 @@ cpci_hp_start(void) | |||
691 | return -ENODEV; | 695 | return -ENODEV; |
692 | } | 696 | } |
693 | 697 | ||
694 | spin_lock(&list_lock); | 698 | down_read(&list_rwsem); |
695 | if(!slots) { | 699 | if(list_empty(&slot_list)) { |
696 | spin_unlock(&list_lock); | 700 | up_read(&list_rwsem); |
697 | return -ENODEV; | 701 | return -ENODEV; |
698 | } | 702 | } |
699 | spin_unlock(&list_lock); | 703 | up_read(&list_rwsem); |
700 | 704 | ||
701 | if(first) { | 705 | if(first) { |
702 | status = init_slots(); | 706 | status = init_slots(); |
@@ -727,7 +731,9 @@ cpci_hp_stop(void) | |||
727 | if(!controller) { | 731 | if(!controller) { |
728 | return -ENODEV; | 732 | return -ENODEV; |
729 | } | 733 | } |
730 | 734 | if(atomic_read(&extracting) != 0) { | |
735 | return -EBUSY; | ||
736 | } | ||
731 | if(controller->irq) { | 737 | if(controller->irq) { |
732 | /* Stop enum interrupt processing */ | 738 | /* Stop enum interrupt processing */ |
733 | dbg("%s - disabling irq", __FUNCTION__); | 739 | dbg("%s - disabling irq", __FUNCTION__); |
@@ -747,7 +753,7 @@ cleanup_slots(void) | |||
747 | * Unregister all of our slots with the pci_hotplug subsystem, | 753 | * Unregister all of our slots with the pci_hotplug subsystem, |
748 | * and free up all memory that we had allocated. | 754 | * and free up all memory that we had allocated. |
749 | */ | 755 | */ |
750 | spin_lock(&list_lock); | 756 | down_write(&list_rwsem); |
751 | if(!slots) { | 757 | if(!slots) { |
752 | goto null_cleanup; | 758 | goto null_cleanup; |
753 | } | 759 | } |
@@ -761,17 +767,14 @@ cleanup_slots(void) | |||
761 | kfree(slot); | 767 | kfree(slot); |
762 | } | 768 | } |
763 | null_cleanup: | 769 | null_cleanup: |
764 | spin_unlock(&list_lock); | 770 | up_write(&list_rwsem); |
765 | return; | 771 | return; |
766 | } | 772 | } |
767 | 773 | ||
768 | int __init | 774 | int __init |
769 | cpci_hotplug_init(int debug) | 775 | cpci_hotplug_init(int debug) |
770 | { | 776 | { |
771 | spin_lock_init(&list_lock); | ||
772 | cpci_debug = debug; | 777 | cpci_debug = debug; |
773 | |||
774 | info(DRIVER_DESC " version: " DRIVER_VERSION); | ||
775 | return 0; | 778 | return 0; |
776 | } | 779 | } |
777 | 780 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 2e969616f298..69eb4fc54f2f 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -32,11 +32,7 @@ | |||
32 | #include "pci_hotplug.h" | 32 | #include "pci_hotplug.h" |
33 | #include "cpci_hotplug.h" | 33 | #include "cpci_hotplug.h" |
34 | 34 | ||
35 | #if !defined(MODULE) | ||
36 | #define MY_NAME "cpci_hotplug" | 35 | #define MY_NAME "cpci_hotplug" |
37 | #else | ||
38 | #define MY_NAME THIS_MODULE->name | ||
39 | #endif | ||
40 | 36 | ||
41 | extern int cpci_debug; | 37 | extern int cpci_debug; |
42 | 38 | ||
@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot) | |||
127 | return hs_csr; | 123 | return hs_csr; |
128 | } | 124 | } |
129 | 125 | ||
130 | #if 0 | ||
131 | u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr) | ||
132 | { | ||
133 | int hs_cap; | ||
134 | u16 new_hs_csr; | ||
135 | |||
136 | hs_cap = pci_bus_find_capability(slot->bus, | ||
137 | slot->devfn, | ||
138 | PCI_CAP_ID_CHSWP); | ||
139 | if(!hs_cap) { | ||
140 | return 0xFFFF; | ||
141 | } | ||
142 | |||
143 | /* Write out the new value */ | ||
144 | if(pci_bus_write_config_word(slot->bus, | ||
145 | slot->devfn, | ||
146 | hs_cap + 2, | ||
147 | hs_csr)) { | ||
148 | return 0xFFFF; | ||
149 | } | ||
150 | |||
151 | /* Read back what we just wrote out */ | ||
152 | if(pci_bus_read_config_word(slot->bus, | ||
153 | slot->devfn, | ||
154 | hs_cap + 2, | ||
155 | &new_hs_csr)) { | ||
156 | return 0xFFFF; | ||
157 | } | ||
158 | return new_hs_csr; | ||
159 | } | ||
160 | #endif | ||
161 | |||
162 | int cpci_check_and_clear_ins(struct slot* slot) | 126 | int cpci_check_and_clear_ins(struct slot* slot) |
163 | { | 127 | { |
164 | int hs_cap; | 128 | int hs_cap; |
@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot) | |||
261 | return -ENODEV; | 225 | return -ENODEV; |
262 | } | 226 | } |
263 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { | 227 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { |
264 | /* Set LOO */ | ||
265 | hs_csr |= HS_CSR_LOO; | 228 | hs_csr |= HS_CSR_LOO; |
266 | if(pci_bus_write_config_word(slot->bus, | 229 | if(pci_bus_write_config_word(slot->bus, |
267 | slot->devfn, | 230 | slot->devfn, |
@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot) | |||
293 | return -ENODEV; | 256 | return -ENODEV; |
294 | } | 257 | } |
295 | if(hs_csr & HS_CSR_LOO) { | 258 | if(hs_csr & HS_CSR_LOO) { |
296 | /* Clear LOO */ | ||
297 | hs_csr &= ~HS_CSR_LOO; | 259 | hs_csr &= ~HS_CSR_LOO; |
298 | if(pci_bus_write_config_word(slot->bus, | 260 | if(pci_bus_write_config_word(slot->bus, |
299 | slot->devfn, | 261 | slot->devfn, |
@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot) | |||
312 | * Device configuration functions | 274 | * Device configuration functions |
313 | */ | 275 | */ |
314 | 276 | ||
315 | static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev) | 277 | static void cpci_enable_device(struct pci_dev *dev) |
316 | { | ||
317 | u8 irq_pin; | ||
318 | int r; | ||
319 | |||
320 | dbg("%s - enter", __FUNCTION__); | ||
321 | |||
322 | /* NOTE: device already setup from prior scan */ | ||
323 | |||
324 | /* FIXME: How would we know if we need to enable the expansion ROM? */ | ||
325 | pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L); | ||
326 | |||
327 | /* Assign resources */ | ||
328 | dbg("assigning resources for %02x:%02x.%x", | ||
329 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
330 | for (r = 0; r < 6; r++) { | ||
331 | struct resource *res = dev->resource + r; | ||
332 | if(res->flags) | ||
333 | pci_assign_resource(dev, r); | ||
334 | } | ||
335 | dbg("finished assigning resources for %02x:%02x.%x", | ||
336 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
337 | |||
338 | /* Does this function have an interrupt at all? */ | ||
339 | dbg("checking for function interrupt"); | ||
340 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); | ||
341 | if(irq_pin) { | ||
342 | dbg("function uses interrupt pin %d", irq_pin); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * Need to explicitly set irq field to 0 so that it'll get assigned | ||
347 | * by the pcibios platform dependent code called by pci_enable_device. | ||
348 | */ | ||
349 | dev->irq = 0; | ||
350 | |||
351 | dbg("enabling device"); | ||
352 | pci_enable_device(dev); /* XXX check return */ | ||
353 | dbg("now dev->irq = %d", dev->irq); | ||
354 | if(irq_pin && dev->irq) { | ||
355 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
356 | } | ||
357 | |||
358 | /* Can't use pci_insert_device at the moment, do it manually for now */ | ||
359 | pci_proc_attach_device(dev); | ||
360 | dbg("notifying drivers"); | ||
361 | //pci_announce_device_to_drivers(dev); | ||
362 | dbg("%s - exit", __FUNCTION__); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev) | ||
367 | { | 278 | { |
368 | int rc; | 279 | struct pci_bus *bus; |
369 | struct pci_bus* child; | ||
370 | struct resource* r; | ||
371 | u8 max, n; | ||
372 | u16 command; | ||
373 | |||
374 | dbg("%s - enter", __FUNCTION__); | ||
375 | 280 | ||
376 | /* Do basic bridge initialization */ | 281 | pci_enable_device(dev); |
377 | rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); | ||
378 | if(rc) { | ||
379 | printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__); | ||
380 | } | ||
381 | rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); | ||
382 | if(rc) { | ||
383 | printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__); | ||
384 | } | ||
385 | rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); | ||
386 | if(rc) { | ||
387 | printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__); | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Set parent bridge's subordinate field so that configuration space | ||
392 | * access will work in pci_scan_bridge and friends. | ||
393 | */ | ||
394 | max = pci_max_busnr(); | ||
395 | bus->subordinate = max + 1; | ||
396 | pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1); | ||
397 | |||
398 | /* Scan behind bridge */ | ||
399 | n = pci_scan_bridge(bus, dev, max, 2); | ||
400 | child = pci_find_bus(0, max + 1); | ||
401 | if (!child) | ||
402 | return -ENODEV; | ||
403 | pci_proc_attach_bus(child); | ||
404 | |||
405 | /* | ||
406 | * Update parent bridge's subordinate field if there were more bridges | ||
407 | * behind the bridge that was scanned. | ||
408 | */ | ||
409 | if(n > max) { | ||
410 | bus->subordinate = n; | ||
411 | pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Update the bridge resources of the bridge to accommodate devices | ||
416 | * behind it. | ||
417 | */ | ||
418 | pci_bus_size_bridges(child); | ||
419 | pci_bus_assign_resources(child); | ||
420 | |||
421 | /* Enable resource mapping via command register */ | ||
422 | command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; | ||
423 | r = child->resource[0]; | ||
424 | if(r && r->start) { | ||
425 | command |= PCI_COMMAND_IO; | ||
426 | } | ||
427 | r = child->resource[1]; | ||
428 | if(r && r->start) { | ||
429 | command |= PCI_COMMAND_MEMORY; | ||
430 | } | ||
431 | r = child->resource[2]; | ||
432 | if(r && r->start) { | ||
433 | command |= PCI_COMMAND_MEMORY; | ||
434 | } | ||
435 | rc = pci_write_config_word(dev, PCI_COMMAND, command); | ||
436 | if(rc) { | ||
437 | err("Error setting command register"); | ||
438 | return rc; | ||
439 | } | ||
440 | |||
441 | /* Set bridge control register */ | ||
442 | command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA; | ||
443 | rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command); | ||
444 | if(rc) { | ||
445 | err("Error setting bridge control register"); | ||
446 | return rc; | ||
447 | } | ||
448 | dbg("%s - exit", __FUNCTION__); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev, | ||
453 | struct pci_bus_wrapped *wrapped_bus) | ||
454 | { | ||
455 | int rc; | ||
456 | struct pci_dev *dev = wrapped_dev->dev; | ||
457 | struct pci_bus *bus = wrapped_bus->bus; | ||
458 | struct slot* slot; | ||
459 | |||
460 | dbg("%s - enter", __FUNCTION__); | ||
461 | |||
462 | /* | ||
463 | * We need to fix up the hotplug representation with the Linux | ||
464 | * representation. | ||
465 | */ | ||
466 | if(wrapped_dev->data) { | ||
467 | slot = (struct slot*) wrapped_dev->data; | ||
468 | slot->dev = dev; | ||
469 | } | ||
470 | |||
471 | /* If it's a bridge, scan behind it for devices */ | ||
472 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 282 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
473 | rc = cpci_configure_bridge(bus, dev); | 283 | bus = dev->subordinate; |
474 | if(rc) | 284 | list_for_each_entry(dev, &bus->devices, bus_list) { |
475 | return rc; | 285 | cpci_enable_device(dev); |
476 | } | ||
477 | |||
478 | /* Actually configure device */ | ||
479 | if(dev) { | ||
480 | rc = cpci_configure_dev(bus, dev); | ||
481 | if(rc) | ||
482 | return rc; | ||
483 | } | ||
484 | dbg("%s - exit", __FUNCTION__); | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev, | ||
489 | struct pci_bus_wrapped *wrapped_bus) | ||
490 | { | ||
491 | struct pci_dev *dev = wrapped_dev->dev; | ||
492 | struct slot* slot; | ||
493 | |||
494 | dbg("%s - enter", __FUNCTION__); | ||
495 | if(!dev) | ||
496 | return -ENODEV; | ||
497 | |||
498 | /* Remove the Linux representation */ | ||
499 | if(pci_remove_device_safe(dev)) { | ||
500 | err("Could not remove device\n"); | ||
501 | return -1; | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Now remove the hotplug representation. | ||
506 | */ | ||
507 | if(wrapped_dev->data) { | ||
508 | slot = (struct slot*) wrapped_dev->data; | ||
509 | slot->dev = NULL; | ||
510 | } else { | ||
511 | dbg("No hotplug representation for %02x:%02x.%x", | ||
512 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
513 | } | ||
514 | dbg("%s - exit", __FUNCTION__); | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus, | ||
519 | struct pci_dev_wrapped *wrapped_dev) | ||
520 | { | ||
521 | struct pci_bus *bus = wrapped_bus->bus; | ||
522 | struct pci_bus *parent = bus->self->bus; | ||
523 | |||
524 | dbg("%s - enter", __FUNCTION__); | ||
525 | |||
526 | /* The cleanup code for proc entries regarding buses should be in the kernel... */ | ||
527 | if(bus->procdir) | ||
528 | dbg("detach_pci_bus %s", bus->procdir->name); | ||
529 | pci_proc_detach_bus(bus); | ||
530 | |||
531 | /* The cleanup code should live in the kernel... */ | ||
532 | bus->self->subordinate = NULL; | ||
533 | |||
534 | /* unlink from parent bus */ | ||
535 | list_del(&bus->node); | ||
536 | |||
537 | /* Now, remove */ | ||
538 | if(bus) | ||
539 | kfree(bus); | ||
540 | |||
541 | /* Update parent's subordinate field */ | ||
542 | if(parent) { | ||
543 | u8 n = pci_bus_max_busnr(parent); | ||
544 | if(n < parent->subordinate) { | ||
545 | parent->subordinate = n; | ||
546 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n); | ||
547 | } | 286 | } |
548 | } | 287 | } |
549 | dbg("%s - exit", __FUNCTION__); | ||
550 | return 0; | ||
551 | } | 288 | } |
552 | 289 | ||
553 | static struct pci_visit configure_functions = { | ||
554 | .visit_pci_dev = configure_visit_pci_dev, | ||
555 | }; | ||
556 | |||
557 | static struct pci_visit unconfigure_functions_phase2 = { | ||
558 | .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2, | ||
559 | .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2 | ||
560 | }; | ||
561 | |||
562 | |||
563 | int cpci_configure_slot(struct slot* slot) | 290 | int cpci_configure_slot(struct slot* slot) |
564 | { | 291 | { |
565 | int rc = 0; | 292 | unsigned char busnr; |
293 | struct pci_bus *child; | ||
566 | 294 | ||
567 | dbg("%s - enter", __FUNCTION__); | 295 | dbg("%s - enter", __FUNCTION__); |
568 | 296 | ||
@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot) | |||
588 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 316 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); |
589 | if(slot->dev == NULL) { | 317 | if(slot->dev == NULL) { |
590 | err("Could not find PCI device for slot %02x", slot->number); | 318 | err("Could not find PCI device for slot %02x", slot->number); |
591 | return 0; | 319 | return 1; |
592 | } | 320 | } |
593 | } | 321 | } |
594 | dbg("slot->dev = %p", slot->dev); | 322 | |
595 | if(slot->dev) { | 323 | if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
596 | struct pci_dev *dev; | 324 | pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr); |
597 | struct pci_dev_wrapped wrapped_dev; | 325 | child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr); |
598 | struct pci_bus_wrapped wrapped_bus; | 326 | pci_do_scan_bus(child); |
599 | int i; | 327 | pci_bus_size_bridges(child); |
600 | |||
601 | memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); | ||
602 | memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); | ||
603 | |||
604 | for (i = 0; i < 8; i++) { | ||
605 | dev = pci_find_slot(slot->bus->number, | ||
606 | PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i)); | ||
607 | if(!dev) | ||
608 | continue; | ||
609 | wrapped_dev.dev = dev; | ||
610 | wrapped_bus.bus = slot->dev->bus; | ||
611 | if(i) | ||
612 | wrapped_dev.data = NULL; | ||
613 | else | ||
614 | wrapped_dev.data = (void*) slot; | ||
615 | rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus); | ||
616 | } | ||
617 | } | 328 | } |
618 | 329 | ||
619 | dbg("%s - exit, rc = %d", __FUNCTION__, rc); | 330 | pci_bus_assign_resources(slot->dev->bus); |
620 | return rc; | 331 | |
332 | cpci_enable_device(slot->dev); | ||
333 | |||
334 | dbg("%s - exit", __FUNCTION__); | ||
335 | return 0; | ||
621 | } | 336 | } |
622 | 337 | ||
623 | int cpci_unconfigure_slot(struct slot* slot) | 338 | int cpci_unconfigure_slot(struct slot* slot) |
624 | { | 339 | { |
625 | int rc = 0; | ||
626 | int i; | 340 | int i; |
627 | struct pci_dev_wrapped wrapped_dev; | ||
628 | struct pci_bus_wrapped wrapped_bus; | ||
629 | struct pci_dev *dev; | 341 | struct pci_dev *dev; |
630 | 342 | ||
631 | dbg("%s - enter", __FUNCTION__); | 343 | dbg("%s - enter", __FUNCTION__); |
632 | |||
633 | if(!slot->dev) { | 344 | if(!slot->dev) { |
634 | err("No device for slot %02x\n", slot->number); | 345 | err("No device for slot %02x\n", slot->number); |
635 | return -ENODEV; | 346 | return -ENODEV; |
636 | } | 347 | } |
637 | 348 | ||
638 | memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); | ||
639 | memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); | ||
640 | |||
641 | for (i = 0; i < 8; i++) { | 349 | for (i = 0; i < 8; i++) { |
642 | dev = pci_find_slot(slot->bus->number, | 350 | dev = pci_find_slot(slot->bus->number, |
643 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 351 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
644 | if(dev) { | 352 | if(dev) { |
645 | wrapped_dev.dev = dev; | 353 | pci_remove_bus_device(dev); |
646 | wrapped_bus.bus = dev->bus; | 354 | slot->dev = NULL; |
647 | if(i) | ||
648 | wrapped_dev.data = NULL; | ||
649 | else | ||
650 | wrapped_dev.data = (void*) slot; | ||
651 | dbg("%s - unconfigure phase 2", __FUNCTION__); | ||
652 | rc = pci_visit_dev(&unconfigure_functions_phase2, | ||
653 | &wrapped_dev, | ||
654 | &wrapped_bus); | ||
655 | if(rc) | ||
656 | break; | ||
657 | } | 355 | } |
658 | } | 356 | } |
659 | dbg("%s - exit, rc = %d", __FUNCTION__, rc); | 357 | dbg("%s - exit", __FUNCTION__); |
660 | return rc; | 358 | return 0; |
661 | } | 359 | } |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index f313121d5141..46b294a12418 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -130,6 +130,7 @@ struct controller { | |||
130 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ | 130 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ |
131 | u8 ctrlcap; | 131 | u8 ctrlcap; |
132 | u16 vendor_id; | 132 | u16 vendor_id; |
133 | u8 cap_base; | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | struct irq_mapping { | 136 | struct irq_mapping { |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index ed1fd8d6178d..df4915dbc321 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev) | |||
607 | static struct pcie_port_service_id port_pci_ids[] = { { | 607 | static struct pcie_port_service_id port_pci_ids[] = { { |
608 | .vendor = PCI_ANY_ID, | 608 | .vendor = PCI_ANY_ID, |
609 | .device = PCI_ANY_ID, | 609 | .device = PCI_ANY_ID, |
610 | .port_type = PCIE_RC_PORT, | 610 | .port_type = PCIE_ANY_PORT, |
611 | .service_type = PCIE_PORT_SERVICE_HP, | 611 | .service_type = PCIE_PORT_SERVICE_HP, |
612 | .driver_data = 0, | 612 | .driver_data = 0, |
613 | }, { /* end: all zeroes */ } | 613 | }, { /* end: all zeroes */ } |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9e70c4681f77..1cda30bd6e47 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -109,20 +109,20 @@ enum ctrl_offsets { | |||
109 | }; | 109 | }; |
110 | static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ | 110 | static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ |
111 | 111 | ||
112 | #define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID ) | 112 | #define PCIE_CAP_ID(cb) ( cb + PCIECAPID ) |
113 | #define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR ) | 113 | #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR ) |
114 | #define CAP_REG ( pcie_cap_base + CAPREG ) | 114 | #define CAP_REG(cb) ( cb + CAPREG ) |
115 | #define DEV_CAP ( pcie_cap_base + DEVCAP ) | 115 | #define DEV_CAP(cb) ( cb + DEVCAP ) |
116 | #define DEV_CTRL ( pcie_cap_base + DEVCTRL ) | 116 | #define DEV_CTRL(cb) ( cb + DEVCTRL ) |
117 | #define DEV_STATUS ( pcie_cap_base + DEVSTATUS ) | 117 | #define DEV_STATUS(cb) ( cb + DEVSTATUS ) |
118 | #define LNK_CAP ( pcie_cap_base + LNKCAP ) | 118 | #define LNK_CAP(cb) ( cb + LNKCAP ) |
119 | #define LNK_CTRL ( pcie_cap_base + LNKCTRL ) | 119 | #define LNK_CTRL(cb) ( cb + LNKCTRL ) |
120 | #define LNK_STATUS ( pcie_cap_base + LNKSTATUS ) | 120 | #define LNK_STATUS(cb) ( cb + LNKSTATUS ) |
121 | #define SLOT_CAP ( pcie_cap_base + SLOTCAP ) | 121 | #define SLOT_CAP(cb) ( cb + SLOTCAP ) |
122 | #define SLOT_CTRL ( pcie_cap_base + SLOTCTRL ) | 122 | #define SLOT_CTRL(cb) ( cb + SLOTCTRL ) |
123 | #define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS ) | 123 | #define SLOT_STATUS(cb) ( cb + SLOTSTATUS ) |
124 | #define ROOT_CTRL ( pcie_cap_base + ROOTCTRL ) | 124 | #define ROOT_CTRL(cb) ( cb + ROOTCTRL ) |
125 | #define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS ) | 125 | #define ROOT_STATUS(cb) ( cb + ROOTSTATUS ) |
126 | 126 | ||
127 | #define hp_register_read_word(pdev, reg , value) \ | 127 | #define hp_register_read_word(pdev, reg , value) \ |
128 | pci_read_config_word(pdev, reg, &value) | 128 | pci_read_config_word(pdev, reg, &value) |
@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
303 | return -1; | 303 | return -1; |
304 | } | 304 | } |
305 | 305 | ||
306 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 306 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
307 | if (retval) { | 307 | if (retval) { |
308 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 308 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
309 | return retval; | 309 | return retval; |
@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
317 | } | 317 | } |
318 | 318 | ||
319 | dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); | 319 | dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); |
320 | retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE); | 320 | retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); |
321 | if (retval) { | 321 | if (retval) { |
322 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 322 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
323 | return retval; | 323 | return retval; |
@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl) | |||
342 | return -1; | 342 | return -1; |
343 | } | 343 | } |
344 | 344 | ||
345 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 345 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); |
346 | 346 | ||
347 | if (retval) { | 347 | if (retval) { |
348 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 348 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
376 | return -1; | 376 | return -1; |
377 | } | 377 | } |
378 | 378 | ||
379 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 379 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
380 | 380 | ||
381 | if (retval) { | 381 | if (retval) { |
382 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 382 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
383 | return retval; | 383 | return retval; |
384 | } | 384 | } |
385 | 385 | ||
386 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl); | 386 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
387 | 387 | ||
388 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; | 388 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; |
389 | 389 | ||
@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
423 | return -1; | 423 | return -1; |
424 | } | 424 | } |
425 | 425 | ||
426 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 426 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
427 | 427 | ||
428 | if (retval) { | 428 | if (retval) { |
429 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 429 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
430 | return retval; | 430 | return retval; |
431 | } | 431 | } |
432 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); | 432 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
433 | 433 | ||
434 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; | 434 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; |
435 | 435 | ||
@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
463 | return -1; | 463 | return -1; |
464 | } | 464 | } |
465 | 465 | ||
466 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 466 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
467 | 467 | ||
468 | if (retval) { | 468 | if (retval) { |
469 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 469 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
490 | return -1; | 490 | return -1; |
491 | } | 491 | } |
492 | 492 | ||
493 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 493 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
494 | 494 | ||
495 | if (retval) { | 495 | if (retval) { |
496 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 496 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot) | |||
518 | return -1; | 518 | return -1; |
519 | } | 519 | } |
520 | 520 | ||
521 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 521 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
522 | 522 | ||
523 | if (retval) { | 523 | if (retval) { |
524 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 524 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
549 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | 549 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); |
550 | return -1; | 550 | return -1; |
551 | } | 551 | } |
552 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 552 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
553 | 553 | ||
554 | if (rc) { | 554 | if (rc) { |
555 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 555 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
574 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 574 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
575 | 575 | ||
576 | pcie_write_cmd(slot, slot_cmd); | 576 | pcie_write_cmd(slot, slot_cmd); |
577 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); | 577 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
578 | 578 | ||
579 | return rc; | 579 | return rc; |
580 | } | 580 | } |
@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
598 | return ; | 598 | return ; |
599 | } | 599 | } |
600 | 600 | ||
601 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 601 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
602 | 602 | ||
603 | if (rc) { | 603 | if (rc) { |
604 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 604 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
611 | 611 | ||
612 | pcie_write_cmd(slot, slot_cmd); | 612 | pcie_write_cmd(slot, slot_cmd); |
613 | 613 | ||
614 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 614 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
615 | return; | 615 | return; |
616 | } | 616 | } |
617 | 617 | ||
@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
633 | return ; | 633 | return ; |
634 | } | 634 | } |
635 | 635 | ||
636 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 636 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
637 | 637 | ||
638 | if (rc) { | 638 | if (rc) { |
639 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 639 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
646 | if (!pciehp_poll_mode) | 646 | if (!pciehp_poll_mode) |
647 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 647 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
648 | pcie_write_cmd(slot, slot_cmd); | 648 | pcie_write_cmd(slot, slot_cmd); |
649 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); | 649 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
650 | 650 | ||
651 | return; | 651 | return; |
652 | } | 652 | } |
@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
669 | return ; | 669 | return ; |
670 | } | 670 | } |
671 | 671 | ||
672 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 672 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
673 | 673 | ||
674 | if (rc) { | 674 | if (rc) { |
675 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 675 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
683 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 683 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
684 | pcie_write_cmd(slot, slot_cmd); | 684 | pcie_write_cmd(slot, slot_cmd); |
685 | 685 | ||
686 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 686 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
687 | return; | 687 | return; |
688 | } | 688 | } |
689 | 689 | ||
@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl, | |||
707 | *first_device_num = 0; | 707 | *first_device_num = 0; |
708 | *num_ctlr_slots = 1; | 708 | *num_ctlr_slots = 1; |
709 | 709 | ||
710 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); | 710 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); |
711 | 711 | ||
712 | if (rc) { | 712 | if (rc) { |
713 | err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); | 713 | err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); |
@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot) | |||
793 | return -1; | 793 | return -1; |
794 | } | 794 | } |
795 | 795 | ||
796 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 796 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
797 | 797 | ||
798 | if (retval) { | 798 | if (retval) { |
799 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 799 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
800 | return retval; | 800 | return retval; |
801 | } | 801 | } |
802 | dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL, | 802 | dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), |
803 | slot_ctrl); | 803 | slot_ctrl); |
804 | 804 | ||
805 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; | 805 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; |
@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot) | |||
813 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); | 813 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); |
814 | return -1; | 814 | return -1; |
815 | } | 815 | } |
816 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 816 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
817 | 817 | ||
818 | DBG_LEAVE_ROUTINE | 818 | DBG_LEAVE_ROUTINE |
819 | 819 | ||
@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot) | |||
842 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | 842 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); |
843 | return -1; | 843 | return -1; |
844 | } | 844 | } |
845 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 845 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
846 | 846 | ||
847 | if (retval) { | 847 | if (retval) { |
848 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 848 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
849 | return retval; | 849 | return retval; |
850 | } | 850 | } |
851 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL, | 851 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), |
852 | slot_ctrl); | 852 | slot_ctrl); |
853 | 853 | ||
854 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; | 854 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; |
@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
862 | err("%s: Write command failed!\n", __FUNCTION__); | 862 | err("%s: Write command failed!\n", __FUNCTION__); |
863 | return -1; | 863 | return -1; |
864 | } | 864 | } |
865 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 865 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
866 | 866 | ||
867 | DBG_LEAVE_ROUTINE | 867 | DBG_LEAVE_ROUTINE |
868 | 868 | ||
@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
900 | return IRQ_NONE; | 900 | return IRQ_NONE; |
901 | } | 901 | } |
902 | 902 | ||
903 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 903 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
904 | if (rc) { | 904 | if (rc) { |
905 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 905 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
906 | return IRQ_NONE; | 906 | return IRQ_NONE; |
@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
918 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 918 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
919 | /* Mask Hot-plug Interrupt Enable */ | 919 | /* Mask Hot-plug Interrupt Enable */ |
920 | if (!pciehp_poll_mode) { | 920 | if (!pciehp_poll_mode) { |
921 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 921 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
922 | if (rc) { | 922 | if (rc) { |
923 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 923 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
924 | return IRQ_NONE; | 924 | return IRQ_NONE; |
@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
928 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 928 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
929 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 929 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
930 | 930 | ||
931 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 931 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
932 | if (rc) { | 932 | if (rc) { |
933 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 933 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
934 | return IRQ_NONE; | 934 | return IRQ_NONE; |
935 | } | 935 | } |
936 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 936 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
937 | 937 | ||
938 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 938 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
939 | if (rc) { | 939 | if (rc) { |
940 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 940 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
941 | return IRQ_NONE; | 941 | return IRQ_NONE; |
@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
944 | 944 | ||
945 | /* Clear command complete interrupt caused by this write */ | 945 | /* Clear command complete interrupt caused by this write */ |
946 | temp_word = 0x1f; | 946 | temp_word = 0x1f; |
947 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 947 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
948 | if (rc) { | 948 | if (rc) { |
949 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 949 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
950 | return IRQ_NONE; | 950 | return IRQ_NONE; |
@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
975 | 975 | ||
976 | /* Clear all events after serving them */ | 976 | /* Clear all events after serving them */ |
977 | temp_word = 0x1F; | 977 | temp_word = 0x1F; |
978 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 978 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
979 | if (rc) { | 979 | if (rc) { |
980 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 980 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
981 | return IRQ_NONE; | 981 | return IRQ_NONE; |
982 | } | 982 | } |
983 | /* Unmask Hot-plug Interrupt Enable */ | 983 | /* Unmask Hot-plug Interrupt Enable */ |
984 | if (!pciehp_poll_mode) { | 984 | if (!pciehp_poll_mode) { |
985 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 985 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
986 | if (rc) { | 986 | if (rc) { |
987 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 987 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
988 | return IRQ_NONE; | 988 | return IRQ_NONE; |
@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
992 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 992 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
993 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | 993 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; |
994 | 994 | ||
995 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 995 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
996 | if (rc) { | 996 | if (rc) { |
997 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 997 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
998 | return IRQ_NONE; | 998 | return IRQ_NONE; |
999 | } | 999 | } |
1000 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 1000 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
1001 | 1001 | ||
1002 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1002 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1003 | if (rc) { | 1003 | if (rc) { |
1004 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1004 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1005 | return IRQ_NONE; | 1005 | return IRQ_NONE; |
@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
1008 | 1008 | ||
1009 | /* Clear command complete interrupt caused by this write */ | 1009 | /* Clear command complete interrupt caused by this write */ |
1010 | temp_word = 0x1F; | 1010 | temp_word = 0x1F; |
1011 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1011 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1012 | if (rc) { | 1012 | if (rc) { |
1013 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1013 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1014 | return IRQ_NONE; | 1014 | return IRQ_NONE; |
@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1038 | return -1; | 1038 | return -1; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); | 1041 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); |
1042 | 1042 | ||
1043 | if (retval) { | 1043 | if (retval) { |
1044 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 1044 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); |
@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value | |||
1079 | return -1; | 1079 | return -1; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); | 1082 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); |
1083 | 1083 | ||
1084 | if (retval) { | 1084 | if (retval) { |
1085 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 1085 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); |
@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1141 | return -1; | 1141 | return -1; |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 1144 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); |
1145 | 1145 | ||
1146 | if (retval) { | 1146 | if (retval) { |
1147 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 1147 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value | |||
1182 | return -1; | 1182 | return -1; |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 1185 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); |
1186 | 1186 | ||
1187 | if (retval) { | 1187 | if (retval) { |
1188 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 1188 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl, | |||
1292 | goto abort_free_ctlr; | 1292 | goto abort_free_ctlr; |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | pcie_cap_base = cap_base; | 1295 | ctrl->cap_base = cap_base; |
1296 | 1296 | ||
1297 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); | 1297 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); |
1298 | 1298 | ||
1299 | rc = hp_register_read_word(pdev, CAP_REG, cap_reg); | 1299 | rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg); |
1300 | if (rc) { | 1300 | if (rc) { |
1301 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1301 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); |
1302 | goto abort_free_ctlr; | 1302 | goto abort_free_ctlr; |
1303 | } | 1303 | } |
1304 | dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg); | 1304 | dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg); |
1305 | 1305 | ||
1306 | if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){ | 1306 | if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) |
1307 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { | ||
1307 | dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__); | 1308 | dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__); |
1308 | goto abort_free_ctlr; | 1309 | goto abort_free_ctlr; |
1309 | } | 1310 | } |
1310 | 1311 | ||
1311 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); | 1312 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); |
1312 | if (rc) { | 1313 | if (rc) { |
1313 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1314 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); |
1314 | goto abort_free_ctlr; | 1315 | goto abort_free_ctlr; |
1315 | } | 1316 | } |
1316 | dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap); | 1317 | dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap); |
1317 | 1318 | ||
1318 | if (!(slot_cap & HP_CAP)) { | 1319 | if (!(slot_cap & HP_CAP)) { |
1319 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); | 1320 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); |
1320 | goto abort_free_ctlr; | 1321 | goto abort_free_ctlr; |
1321 | } | 1322 | } |
1322 | /* For debugging purpose */ | 1323 | /* For debugging purpose */ |
1323 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1324 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1324 | if (rc) { | 1325 | if (rc) { |
1325 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1326 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1326 | goto abort_free_ctlr; | 1327 | goto abort_free_ctlr; |
1327 | } | 1328 | } |
1328 | dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); | 1329 | dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); |
1329 | 1330 | ||
1330 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 1331 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); |
1331 | if (rc) { | 1332 | if (rc) { |
1332 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1333 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1333 | goto abort_free_ctlr; | 1334 | goto abort_free_ctlr; |
1334 | } | 1335 | } |
1335 | dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); | 1336 | dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); |
1336 | 1337 | ||
1337 | if (first) { | 1338 | if (first) { |
1338 | spin_lock_init(&hpc_event_lock); | 1339 | spin_lock_init(&hpc_event_lock); |
@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl, | |||
1372 | php_ctlr->num_slots = 1; | 1373 | php_ctlr->num_slots = 1; |
1373 | 1374 | ||
1374 | /* Mask Hot-plug Interrupt Enable */ | 1375 | /* Mask Hot-plug Interrupt Enable */ |
1375 | rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); | 1376 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1376 | if (rc) { | 1377 | if (rc) { |
1377 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1378 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1378 | goto abort_free_ctlr; | 1379 | goto abort_free_ctlr; |
1379 | } | 1380 | } |
1380 | 1381 | ||
1381 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); | 1382 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); |
1382 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 1383 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
1383 | 1384 | ||
1384 | rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); | 1385 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1385 | if (rc) { | 1386 | if (rc) { |
1386 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1387 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
1387 | goto abort_free_ctlr; | 1388 | goto abort_free_ctlr; |
1388 | } | 1389 | } |
1389 | dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); | 1390 | dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); |
1390 | 1391 | ||
1391 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1392 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1392 | if (rc) { | 1393 | if (rc) { |
1393 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1394 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1394 | goto abort_free_ctlr; | 1395 | goto abort_free_ctlr; |
1395 | } | 1396 | } |
1396 | dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); | 1397 | dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base) |
1398 | , slot_status); | ||
1397 | 1399 | ||
1398 | temp_word = 0x1F; /* Clear all events */ | 1400 | temp_word = 0x1F; /* Clear all events */ |
1399 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1401 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1400 | if (rc) { | 1402 | if (rc) { |
1401 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1403 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1402 | goto abort_free_ctlr; | 1404 | goto abort_free_ctlr; |
1403 | } | 1405 | } |
1404 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); | 1406 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word); |
1405 | 1407 | ||
1406 | if (pciehp_poll_mode) {/* Install interrupt polling code */ | 1408 | if (pciehp_poll_mode) {/* Install interrupt polling code */ |
1407 | /* Install and start the interrupt polling timer */ | 1409 | /* Install and start the interrupt polling timer */ |
@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl, | |||
1417 | } | 1419 | } |
1418 | } | 1420 | } |
1419 | 1421 | ||
1420 | rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); | 1422 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1421 | if (rc) { | 1423 | if (rc) { |
1422 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1424 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1423 | goto abort_free_ctlr; | 1425 | goto abort_free_ctlr; |
1424 | } | 1426 | } |
1425 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); | 1427 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); |
1426 | dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap); | 1428 | dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap); |
1427 | 1429 | ||
1428 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; | 1430 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; |
@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl, | |||
1446 | dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); | 1448 | dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); |
1447 | 1449 | ||
1448 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ | 1450 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ |
1449 | rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); | 1451 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1450 | if (rc) { | 1452 | if (rc) { |
1451 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1453 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
1452 | goto abort_free_ctlr; | 1454 | goto abort_free_ctlr; |
1453 | } | 1455 | } |
1454 | dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); | 1456 | dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); |
1455 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1457 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1456 | if (rc) { | 1458 | if (rc) { |
1457 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1459 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1458 | goto abort_free_ctlr; | 1460 | goto abort_free_ctlr; |
1459 | } | 1461 | } |
1460 | dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, | 1462 | dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, |
1461 | SLOT_STATUS, slot_status); | 1463 | SLOT_STATUS(ctrl->cap_base), slot_status); |
1462 | 1464 | ||
1463 | temp_word = 0x1F; /* Clear all events */ | 1465 | temp_word = 0x1F; /* Clear all events */ |
1464 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1466 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1465 | if (rc) { | 1467 | if (rc) { |
1466 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1468 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1467 | goto abort_free_ctlr; | 1469 | goto abort_free_ctlr; |
1468 | } | 1470 | } |
1469 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); | 1471 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word); |
1470 | 1472 | ||
1471 | /* Add this HPC instance into the HPC list */ | 1473 | /* Add this HPC instance into the HPC list */ |
1472 | spin_lock(&list_lock); | 1474 | spin_lock(&list_lock); |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index f0c53f850aed..a70a5c5705f2 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | |||
95 | */ | 95 | */ |
96 | static void release_slot(struct hotplug_slot *hotplug_slot) | 96 | static void release_slot(struct hotplug_slot *hotplug_slot) |
97 | { | 97 | { |
98 | struct slot *slot = (struct slot *)hotplug_slot->private; | 98 | struct slot *slot = hotplug_slot->private; |
99 | 99 | ||
100 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 100 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
101 | 101 | ||
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 9f90eb8e6ecd..490a9553a062 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1885 | func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); | 1885 | func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); |
1886 | if (!func) { | 1886 | if (!func) { |
1887 | dbg("%s: Error! slot NULL\n", __FUNCTION__); | 1887 | dbg("%s: Error! slot NULL\n", __FUNCTION__); |
1888 | return 1; | 1888 | return -ENODEV; |
1889 | } | 1889 | } |
1890 | 1890 | ||
1891 | /* Check to see if (latch closed, card present, power off) */ | 1891 | /* Check to see if (latch closed, card present, power off) */ |
@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1894 | if (rc || !getstatus) { | 1894 | if (rc || !getstatus) { |
1895 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 1895 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
1896 | up(&p_slot->ctrl->crit_sect); | 1896 | up(&p_slot->ctrl->crit_sect); |
1897 | return 1; | 1897 | return -ENODEV; |
1898 | } | 1898 | } |
1899 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 1899 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
1900 | if (rc || getstatus) { | 1900 | if (rc || getstatus) { |
1901 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 1901 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
1902 | up(&p_slot->ctrl->crit_sect); | 1902 | up(&p_slot->ctrl->crit_sect); |
1903 | return 1; | 1903 | return -ENODEV; |
1904 | } | 1904 | } |
1905 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 1905 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
1906 | if (rc || getstatus) { | 1906 | if (rc || getstatus) { |
1907 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); | 1907 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); |
1908 | up(&p_slot->ctrl->crit_sect); | 1908 | up(&p_slot->ctrl->crit_sect); |
1909 | return 1; | 1909 | return -ENODEV; |
1910 | } | 1910 | } |
1911 | up(&p_slot->ctrl->crit_sect); | 1911 | up(&p_slot->ctrl->crit_sect); |
1912 | 1912 | ||
@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1914 | 1914 | ||
1915 | func = shpchp_slot_create(p_slot->bus); | 1915 | func = shpchp_slot_create(p_slot->bus); |
1916 | if (func == NULL) | 1916 | if (func == NULL) |
1917 | return 1; | 1917 | return -ENOMEM; |
1918 | 1918 | ||
1919 | func->bus = p_slot->bus; | 1919 | func->bus = p_slot->bus; |
1920 | func->device = p_slot->device; | 1920 | func->device = p_slot->device; |
@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1939 | /* Setup slot structure with entry for empty slot */ | 1939 | /* Setup slot structure with entry for empty slot */ |
1940 | func = shpchp_slot_create(p_slot->bus); | 1940 | func = shpchp_slot_create(p_slot->bus); |
1941 | if (func == NULL) | 1941 | if (func == NULL) |
1942 | return (1); /* Out of memory */ | 1942 | return -ENOMEM; /* Out of memory */ |
1943 | 1943 | ||
1944 | func->bus = p_slot->bus; | 1944 | func->bus = p_slot->bus; |
1945 | func->device = p_slot->device; | 1945 | func->device = p_slot->device; |
@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
1972 | struct pci_func *func; | 1972 | struct pci_func *func; |
1973 | 1973 | ||
1974 | if (!p_slot->ctrl) | 1974 | if (!p_slot->ctrl) |
1975 | return 1; | 1975 | return -ENODEV; |
1976 | 1976 | ||
1977 | pci_bus = p_slot->ctrl->pci_dev->subordinate; | 1977 | pci_bus = p_slot->ctrl->pci_dev->subordinate; |
1978 | 1978 | ||
@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
1983 | if (ret || !getstatus) { | 1983 | if (ret || !getstatus) { |
1984 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 1984 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
1985 | up(&p_slot->ctrl->crit_sect); | 1985 | up(&p_slot->ctrl->crit_sect); |
1986 | return 1; | 1986 | return -ENODEV; |
1987 | } | 1987 | } |
1988 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 1988 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
1989 | if (ret || getstatus) { | 1989 | if (ret || getstatus) { |
1990 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 1990 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
1991 | up(&p_slot->ctrl->crit_sect); | 1991 | up(&p_slot->ctrl->crit_sect); |
1992 | return 1; | 1992 | return -ENODEV; |
1993 | } | 1993 | } |
1994 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 1994 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
1995 | if (ret || !getstatus) { | 1995 | if (ret || !getstatus) { |
1996 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); | 1996 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); |
1997 | up(&p_slot->ctrl->crit_sect); | 1997 | up(&p_slot->ctrl->crit_sect); |
1998 | return 1; | 1998 | return -ENODEV; |
1999 | } | 1999 | } |
2000 | up(&p_slot->ctrl->crit_sect); | 2000 | up(&p_slot->ctrl->crit_sect); |
2001 | 2001 | ||
@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2011 | /* Check the Class Code */ | 2011 | /* Check the Class Code */ |
2012 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); | 2012 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); |
2013 | if (rc) | 2013 | if (rc) |
2014 | return rc; | 2014 | return -ENODEV; |
2015 | 2015 | ||
2016 | if (class_code == PCI_BASE_CLASS_DISPLAY) { | 2016 | if (class_code == PCI_BASE_CLASS_DISPLAY) { |
2017 | /* Display/Video adapter (not supported) */ | 2017 | /* Display/Video adapter (not supported) */ |
@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2020 | /* See if it's a bridge */ | 2020 | /* See if it's a bridge */ |
2021 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 2021 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
2022 | if (rc) | 2022 | if (rc) |
2023 | return rc; | 2023 | return -ENODEV; |
2024 | 2024 | ||
2025 | /* If it's a bridge, check the VGA Enable bit */ | 2025 | /* If it's a bridge, check the VGA Enable bit */ |
2026 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | 2026 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
2027 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); | 2027 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); |
2028 | if (rc) | 2028 | if (rc) |
2029 | return rc; | 2029 | return -ENODEV; |
2030 | 2030 | ||
2031 | /* If the VGA Enable bit is set, remove isn't supported */ | 2031 | /* If the VGA Enable bit is set, remove isn't supported */ |
2032 | if (BCR & PCI_BRIDGE_CTL_VGA) { | 2032 | if (BCR & PCI_BRIDGE_CTL_VGA) { |
@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2042 | if ((func != NULL) && !rc) { | 2042 | if ((func != NULL) && !rc) { |
2043 | rc = remove_board(func, p_slot->ctrl); | 2043 | rc = remove_board(func, p_slot->ctrl); |
2044 | } else if (!rc) | 2044 | } else if (!rc) |
2045 | rc = 1; | 2045 | rc = -ENODEV; |
2046 | 2046 | ||
2047 | if (p_slot) | 2047 | if (p_slot) |
2048 | update_slot_info(p_slot); | 2048 | update_slot_info(p_slot); |
2049 | 2049 | ||
2050 | return(rc); | 2050 | return rc; |
2051 | } | 2051 | } |
2052 | 2052 | ||
2053 | 2053 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 8568b207f189..6ca0061137a6 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf) | |||
73 | return (str - buf); | 73 | return (str - buf); |
74 | } | 74 | } |
75 | 75 | ||
76 | static ssize_t modalias_show(struct device *dev, char *buf) | ||
77 | { | ||
78 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
79 | |||
80 | return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", | ||
81 | pci_dev->vendor, pci_dev->device, | ||
82 | pci_dev->subsystem_vendor, pci_dev->subsystem_device, | ||
83 | (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), | ||
84 | (u8)(pci_dev->class)); | ||
85 | } | ||
86 | |||
76 | struct device_attribute pci_dev_attrs[] = { | 87 | struct device_attribute pci_dev_attrs[] = { |
77 | __ATTR_RO(resource), | 88 | __ATTR_RO(resource), |
78 | __ATTR_RO(vendor), | 89 | __ATTR_RO(vendor), |
@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = { | |||
82 | __ATTR_RO(class), | 93 | __ATTR_RO(class), |
83 | __ATTR_RO(irq), | 94 | __ATTR_RO(irq), |
84 | __ATTR_RO(local_cpus), | 95 | __ATTR_RO(local_cpus), |
96 | __ATTR_RO(modalias), | ||
85 | __ATTR_NULL, | 97 | __ATTR_NULL, |
86 | }; | 98 | }; |
87 | 99 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 79cdc16c52c8..744da0d4ae5f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void); | |||
32 | extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); | 32 | extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
33 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | 33 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); |
34 | 34 | ||
35 | struct pci_dev_wrapped { | ||
36 | struct pci_dev *dev; | ||
37 | void *data; | ||
38 | }; | ||
39 | |||
40 | struct pci_bus_wrapped { | ||
41 | struct pci_bus *bus; | ||
42 | void *data; | ||
43 | }; | ||
44 | |||
45 | struct pci_visit { | ||
46 | int (* pre_visit_pci_bus) (struct pci_bus_wrapped *, | ||
47 | struct pci_dev_wrapped *); | ||
48 | int (* post_visit_pci_bus) (struct pci_bus_wrapped *, | ||
49 | struct pci_dev_wrapped *); | ||
50 | |||
51 | int (* pre_visit_pci_dev) (struct pci_dev_wrapped *, | ||
52 | struct pci_bus_wrapped *); | ||
53 | int (* visit_pci_dev) (struct pci_dev_wrapped *, | ||
54 | struct pci_bus_wrapped *); | ||
55 | int (* post_visit_pci_dev) (struct pci_dev_wrapped *, | ||
56 | struct pci_bus_wrapped *); | ||
57 | }; | ||
58 | |||
59 | extern int pci_visit_dev(struct pci_visit *fn, | ||
60 | struct pci_dev_wrapped *wrapped_dev, | ||
61 | struct pci_bus_wrapped *wrapped_parent); | ||
62 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 35 | extern void pci_remove_legacy_files(struct pci_bus *bus); |
63 | 36 | ||
64 | /* Lock for read/write access to pci device and bus lists */ | 37 | /* Lock for read/write access to pci device and bus lists */ |
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index 4037a3e568de..3e84b501e6a4 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
39 | driver->id_table->vendor != pciedev->id.vendor) || | 39 | driver->id_table->vendor != pciedev->id.vendor) || |
40 | (driver->id_table->device != PCI_ANY_ID && | 40 | (driver->id_table->device != PCI_ANY_ID && |
41 | driver->id_table->device != pciedev->id.device) || | 41 | driver->id_table->device != pciedev->id.device) || |
42 | driver->id_table->port_type != pciedev->id.port_type || | 42 | (driver->id_table->port_type != PCIE_ANY_PORT && |
43 | driver->id_table->port_type != pciedev->id.port_type) || | ||
43 | driver->id_table->service_type != pciedev->id.service_type ) | 44 | driver->id_table->service_type != pciedev->id.service_type ) |
44 | return 0; | 45 | return 0; |
45 | 46 | ||
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0b5d3a5b7eda..ee9b96da841e 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1253,11 +1253,11 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1253 | unsigned long timeout = jiffies + (HZ * 5); | 1253 | unsigned long timeout = jiffies + (HZ * 5); |
1254 | 1254 | ||
1255 | if (ap->flags & ATA_FLAG_SATA_RESET) { | 1255 | if (ap->flags & ATA_FLAG_SATA_RESET) { |
1256 | scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */ | 1256 | /* issue phy wake/reset */ |
1257 | scr_read(ap, SCR_STATUS); /* dummy read; flush */ | 1257 | scr_write_flush(ap, SCR_CONTROL, 0x301); |
1258 | udelay(400); /* FIXME: a guess */ | 1258 | udelay(400); /* FIXME: a guess */ |
1259 | } | 1259 | } |
1260 | scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */ | 1260 | scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ |
1261 | 1261 | ||
1262 | /* wait for phy to become ready, if necessary */ | 1262 | /* wait for phy to become ready, if necessary */ |
1263 | do { | 1263 | do { |
@@ -2539,7 +2539,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
2539 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); | 2539 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); |
2540 | qc->dma_dir = DMA_FROM_DEVICE; | 2540 | qc->dma_dir = DMA_FROM_DEVICE; |
2541 | 2541 | ||
2542 | memset(&qc->cdb, 0, sizeof(ap->cdb_len)); | 2542 | memset(&qc->cdb, 0, ap->cdb_len); |
2543 | qc->cdb[0] = REQUEST_SENSE; | 2543 | qc->cdb[0] = REQUEST_SENSE; |
2544 | qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; | 2544 | qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; |
2545 | 2545 | ||
@@ -2811,6 +2811,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
2811 | 2811 | ||
2812 | /* call completion callback */ | 2812 | /* call completion callback */ |
2813 | rc = qc->complete_fn(qc, drv_stat); | 2813 | rc = qc->complete_fn(qc, drv_stat); |
2814 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | ||
2814 | 2815 | ||
2815 | /* if callback indicates not to complete command (non-zero), | 2816 | /* if callback indicates not to complete command (non-zero), |
2816 | * return immediately | 2817 | * return immediately |
@@ -3229,7 +3230,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
3229 | struct ata_queued_cmd *qc; | 3230 | struct ata_queued_cmd *qc; |
3230 | 3231 | ||
3231 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3232 | qc = ata_qc_from_tag(ap, ap->active_tag); |
3232 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) | 3233 | if (qc && (!(qc->tf.ctl & ATA_NIEN)) && |
3234 | (qc->flags & ATA_QCFLAG_ACTIVE)) | ||
3233 | handled |= ata_host_intr(ap, qc); | 3235 | handled |= ata_host_intr(ap, qc); |
3234 | } | 3236 | } |
3235 | } | 3237 | } |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 4c96df060c3b..416ba67ba9ee 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev) | |||
347 | */ | 347 | */ |
348 | if ((dev->flags & ATA_DFLAG_LBA48) && | 348 | if ((dev->flags & ATA_DFLAG_LBA48) && |
349 | ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { | 349 | ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { |
350 | sdev->host->max_sectors = 2048; | 350 | /* |
351 | * do not overwrite sdev->host->max_sectors, since | ||
352 | * other drives on this host may not support LBA48 | ||
353 | */ | ||
351 | blk_queue_max_sectors(sdev->request_queue, 2048); | 354 | blk_queue_max_sectors(sdev->request_queue, 2048); |
352 | } | 355 | } |
353 | } | 356 | } |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 8d1a5d25c053..05075bd3a893 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -395,7 +395,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
395 | 395 | ||
396 | /* Clear a magic bit in SCR1 according to Darwin, those help | 396 | /* Clear a magic bit in SCR1 according to Darwin, those help |
397 | * some funky seagate drives (though so far, those were already | 397 | * some funky seagate drives (though so far, those were already |
398 | * set by the firmware on the machines I had access to | 398 | * set by the firmware on the machines I had access to) |
399 | */ | 399 | */ |
400 | writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000, | 400 | writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000, |
401 | mmio_base + K2_SATA_SICR1_OFFSET); | 401 | mmio_base + K2_SATA_SICR1_OFFSET); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 545b440a2d2f..981ccb233ef5 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function, | |||
225 | int errno) | 225 | int errno) |
226 | { | 226 | { |
227 | char nbuf[16]; | 227 | char nbuf[16]; |
228 | const char *errstr = ext3_decode_error(sb, errno, nbuf); | 228 | const char *errstr; |
229 | |||
230 | /* Special case: if the error is EROFS, and we're not already | ||
231 | * inside a transaction, then there's really no point in logging | ||
232 | * an error. */ | ||
233 | if (errno == -EROFS && journal_current_handle() == NULL && | ||
234 | (sb->s_flags & MS_RDONLY)) | ||
235 | return; | ||
229 | 236 | ||
237 | errstr = ext3_decode_error(sb, errno, nbuf); | ||
230 | printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", | 238 | printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", |
231 | sb->s_id, function, errstr); | 239 | sb->s_id, function, errstr); |
232 | 240 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 505160ab472b..1f7e2039a04e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -584,6 +584,13 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) | |||
584 | ap->ops->scr_write(ap, reg, val); | 584 | ap->ops->scr_write(ap, reg, val); |
585 | } | 585 | } |
586 | 586 | ||
587 | static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, | ||
588 | u32 val) | ||
589 | { | ||
590 | ap->ops->scr_write(ap, reg, val); | ||
591 | (void) ap->ops->scr_read(ap, reg); | ||
592 | } | ||
593 | |||
587 | static inline unsigned int sata_dev_present(struct ata_port *ap) | 594 | static inline unsigned int sata_dev_present(struct ata_port *ap) |
588 | { | 595 | { |
589 | return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; | 596 | return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; |