]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/pci/hotplug/cpqphp_core.c
PCI Hotplug: cpqphp: obey 80 column convention in cpqphp.h
[mirror_ubuntu-bionic-kernel.git] / drivers / pci / hotplug / cpqphp_core.c
CommitLineData
1da177e4
LT
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 * Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
861fefbf 28 * Torben Mathiasen <torben.mathiasen@hp.com>
1da177e4
LT
29 */
30
1da177e4
LT
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h>
7a54f25c 39#include <linux/pci_hotplug.h>
1da177e4
LT
40#include <linux/init.h>
41#include <linux/interrupt.h>
42
43#include <asm/uaccess.h>
44
45#include "cpqphp.h"
46#include "cpqphp_nvram.h"
82487711 47#include <asm/pci_x86.h>
1da177e4
LT
48
49
50/* Global variables */
51int cpqhp_debug;
52int cpqhp_legacy_mode;
53struct controller *cpqhp_ctrl_list; /* = NULL */
54struct pci_func *cpqhp_slot_list[256];
55
56/* local variables */
57static void __iomem *smbios_table;
58static void __iomem *smbios_start;
59static void __iomem *cpqhp_rom_start;
60static int power_mode;
61static int debug;
4002307d 62static int initialized;
1da177e4
LT
63
64#define DRIVER_VERSION "0.9.8"
65#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
66#define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver"
67
68MODULE_AUTHOR(DRIVER_AUTHOR);
69MODULE_DESCRIPTION(DRIVER_DESC);
70MODULE_LICENSE("GPL");
71
72module_param(power_mode, bool, 0644);
73MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
74
75module_param(debug, bool, 0644);
76MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
77
78#define CPQHPC_MODULE_MINOR 208
79
80static int one_time_init (void);
81static int set_attention_status (struct hotplug_slot *slot, u8 value);
82static int process_SI (struct hotplug_slot *slot);
83static int process_SS (struct hotplug_slot *slot);
84static int hardware_test (struct hotplug_slot *slot, u32 value);
85static int get_power_status (struct hotplug_slot *slot, u8 *value);
86static int get_attention_status (struct hotplug_slot *slot, u8 *value);
87static int get_latch_status (struct hotplug_slot *slot, u8 *value);
88static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
89static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
90static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
91
92static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
93 .owner = THIS_MODULE,
94 .set_attention_status = set_attention_status,
95 .enable_slot = process_SI,
96 .disable_slot = process_SS,
97 .hardware_test = hardware_test,
98 .get_power_status = get_power_status,
99 .get_attention_status = get_attention_status,
100 .get_latch_status = get_latch_status,
101 .get_adapter_status = get_adapter_status,
861fefbf
AC
102 .get_max_bus_speed = get_max_bus_speed,
103 .get_cur_bus_speed = get_cur_bus_speed,
1da177e4
LT
104};
105
106
107static inline int is_slot64bit(struct slot *slot)
108{
109 return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
110}
111
112static inline int is_slot66mhz(struct slot *slot)
113{
114 return (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E) ? 1 : 0;
115}
116
117/**
118 * detect_SMBIOS_pointer - find the System Management BIOS Table in mem region.
1da177e4
LT
119 * @begin: begin pointer for region to be scanned.
120 * @end: end pointer for region to be scanned.
121 *
26e6c66e 122 * Returns pointer to the head of the SMBIOS tables (or %NULL).
1da177e4
LT
123 */
124static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
125{
126 void __iomem *fp;
127 void __iomem *endp;
128 u8 temp1, temp2, temp3, temp4;
129 int status = 0;
130
131 endp = (end - sizeof(u32) + 1);
132
133 for (fp = begin; fp <= endp; fp += 16) {
134 temp1 = readb(fp);
135 temp2 = readb(fp+1);
136 temp3 = readb(fp+2);
137 temp4 = readb(fp+3);
138 if (temp1 == '_' &&
139 temp2 == 'S' &&
140 temp3 == 'M' &&
141 temp4 == '_') {
142 status = 1;
143 break;
144 }
145 }
861fefbf 146
1da177e4
LT
147 if (!status)
148 fp = NULL;
149
150 dbg("Discovered SMBIOS Entry point at %p\n", fp);
151
152 return fp;
153}
154
155/**
156 * init_SERR - Initializes the per slot SERR generation.
26e6c66e 157 * @ctrl: controller to use
1da177e4
LT
158 *
159 * For unexpected switch opens
1da177e4
LT
160 */
161static int init_SERR(struct controller * ctrl)
162{
163 u32 tempdword;
164 u32 number_of_slots;
165 u8 physical_slot;
166
167 if (!ctrl)
168 return 1;
169
170 tempdword = ctrl->first_slot;
171
172 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
427438c6 173 /* Loop through slots */
1da177e4
LT
174 while (number_of_slots) {
175 physical_slot = tempdword;
176 writeb(0, ctrl->hpc_reg + SLOT_SERR);
177 tempdword++;
178 number_of_slots--;
179 }
180
181 return 0;
182}
183
184
185/* nice debugging output */
186static int pci_print_IRQ_route (void)
187{
188 struct irq_routing_table *routing_table;
189 int len;
190 int loop;
191
192 u8 tbus, tdevice, tslot;
193
194 routing_table = pcibios_get_irq_routing_table();
195 if (routing_table == NULL) {
196 err("No BIOS Routing Table??? Not good\n");
197 return -ENOMEM;
198 }
199
200 len = (routing_table->size - sizeof(struct irq_routing_table)) /
201 sizeof(struct irq_info);
427438c6 202 /* Make sure I got at least one entry */
1da177e4
LT
203 if (len == 0) {
204 kfree(routing_table);
205 return -1;
206 }
207
208 dbg("bus dev func slot\n");
209
210 for (loop = 0; loop < len; ++loop) {
211 tbus = routing_table->slots[loop].bus;
212 tdevice = routing_table->slots[loop].devfn;
213 tslot = routing_table->slots[loop].slot;
214 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
215
216 }
217 kfree(routing_table);
218 return 0;
219}
220
221
222/**
223 * get_subsequent_smbios_entry: get the next entry from bios table.
26e6c66e
RD
224 * @smbios_start: where to start in the SMBIOS table
225 * @smbios_table: location of the SMBIOS table
1da177e4
LT
226 * @curr: %NULL or pointer to previously returned structure
227 *
26e6c66e
RD
228 * Gets the first entry if previous == NULL;
229 * otherwise, returns the next entry.
230 * Uses global SMBIOS Table pointer.
231 *
232 * Returns a pointer to an SMBIOS structure or NULL if none found.
1da177e4
LT
233 */
234static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
235 void __iomem *smbios_table,
236 void __iomem *curr)
237{
238 u8 bail = 0;
239 u8 previous_byte = 1;
240 void __iomem *p_temp;
241 void __iomem *p_max;
242
243 if (!smbios_table || !curr)
244 return(NULL);
245
427438c6 246 /* set p_max to the end of the table */
1da177e4
LT
247 p_max = smbios_start + readw(smbios_table + ST_LENGTH);
248
249 p_temp = curr;
250 p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
251
252 while ((p_temp < p_max) && !bail) {
253 /* Look for the double NULL terminator
254 * The first condition is the previous byte
427438c6
AC
255 * and the second is the curr
256 */
1da177e4
LT
257 if (!previous_byte && !(readb(p_temp))) {
258 bail = 1;
259 }
260
261 previous_byte = readb(p_temp);
262 p_temp++;
263 }
264
265 if (p_temp < p_max) {
266 return p_temp;
267 } else {
268 return NULL;
269 }
270}
271
272
273/**
26e6c66e
RD
274 * get_SMBIOS_entry - return the requested SMBIOS entry or %NULL
275 * @smbios_start: where to start in the SMBIOS table
276 * @smbios_table: location of the SMBIOS table
277 * @type: SMBIOS structure type to be returned
1da177e4
LT
278 * @previous: %NULL or pointer to previously returned structure
279 *
26e6c66e 280 * Gets the first entry of the specified type if previous == %NULL;
1da177e4 281 * Otherwise, returns the next entry of the given type.
26e6c66e
RD
282 * Uses global SMBIOS Table pointer.
283 * Uses get_subsequent_smbios_entry.
1da177e4 284 *
26e6c66e 285 * Returns a pointer to an SMBIOS structure or %NULL if none found.
1da177e4
LT
286 */
287static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
288 void __iomem *smbios_table,
289 u8 type,
290 void __iomem *previous)
291{
292 if (!smbios_table)
293 return NULL;
294
861fefbf 295 if (!previous) {
1da177e4
LT
296 previous = smbios_start;
297 } else {
298 previous = get_subsequent_smbios_entry(smbios_start,
299 smbios_table, previous);
300 }
301
302 while (previous) {
861fefbf 303 if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
1da177e4
LT
304 previous = get_subsequent_smbios_entry(smbios_start,
305 smbios_table, previous);
306 } else {
307 break;
308 }
309 }
310
311 return previous;
312}
313
314static void release_slot(struct hotplug_slot *hotplug_slot)
315{
316 struct slot *slot = hotplug_slot->private;
317
30ac7acd 318 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
319
320 kfree(slot->hotplug_slot->info);
1da177e4
LT
321 kfree(slot->hotplug_slot);
322 kfree(slot);
323}
324
30ac7acd
AC
325#define SLOT_NAME_SIZE 10
326
1da177e4
LT
327static int ctrl_slot_setup(struct controller *ctrl,
328 void __iomem *smbios_start,
329 void __iomem *smbios_table)
330{
efbf62e9
JJ
331 struct slot *slot;
332 struct hotplug_slot *hotplug_slot;
333 struct hotplug_slot_info *hotplug_slot_info;
1da177e4
LT
334 u8 number_of_slots;
335 u8 slot_device;
336 u8 slot_number;
337 u8 ctrl_slot;
338 u32 tempdword;
30ac7acd 339 char name[SLOT_NAME_SIZE];
1da177e4
LT
340 void __iomem *slot_entry= NULL;
341 int result = -ENOMEM;
342
66bef8c0 343 dbg("%s\n", __func__);
1da177e4
LT
344
345 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
346
347 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
348 slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
349 slot_number = ctrl->first_slot;
350
351 while (number_of_slots) {
f5afe806 352 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
efbf62e9 353 if (!slot)
1da177e4
LT
354 goto error;
355
f5afe806 356 slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
1da177e4 357 GFP_KERNEL);
efbf62e9 358 if (!slot->hotplug_slot)
1da177e4 359 goto error_slot;
efbf62e9 360 hotplug_slot = slot->hotplug_slot;
1da177e4 361
efbf62e9 362 hotplug_slot->info =
f5afe806 363 kzalloc(sizeof(*(hotplug_slot->info)),
1da177e4 364 GFP_KERNEL);
efbf62e9 365 if (!hotplug_slot->info)
1da177e4 366 goto error_hpslot;
efbf62e9 367 hotplug_slot_info = hotplug_slot->info;
1da177e4 368
efbf62e9
JJ
369 slot->ctrl = ctrl;
370 slot->bus = ctrl->bus;
371 slot->device = slot_device;
372 slot->number = slot_number;
30ac7acd 373 dbg("slot->number = %u\n", slot->number);
1da177e4
LT
374
375 slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
376 slot_entry);
377
efbf62e9
JJ
378 while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
379 slot->number)) {
1da177e4
LT
380 slot_entry = get_SMBIOS_entry(smbios_start,
381 smbios_table, 9, slot_entry);
382 }
383
efbf62e9 384 slot->p_sm_slot = slot_entry;
1da177e4 385
efbf62e9
JJ
386 init_timer(&slot->task_event);
387 slot->task_event.expires = jiffies + 5 * HZ;
388 slot->task_event.function = cpqhp_pushbutton_thread;
1da177e4 389
427438c6
AC
390 /*FIXME: these capabilities aren't used but if they are
391 * they need to be correctly implemented
392 */
efbf62e9
JJ
393 slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
394 slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
1da177e4 395
efbf62e9
JJ
396 if (is_slot64bit(slot))
397 slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
398 if (is_slot66mhz(slot))
399 slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
1da177e4 400 if (ctrl->speed == PCI_SPEED_66MHz)
efbf62e9 401 slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
1da177e4 402
efbf62e9
JJ
403 ctrl_slot =
404 slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
1da177e4 405
427438c6 406 /* Check presence */
efbf62e9
JJ
407 slot->capabilities |=
408 ((((~tempdword) >> 23) |
409 ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
427438c6 410 /* Check the switch state */
efbf62e9
JJ
411 slot->capabilities |=
412 ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
427438c6 413 /* Check the slot enable */
efbf62e9
JJ
414 slot->capabilities |=
415 ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
1da177e4
LT
416
417 /* register this slot with the hotplug pci core */
efbf62e9
JJ
418 hotplug_slot->release = &release_slot;
419 hotplug_slot->private = slot;
30ac7acd 420 snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
efbf62e9 421 hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
30ac7acd 422
efbf62e9
JJ
423 hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
424 hotplug_slot_info->attention_status =
425 cpq_get_attention_status(ctrl, slot);
426 hotplug_slot_info->latch_status =
427 cpq_get_latch_status(ctrl, slot);
428 hotplug_slot_info->adapter_status =
429 get_presence_status(ctrl, slot);
861fefbf 430
efbf62e9 431 dbg("registering bus %d, dev %d, number %d, "
1da177e4 432 "ctrl->slot_device_offset %d, slot %d\n",
efbf62e9
JJ
433 slot->bus, slot->device,
434 slot->number, ctrl->slot_device_offset,
1da177e4 435 slot_number);
f46753c5 436 result = pci_hp_register(hotplug_slot,
d2174c3c 437 ctrl->pci_dev->bus,
1359f270 438 slot->device,
30ac7acd 439 name);
1da177e4 440 if (result) {
efbf62e9 441 err("pci_hp_register failed with error %d\n", result);
30ac7acd 442 goto error_info;
1da177e4 443 }
861fefbf 444
efbf62e9
JJ
445 slot->next = ctrl->slot;
446 ctrl->slot = slot;
1da177e4
LT
447
448 number_of_slots--;
449 slot_device++;
450 slot_number++;
451 }
452
453 return 0;
1da177e4 454error_info:
efbf62e9 455 kfree(hotplug_slot_info);
1da177e4 456error_hpslot:
efbf62e9 457 kfree(hotplug_slot);
1da177e4 458error_slot:
efbf62e9 459 kfree(slot);
1da177e4
LT
460error:
461 return result;
462}
463
464static int ctrl_slot_cleanup (struct controller * ctrl)
465{
466 struct slot *old_slot, *next_slot;
467
468 old_slot = ctrl->slot;
469 ctrl->slot = NULL;
470
471 while (old_slot) {
472 /* memory will be freed by the release_slot callback */
473 next_slot = old_slot->next;
474 pci_hp_deregister (old_slot->hotplug_slot);
475 old_slot = next_slot;
476 }
477
9f3f4681
GKH
478 cpqhp_remove_debugfs_files(ctrl);
479
427438c6 480 /* Free IRQ associated with hot plug device */
1da177e4 481 free_irq(ctrl->interrupt, ctrl);
427438c6 482 /* Unmap the memory */
1da177e4 483 iounmap(ctrl->hpc_reg);
427438c6 484 /* Finally reclaim PCI mem */
1da177e4
LT
485 release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
486 pci_resource_len(ctrl->pci_dev, 0));
487
488 return(0);
489}
490
491
427438c6
AC
492/**
493 * get_slot_mapping - determine logical slot mapping for PCI device
494 *
495 * Won't work for more than one PCI-PCI bridge in a slot.
496 *
497 * @bus_num - bus number of PCI device
498 * @dev_num - device number of PCI device
499 * @slot - Pointer to u8 where slot number will be returned
500 *
501 * Output: SUCCESS or FAILURE
502 */
1da177e4
LT
503static int
504get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
505{
506 struct irq_routing_table *PCIIRQRoutingInfoLength;
507 u32 work;
508 long len;
509 long loop;
510
511 u8 tbus, tdevice, tslot, bridgeSlot;
512
66bef8c0 513 dbg("%s: %p, %d, %d, %p\n", __func__, bus, bus_num, dev_num, slot);
1da177e4
LT
514
515 bridgeSlot = 0xFF;
516
517 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
518 if (!PCIIRQRoutingInfoLength)
519 return -1;
520
521 len = (PCIIRQRoutingInfoLength->size -
522 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
427438c6 523 /* Make sure I got at least one entry */
1da177e4
LT
524 if (len == 0) {
525 kfree(PCIIRQRoutingInfoLength);
526 return -1;
527 }
528
529 for (loop = 0; loop < len; ++loop) {
530 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
531 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
532 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
533
534 if ((tbus == bus_num) && (tdevice == dev_num)) {
535 *slot = tslot;
536 kfree(PCIIRQRoutingInfoLength);
537 return 0;
538 } else {
539 /* Did not get a match on the target PCI device. Check
427438c6
AC
540 * if the current IRQ table entry is a PCI-to-PCI
541 * bridge device. If so, and it's secondary bus
542 * matches the bus number for the target device, I need
543 * to save the bridge's slot number. If I can not find
544 * an entry for the target device, I will have to
545 * assume it's on the other side of the bridge, and
546 * assign it the bridge's slot.
547 */
1da177e4
LT
548 bus->number = tbus;
549 pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
3799a4e7 550 PCI_CLASS_REVISION, &work);
1da177e4
LT
551
552 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
553 pci_bus_read_config_dword(bus,
554 PCI_DEVFN(tdevice, 0),
555 PCI_PRIMARY_BUS, &work);
556 // See if bridge's secondary bus matches target bus.
557 if (((work >> 8) & 0x000000FF) == (long) bus_num) {
558 bridgeSlot = tslot;
559 }
560 }
561 }
562
563 }
564
427438c6
AC
565 /* If we got here, we didn't find an entry in the IRQ mapping table for
566 * the target PCI device. If we did determine that the target device
567 * is on the other side of a PCI-to-PCI bridge, return the slot number
568 * for the bridge.
569 */
1da177e4
LT
570 if (bridgeSlot != 0xFF) {
571 *slot = bridgeSlot;
572 kfree(PCIIRQRoutingInfoLength);
573 return 0;
574 }
575 kfree(PCIIRQRoutingInfoLength);
427438c6 576 /* Couldn't find an entry in the routing table for this PCI device */
1da177e4
LT
577 return -1;
578}
579
580
581/**
582 * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
26e6c66e
RD
583 * @ctrl: struct controller to use
584 * @func: PCI device/function info
585 * @status: LED control flag: 1 = LED on, 0 = LED off
1da177e4
LT
586 */
587static int
588cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
589 u32 status)
590{
591 u8 hp_slot;
592
593 if (func == NULL)
594 return(1);
595
596 hp_slot = func->device - ctrl->slot_device_offset;
597
427438c6 598 /* Wait for exclusive access to hardware */
6aa4cdd0 599 mutex_lock(&ctrl->crit_sect);
1da177e4
LT
600
601 if (status == 1) {
602 amber_LED_on (ctrl, hp_slot);
603 } else if (status == 0) {
604 amber_LED_off (ctrl, hp_slot);
605 } else {
427438c6 606 /* Done with exclusive hardware access */
6aa4cdd0 607 mutex_unlock(&ctrl->crit_sect);
1da177e4
LT
608 return(1);
609 }
610
611 set_SOGO(ctrl);
612
427438c6 613 /* Wait for SOBS to be unset */
1da177e4
LT
614 wait_for_ctrl_irq (ctrl);
615
427438c6 616 /* Done with exclusive hardware access */
6aa4cdd0 617 mutex_unlock(&ctrl->crit_sect);
1da177e4
LT
618
619 return(0);
620}
621
622
623/**
624 * set_attention_status - Turns the Amber LED for a slot on or off
26e6c66e
RD
625 * @hotplug_slot: slot to change LED on
626 * @status: LED control flag
1da177e4
LT
627 */
628static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
629{
630 struct pci_func *slot_func;
631 struct slot *slot = hotplug_slot->private;
632 struct controller *ctrl = slot->ctrl;
633 u8 bus;
634 u8 devfn;
635 u8 device;
636 u8 function;
637
30ac7acd 638 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
639
640 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
641 return -ENODEV;
642
643 device = devfn >> 3;
644 function = devfn & 0x7;
645 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
646
647 slot_func = cpqhp_slot_find(bus, device, function);
648 if (!slot_func)
649 return -ENODEV;
650
651 return cpqhp_set_attention_status(ctrl, slot_func, status);
652}
653
654
655static int process_SI(struct hotplug_slot *hotplug_slot)
656{
657 struct pci_func *slot_func;
658 struct slot *slot = hotplug_slot->private;
659 struct controller *ctrl = slot->ctrl;
660 u8 bus;
661 u8 devfn;
662 u8 device;
663 u8 function;
664
30ac7acd 665 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
666
667 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
668 return -ENODEV;
669
670 device = devfn >> 3;
671 function = devfn & 0x7;
672 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
673
674 slot_func = cpqhp_slot_find(bus, device, function);
675 if (!slot_func)
676 return -ENODEV;
677
678 slot_func->bus = bus;
679 slot_func->device = device;
680 slot_func->function = function;
681 slot_func->configured = 0;
682 dbg("board_added(%p, %p)\n", slot_func, ctrl);
683 return cpqhp_process_SI(ctrl, slot_func);
684}
685
686
687static int process_SS(struct hotplug_slot *hotplug_slot)
688{
689 struct pci_func *slot_func;
690 struct slot *slot = hotplug_slot->private;
691 struct controller *ctrl = slot->ctrl;
692 u8 bus;
693 u8 devfn;
694 u8 device;
695 u8 function;
696
30ac7acd 697 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
698
699 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
700 return -ENODEV;
701
702 device = devfn >> 3;
703 function = devfn & 0x7;
704 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
705
706 slot_func = cpqhp_slot_find(bus, device, function);
707 if (!slot_func)
708 return -ENODEV;
709
66bef8c0 710 dbg("In %s, slot_func = %p, ctrl = %p\n", __func__, slot_func, ctrl);
1da177e4
LT
711 return cpqhp_process_SS(ctrl, slot_func);
712}
713
714
715static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
716{
717 struct slot *slot = hotplug_slot->private;
718 struct controller *ctrl = slot->ctrl;
719
30ac7acd 720 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4 721
861fefbf 722 return cpqhp_hardware_test(ctrl, value);
1da177e4
LT
723}
724
725
726static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
727{
728 struct slot *slot = hotplug_slot->private;
729 struct controller *ctrl = slot->ctrl;
730
30ac7acd 731 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
732
733 *value = get_slot_enabled(ctrl, slot);
734 return 0;
735}
736
737static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
738{
739 struct slot *slot = hotplug_slot->private;
740 struct controller *ctrl = slot->ctrl;
861fefbf 741
30ac7acd 742 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
743
744 *value = cpq_get_attention_status(ctrl, slot);
745 return 0;
746}
747
748static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
749{
750 struct slot *slot = hotplug_slot->private;
751 struct controller *ctrl = slot->ctrl;
752
30ac7acd 753 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
754
755 *value = cpq_get_latch_status(ctrl, slot);
756
757 return 0;
758}
759
760static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
761{
762 struct slot *slot = hotplug_slot->private;
763 struct controller *ctrl = slot->ctrl;
764
30ac7acd 765 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
766
767 *value = get_presence_status(ctrl, slot);
768
769 return 0;
770}
771
772static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
773{
774 struct slot *slot = hotplug_slot->private;
775 struct controller *ctrl = slot->ctrl;
776
30ac7acd 777 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
778
779 *value = ctrl->speed_capability;
780
781 return 0;
782}
783
784static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
785{
786 struct slot *slot = hotplug_slot->private;
787 struct controller *ctrl = slot->ctrl;
788
30ac7acd 789 dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
1da177e4
LT
790
791 *value = ctrl->speed;
792
793 return 0;
794}
795
796static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
797{
798 u8 num_of_slots = 0;
799 u8 hp_slot = 0;
800 u8 device;
1da177e4
LT
801 u8 bus_cap;
802 u16 temp_word;
803 u16 vendor_id;
804 u16 subsystem_vid;
805 u16 subsystem_deviceid;
806 u32 rc;
807 struct controller *ctrl;
808 struct pci_func *func;
fe89cf4c
BH
809 int err;
810
811 err = pci_enable_device(pdev);
812 if (err) {
813 printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
814 pci_name(pdev), err);
815 return err;
816 }
1da177e4 817
427438c6
AC
818 /* Need to read VID early b/c it's used to differentiate CPQ and INTC
819 * discovery
820 */
1da177e4
LT
821 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
822 if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
823 err(msg_HPC_non_compaq_or_intel);
fe89cf4c
BH
824 rc = -ENODEV;
825 goto err_disable_device;
1da177e4
LT
826 }
827 dbg("Vendor ID: %x\n", vendor_id);
828
44c10138
AK
829 dbg("revision: %d\n", pdev->revision);
830 if ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!pdev->revision)) {
1da177e4 831 err(msg_HPC_rev_error);
fe89cf4c
BH
832 rc = -ENODEV;
833 goto err_disable_device;
1da177e4
LT
834 }
835
836 /* Check for the proper subsytem ID's
861fefbf 837 * Intel uses a different SSID programming model than Compaq.
1da177e4
LT
838 * For Intel, each SSID bit identifies a PHP capability.
839 * Also Intel HPC's may have RID=0.
840 */
44c10138 841 if ((pdev->revision > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
427438c6
AC
842 /* TODO: This code can be made to support non-Compaq or Intel
843 * subsystem IDs
844 */
1da177e4
LT
845 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
846 if (rc) {
66bef8c0 847 err("%s : pci_read_config_word failed\n", __func__);
fe89cf4c 848 goto err_disable_device;
1da177e4
LT
849 }
850 dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
851 if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
852 err(msg_HPC_non_compaq_or_intel);
fe89cf4c
BH
853 rc = -ENODEV;
854 goto err_disable_device;
1da177e4
LT
855 }
856
f5afe806 857 ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
1da177e4 858 if (!ctrl) {
66bef8c0 859 err("%s : out of memory\n", __func__);
fe89cf4c
BH
860 rc = -ENOMEM;
861 goto err_disable_device;
1da177e4 862 }
1da177e4
LT
863
864 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
865 if (rc) {
66bef8c0 866 err("%s : pci_read_config_word failed\n", __func__);
1da177e4
LT
867 goto err_free_ctrl;
868 }
869
870 info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
871
427438c6
AC
872 /* Set Vendor ID, so it can be accessed later from other
873 * functions
874 */
1da177e4
LT
875 ctrl->vendor_id = vendor_id;
876
877 switch (subsystem_vid) {
878 case PCI_VENDOR_ID_COMPAQ:
44c10138 879 if (pdev->revision >= 0x13) { /* CIOBX */
1da177e4
LT
880 ctrl->push_flag = 1;
881 ctrl->slot_switch_type = 1;
882 ctrl->push_button = 1;
883 ctrl->pci_config_space = 1;
884 ctrl->defeature_PHP = 1;
885 ctrl->pcix_support = 1;
886 ctrl->pcix_speed_capability = 1;
887 pci_read_config_byte(pdev, 0x41, &bus_cap);
888 if (bus_cap & 0x80) {
889 dbg("bus max supports 133MHz PCI-X\n");
890 ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
891 break;
892 }
893 if (bus_cap & 0x40) {
894 dbg("bus max supports 100MHz PCI-X\n");
895 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
896 break;
897 }
898 if (bus_cap & 20) {
899 dbg("bus max supports 66MHz PCI-X\n");
900 ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
901 break;
902 }
903 if (bus_cap & 10) {
904 dbg("bus max supports 66MHz PCI\n");
905 ctrl->speed_capability = PCI_SPEED_66MHz;
906 break;
907 }
908
909 break;
910 }
911
912 switch (subsystem_deviceid) {
913 case PCI_SUB_HPC_ID:
914 /* Original 6500/7000 implementation */
915 ctrl->slot_switch_type = 1;
916 ctrl->speed_capability = PCI_SPEED_33MHz;
917 ctrl->push_button = 0;
918 ctrl->pci_config_space = 1;
919 ctrl->defeature_PHP = 1;
920 ctrl->pcix_support = 0;
921 ctrl->pcix_speed_capability = 0;
922 break;
923 case PCI_SUB_HPC_ID2:
924 /* First Pushbutton implementation */
925 ctrl->push_flag = 1;
926 ctrl->slot_switch_type = 1;
927 ctrl->speed_capability = PCI_SPEED_33MHz;
928 ctrl->push_button = 1;
929 ctrl->pci_config_space = 1;
930 ctrl->defeature_PHP = 1;
931 ctrl->pcix_support = 0;
932 ctrl->pcix_speed_capability = 0;
933 break;
934 case PCI_SUB_HPC_ID_INTC:
935 /* Third party (6500/7000) */
936 ctrl->slot_switch_type = 1;
937 ctrl->speed_capability = PCI_SPEED_33MHz;
938 ctrl->push_button = 0;
939 ctrl->pci_config_space = 1;
940 ctrl->defeature_PHP = 1;
941 ctrl->pcix_support = 0;
942 ctrl->pcix_speed_capability = 0;
943 break;
944 case PCI_SUB_HPC_ID3:
945 /* First 66 Mhz implementation */
946 ctrl->push_flag = 1;
947 ctrl->slot_switch_type = 1;
948 ctrl->speed_capability = PCI_SPEED_66MHz;
949 ctrl->push_button = 1;
950 ctrl->pci_config_space = 1;
951 ctrl->defeature_PHP = 1;
952 ctrl->pcix_support = 0;
953 ctrl->pcix_speed_capability = 0;
954 break;
955 case PCI_SUB_HPC_ID4:
956 /* First PCI-X implementation, 100MHz */
957 ctrl->push_flag = 1;
958 ctrl->slot_switch_type = 1;
959 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
960 ctrl->push_button = 1;
961 ctrl->pci_config_space = 1;
962 ctrl->defeature_PHP = 1;
963 ctrl->pcix_support = 1;
964 ctrl->pcix_speed_capability = 0;
965 break;
966 default:
967 err(msg_HPC_not_supported);
968 rc = -ENODEV;
969 goto err_free_ctrl;
970 }
971 break;
972
973 case PCI_VENDOR_ID_INTEL:
974 /* Check for speed capability (0=33, 1=66) */
975 if (subsystem_deviceid & 0x0001) {
976 ctrl->speed_capability = PCI_SPEED_66MHz;
977 } else {
978 ctrl->speed_capability = PCI_SPEED_33MHz;
979 }
980
981 /* Check for push button */
982 if (subsystem_deviceid & 0x0002) {
983 /* no push button */
984 ctrl->push_button = 0;
985 } else {
986 /* push button supported */
987 ctrl->push_button = 1;
988 }
989
990 /* Check for slot switch type (0=mechanical, 1=not mechanical) */
991 if (subsystem_deviceid & 0x0004) {
992 /* no switch */
993 ctrl->slot_switch_type = 0;
994 } else {
995 /* switch */
996 ctrl->slot_switch_type = 1;
997 }
998
999 /* PHP Status (0=De-feature PHP, 1=Normal operation) */
1000 if (subsystem_deviceid & 0x0008) {
427438c6 1001 ctrl->defeature_PHP = 1; /* PHP supported */
1da177e4 1002 } else {
427438c6 1003 ctrl->defeature_PHP = 0; /* PHP not supported */
1da177e4
LT
1004 }
1005
1006 /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
1007 if (subsystem_deviceid & 0x0010) {
427438c6 1008 ctrl->alternate_base_address = 1; /* supported */
1da177e4 1009 } else {
427438c6 1010 ctrl->alternate_base_address = 0; /* not supported */
1da177e4
LT
1011 }
1012
1013 /* PCI Config Space Index (0=not supported, 1=supported) */
1014 if (subsystem_deviceid & 0x0020) {
427438c6 1015 ctrl->pci_config_space = 1; /* supported */
1da177e4 1016 } else {
427438c6 1017 ctrl->pci_config_space = 0; /* not supported */
1da177e4
LT
1018 }
1019
1020 /* PCI-X support */
1021 if (subsystem_deviceid & 0x0080) {
1022 /* PCI-X capable */
1023 ctrl->pcix_support = 1;
1024 /* Frequency of operation in PCI-X mode */
1025 if (subsystem_deviceid & 0x0040) {
1026 /* 133MHz PCI-X if bit 7 is 1 */
1027 ctrl->pcix_speed_capability = 1;
1028 } else {
1029 /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
1030 /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
1031 ctrl->pcix_speed_capability = 0;
1032 }
1033 } else {
1034 /* Conventional PCI */
1035 ctrl->pcix_support = 0;
1036 ctrl->pcix_speed_capability = 0;
1037 }
1038 break;
1039
1040 default:
1041 err(msg_HPC_not_supported);
1042 rc = -ENODEV;
1043 goto err_free_ctrl;
1044 }
1045
1046 } else {
1047 err(msg_HPC_not_supported);
1048 return -ENODEV;
1049 }
1050
427438c6 1051 /* Tell the user that we found one. */
1da177e4
LT
1052 info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
1053 pdev->bus->number);
1054
1055 dbg("Hotplug controller capabilities:\n");
1056 dbg(" speed_capability %d\n", ctrl->speed_capability);
1057 dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ?
1058 "switch present" : "no switch");
1059 dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ?
1060 "PHP supported" : "PHP not supported");
1061 dbg(" alternate_base_address %s\n", ctrl->alternate_base_address ?
1062 "supported" : "not supported");
1063 dbg(" pci_config_space %s\n", ctrl->pci_config_space ?
1064 "supported" : "not supported");
1065 dbg(" pcix_speed_capability %s\n", ctrl->pcix_speed_capability ?
1066 "supported" : "not supported");
1067 dbg(" pcix_support %s\n", ctrl->pcix_support ?
1068 "supported" : "not supported");
1069
1070 ctrl->pci_dev = pdev;
1071 pci_set_drvdata(pdev, ctrl);
1072
1073 /* make our own copy of the pci bus structure,
1074 * as we like tweaking it a lot */
1075 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
1076 if (!ctrl->pci_bus) {
1077 err("out of memory\n");
1078 rc = -ENOMEM;
1079 goto err_free_ctrl;
1080 }
1081 memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
1082
1083 ctrl->bus = pdev->bus->number;
44c10138 1084 ctrl->rev = pdev->revision;
1da177e4
LT
1085 dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
1086 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
1087
6aa4cdd0 1088 mutex_init(&ctrl->crit_sect);
1da177e4
LT
1089 init_waitqueue_head(&ctrl->queue);
1090
1091 /* initialize our threads if they haven't already been started up */
1092 rc = one_time_init();
1093 if (rc) {
1094 goto err_free_bus;
1095 }
861fefbf 1096
1da177e4 1097 dbg("pdev = %p\n", pdev);
1396a8c3
GKH
1098 dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0));
1099 dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0));
1da177e4
LT
1100
1101 if (!request_mem_region(pci_resource_start(pdev, 0),
1102 pci_resource_len(pdev, 0), MY_NAME)) {
1103 err("cannot reserve MMIO region\n");
1104 rc = -ENOMEM;
1105 goto err_free_bus;
1106 }
1107
1108 ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0),
1109 pci_resource_len(pdev, 0));
1110 if (!ctrl->hpc_reg) {
1396a8c3
GKH
1111 err("cannot remap MMIO region %llx @ %llx\n",
1112 (unsigned long long)pci_resource_len(pdev, 0),
1113 (unsigned long long)pci_resource_start(pdev, 0));
1da177e4
LT
1114 rc = -ENODEV;
1115 goto err_free_mem_region;
1116 }
1117
1118 // Check for 66Mhz operation
1119 ctrl->speed = get_controller_speed(ctrl);
1120
1121
1122 /********************************************************
1123 *
1124 * Save configuration headers for this and
1125 * subordinate PCI buses
1126 *
1127 ********************************************************/
1128
427438c6 1129 /* find the physical slot number of the first hot plug slot */
1da177e4
LT
1130
1131 /* Get slot won't work for devices behind bridges, but
1132 * in this case it will always be called for the "base"
1133 * bus/dev/func of a slot.
1134 * CS: this is leveraging the PCIIRQ routing code from the kernel
1135 * (pci-pc.c: get_irq_routing_table) */
1136 rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number,
1137 (readb(ctrl->hpc_reg + SLOT_MASK) >> 4),
1138 &(ctrl->first_slot));
1139 dbg("get_slot_mapping: first_slot = %d, returned = %d\n",
1140 ctrl->first_slot, rc);
1141 if (rc) {
1142 err(msg_initialization_err, rc);
1143 goto err_iounmap;
1144 }
1145
427438c6 1146 /* Store PCI Config Space for all devices on this bus */
1da177e4
LT
1147 rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
1148 if (rc) {
1149 err("%s: unable to save PCI configuration data, error %d\n",
66bef8c0 1150 __func__, rc);
1da177e4
LT
1151 goto err_iounmap;
1152 }
1153
1154 /*
1155 * Get IO, memory, and IRQ resources for new devices
1156 */
427438c6 1157 /* The next line is required for cpqhp_find_available_resources */
1da177e4
LT
1158 ctrl->interrupt = pdev->irq;
1159 if (ctrl->interrupt < 0x10) {
1160 cpqhp_legacy_mode = 1;
1161 dbg("System seems to be configured for Full Table Mapped MPS mode\n");
1162 }
1163
1164 ctrl->cfgspc_irq = 0;
1165 pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
1166
1167 rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
1168 ctrl->add_support = !rc;
1169 if (rc) {
1170 dbg("cpqhp_find_available_resources = 0x%x\n", rc);
1171 err("unable to locate PCI configuration resources for hot plug add.\n");
1172 goto err_iounmap;
1173 }
1174
1175 /*
1176 * Finish setting up the hot plug ctrl device
1177 */
1178 ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1179 dbg("NumSlots %d \n", ctrl->slot_device_offset);
1180
1181 ctrl->next_event = 0;
1182
1183 /* Setup the slot information structures */
1184 rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
1185 if (rc) {
1186 err(msg_initialization_err, 6);
1187 err("%s: unable to save PCI configuration data, error %d\n",
66bef8c0 1188 __func__, rc);
1da177e4
LT
1189 goto err_iounmap;
1190 }
861fefbf 1191
1da177e4
LT
1192 /* Mask all general input interrupts */
1193 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
1194
1195 /* set up the interrupt */
1196 dbg("HPC interrupt = %d \n", ctrl->interrupt);
1197 if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
6b4486e2 1198 IRQF_SHARED, MY_NAME, ctrl)) {
1da177e4
LT
1199 err("Can't get irq %d for the hotplug pci controller\n",
1200 ctrl->interrupt);
1201 rc = -ENODEV;
1202 goto err_iounmap;
1203 }
1204
427438c6
AC
1205 /* Enable Shift Out interrupt and clear it, also enable SERR on power
1206 * fault
1207 */
1da177e4
LT
1208 temp_word = readw(ctrl->hpc_reg + MISC);
1209 temp_word |= 0x4006;
1210 writew(temp_word, ctrl->hpc_reg + MISC);
1211
427438c6 1212 /* Changed 05/05/97 to clear all interrupts at start */
1da177e4
LT
1213 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
1214
1215 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
1216
1217 writel(0x0L, ctrl->hpc_reg + INT_MASK);
1218
1219 if (!cpqhp_ctrl_list) {
1220 cpqhp_ctrl_list = ctrl;
1221 ctrl->next = NULL;
1222 } else {
1223 ctrl->next = cpqhp_ctrl_list;
1224 cpqhp_ctrl_list = ctrl;
1225 }
1226
427438c6
AC
1227 /* turn off empty slots here unless command line option "ON" set
1228 * Wait for exclusive access to hardware
1229 */
6aa4cdd0 1230 mutex_lock(&ctrl->crit_sect);
1da177e4
LT
1231
1232 num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
1233
427438c6 1234 /* find first device number for the ctrl */
1da177e4
LT
1235 device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1236
1237 while (num_of_slots) {
1238 dbg("num_of_slots: %d\n", num_of_slots);
1239 func = cpqhp_slot_find(ctrl->bus, device, 0);
1240 if (!func)
1241 break;
1242
1243 hp_slot = func->device - ctrl->slot_device_offset;
1244 dbg("hp_slot: %d\n", hp_slot);
1245
427438c6 1246 /* We have to save the presence info for these slots */
1da177e4
LT
1247 temp_word = ctrl->ctrl_int_comp >> 16;
1248 func->presence_save = (temp_word >> hp_slot) & 0x01;
1249 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
1250
1251 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
1252 func->switch_save = 0;
1253 } else {
1254 func->switch_save = 0x10;
1255 }
1256
1257 if (!power_mode) {
1258 if (!func->is_a_board) {
1259 green_LED_off(ctrl, hp_slot);
1260 slot_disable(ctrl, hp_slot);
1261 }
1262 }
1263
1264 device++;
1265 num_of_slots--;
1266 }
1267
1268 if (!power_mode) {
1269 set_SOGO(ctrl);
427438c6 1270 /* Wait for SOBS to be unset */
1da177e4
LT
1271 wait_for_ctrl_irq(ctrl);
1272 }
1273
1274 rc = init_SERR(ctrl);
1275 if (rc) {
1276 err("init_SERR failed\n");
6aa4cdd0 1277 mutex_unlock(&ctrl->crit_sect);
1da177e4
LT
1278 goto err_free_irq;
1279 }
1280
427438c6 1281 /* Done with exclusive hardware access */
6aa4cdd0 1282 mutex_unlock(&ctrl->crit_sect);
1da177e4 1283
9f3f4681 1284 cpqhp_create_debugfs_files(ctrl);
1da177e4
LT
1285
1286 return 0;
1287
1288err_free_irq:
1289 free_irq(ctrl->interrupt, ctrl);
1290err_iounmap:
1291 iounmap(ctrl->hpc_reg);
1292err_free_mem_region:
1293 release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1294err_free_bus:
1295 kfree(ctrl->pci_bus);
1296err_free_ctrl:
1297 kfree(ctrl);
fe89cf4c
BH
1298err_disable_device:
1299 pci_disable_device(pdev);
1da177e4
LT
1300 return rc;
1301}
1302
1da177e4
LT
1303static int one_time_init(void)
1304{
1305 int loop;
1306 int retval = 0;
1da177e4
LT
1307
1308 if (initialized)
1309 return 0;
1310
1311 power_mode = 0;
1312
1313 retval = pci_print_IRQ_route();
1314 if (retval)
1315 goto error;
1316
1317 dbg("Initialize + Start the notification mechanism \n");
1318
1319 retval = cpqhp_event_start_thread();
1320 if (retval)
1321 goto error;
1322
1323 dbg("Initialize slot lists\n");
1324 for (loop = 0; loop < 256; loop++) {
1325 cpqhp_slot_list[loop] = NULL;
1326 }
1327
427438c6
AC
1328 /* FIXME: We also need to hook the NMI handler eventually.
1329 * this also needs to be worked with Christoph
1330 * register_NMI_handler();
1331 */
1332 /* Map rom address */
1da177e4
LT
1333 cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
1334 if (!cpqhp_rom_start) {
1335 err ("Could not ioremap memory region for ROM\n");
1336 retval = -EIO;
1337 goto error;
1338 }
861fefbf 1339
427438c6
AC
1340 /* Now, map the int15 entry point if we are on compaq specific
1341 * hardware
1342 */
1da177e4 1343 compaq_nvram_init(cpqhp_rom_start);
861fefbf 1344
1da177e4
LT
1345 /* Map smbios table entry point structure */
1346 smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
1347 cpqhp_rom_start + ROM_PHY_LEN);
1348 if (!smbios_table) {
1349 err ("Could not find the SMBIOS pointer in memory\n");
1350 retval = -EIO;
1351 goto error_rom_start;
1352 }
1353
1354 smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
1355 readw(smbios_table + ST_LENGTH));
1356 if (!smbios_start) {
1357 err ("Could not ioremap memory region taken from SMBIOS values\n");
1358 retval = -EIO;
1359 goto error_smbios_start;
1360 }
1361
1362 initialized = 1;
1363
1364 return retval;
1365
1366error_smbios_start:
1367 iounmap(smbios_start);
1368error_rom_start:
1369 iounmap(cpqhp_rom_start);
1370error:
1371 return retval;
1372}
1373
1da177e4
LT
1374static void __exit unload_cpqphpd(void)
1375{
1376 struct pci_func *next;
1377 struct pci_func *TempSlot;
1378 int loop;
1379 u32 rc;
1380 struct controller *ctrl;
1381 struct controller *tctrl;
1382 struct pci_resource *res;
1383 struct pci_resource *tres;
1384
1385 rc = compaq_nvram_store(cpqhp_rom_start);
1386
1387 ctrl = cpqhp_ctrl_list;
1388
1389 while (ctrl) {
1390 if (ctrl->hpc_reg) {
1391 u16 misc;
1392 rc = read_slot_enable (ctrl);
861fefbf 1393
1da177e4
LT
1394 writeb(0, ctrl->hpc_reg + SLOT_SERR);
1395 writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
861fefbf 1396
1da177e4
LT
1397 misc = readw(ctrl->hpc_reg + MISC);
1398 misc &= 0xFFFD;
1399 writew(misc, ctrl->hpc_reg + MISC);
1400 }
1401
1402 ctrl_slot_cleanup(ctrl);
1403
1404 res = ctrl->io_head;
1405 while (res) {
1406 tres = res;
1407 res = res->next;
1408 kfree(tres);
1409 }
1410
1411 res = ctrl->mem_head;
1412 while (res) {
1413 tres = res;
1414 res = res->next;
1415 kfree(tres);
1416 }
1417
1418 res = ctrl->p_mem_head;
1419 while (res) {
1420 tres = res;
1421 res = res->next;
1422 kfree(tres);
1423 }
1424
1425 res = ctrl->bus_head;
1426 while (res) {
1427 tres = res;
1428 res = res->next;
1429 kfree(tres);
1430 }
1431
1432 kfree (ctrl->pci_bus);
1433
1434 tctrl = ctrl;
1435 ctrl = ctrl->next;
1436 kfree(tctrl);
1437 }
1438
1439 for (loop = 0; loop < 256; loop++) {
1440 next = cpqhp_slot_list[loop];
1441 while (next != NULL) {
1442 res = next->io_head;
1443 while (res) {
1444 tres = res;
1445 res = res->next;
1446 kfree(tres);
1447 }
1448
1449 res = next->mem_head;
1450 while (res) {
1451 tres = res;
1452 res = res->next;
1453 kfree(tres);
1454 }
1455
1456 res = next->p_mem_head;
1457 while (res) {
1458 tres = res;
1459 res = res->next;
1460 kfree(tres);
1461 }
1462
1463 res = next->bus_head;
1464 while (res) {
1465 tres = res;
1466 res = res->next;
1467 kfree(tres);
1468 }
1469
1470 TempSlot = next;
1471 next = next->next;
1472 kfree(TempSlot);
1473 }
1474 }
1475
427438c6 1476 /* Stop the notification mechanism */
4002307d
KM
1477 if (initialized)
1478 cpqhp_event_stop_thread();
1da177e4 1479
427438c6 1480 /* unmap the rom address */
1da177e4
LT
1481 if (cpqhp_rom_start)
1482 iounmap(cpqhp_rom_start);
1483 if (smbios_start)
1484 iounmap(smbios_start);
1485}
1486
1da177e4
LT
1487static struct pci_device_id hpcd_pci_tbl[] = {
1488 {
1489 /* handle any PCI Hotplug controller */
1490 .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1491 .class_mask = ~0,
861fefbf 1492
1da177e4
LT
1493 /* no matter who makes it */
1494 .vendor = PCI_ANY_ID,
1495 .device = PCI_ANY_ID,
1496 .subvendor = PCI_ANY_ID,
1497 .subdevice = PCI_ANY_ID,
861fefbf 1498
1da177e4
LT
1499 }, { /* end: all zeroes */ }
1500};
1501
1502MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
1503
1da177e4
LT
1504static struct pci_driver cpqhpc_driver = {
1505 .name = "compaq_pci_hotplug",
1506 .id_table = hpcd_pci_tbl,
1507 .probe = cpqhpc_probe,
1508 /* remove: cpqhpc_remove_one, */
1509};
1510
1da177e4
LT
1511static int __init cpqhpc_init(void)
1512{
1513 int result;
1514
1515 cpqhp_debug = debug;
1516
1517 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
9f3f4681 1518 cpqhp_initialize_debugfs();
1da177e4
LT
1519 result = pci_register_driver(&cpqhpc_driver);
1520 dbg("pci_register_driver = %d\n", result);
1521 return result;
1522}
1523
1da177e4
LT
1524static void __exit cpqhpc_cleanup(void)
1525{
1526 dbg("unload_cpqphpd()\n");
1527 unload_cpqphpd();
1528
1529 dbg("pci_unregister_driver\n");
1530 pci_unregister_driver(&cpqhpc_driver);
9f3f4681 1531 cpqhp_shutdown_debugfs();
1da177e4
LT
1532}
1533
1da177e4
LT
1534module_init(cpqhpc_init);
1535module_exit(cpqhpc_cleanup);