[PATCH] s390: dasd open counter
[linux-2.6.22.y-op.git] / drivers / pci / hotplug / ibmphp_core.c
blobdc59da675c0807e3913a1dbf420bf2d15817fbde
1 /*
2 * IBM Hot Plug Controller Driver
4 * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
9 * All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Send feedback to <gregkh@us.ibm.com>
30 #include <linux/init.h>
31 #include <linux/module.h>
32 #include <linux/slab.h>
33 #include <linux/pci.h>
34 #include <linux/interrupt.h>
35 #include <linux/delay.h>
36 #include <linux/wait.h>
37 #include <linux/smp_lock.h>
38 #include "../pci.h"
39 #include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
40 #include "ibmphp.h"
42 #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
43 #define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
44 #define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
45 #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
46 #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
48 #define DRIVER_VERSION "0.6"
49 #define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
51 int ibmphp_debug;
53 static int debug;
54 module_param(debug, bool, S_IRUGO | S_IWUSR);
55 MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
56 MODULE_LICENSE ("GPL");
57 MODULE_DESCRIPTION (DRIVER_DESC);
59 struct pci_bus *ibmphp_pci_bus;
60 static int max_slots;
62 static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS
63 * tables don't provide default info for empty slots */
65 static int init_flag;
68 static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
70 static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
72 return get_max_adapter_speed_1 (hs, value, 1);
75 static inline int get_cur_bus_info(struct slot **sl)
77 int rc = 1;
78 struct slot * slot_cur = *sl;
80 debug("options = %x\n", slot_cur->ctrl->options);
81 debug("revision = %x\n", slot_cur->ctrl->revision);
83 if (READ_BUS_STATUS(slot_cur->ctrl))
84 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
86 if (rc)
87 return rc;
89 slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
90 if (READ_BUS_MODE(slot_cur->ctrl))
91 slot_cur->bus_on->current_bus_mode =
92 CURRENT_BUS_MODE(slot_cur->busstatus);
93 else
94 slot_cur->bus_on->current_bus_mode = 0xFF;
96 debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
97 slot_cur->busstatus,
98 slot_cur->bus_on->current_speed,
99 slot_cur->bus_on->current_bus_mode);
101 *sl = slot_cur;
102 return 0;
105 static inline int slot_update(struct slot **sl)
107 int rc;
108 rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
109 if (rc)
110 return rc;
111 if (!init_flag)
112 rc = get_cur_bus_info(sl);
113 return rc;
116 static int __init get_max_slots (void)
118 struct slot * slot_cur;
119 struct list_head * tmp;
120 u8 slot_count = 0;
122 list_for_each(tmp, &ibmphp_slot_head) {
123 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
124 /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
125 slot_count = max(slot_count, slot_cur->number);
127 return slot_count;
130 /* This routine will put the correct slot->device information per slot. It's
131 * called from initialization of the slot structures. It will also assign
132 * interrupt numbers per each slot.
133 * Parameters: struct slot
134 * Returns 0 or errors
136 int ibmphp_init_devno(struct slot **cur_slot)
138 struct irq_routing_table *rtable;
139 int len;
140 int loop;
141 int i;
143 rtable = pcibios_get_irq_routing_table();
144 if (!rtable) {
145 err("no BIOS routing table...\n");
146 return -ENOMEM;
149 len = (rtable->size - sizeof(struct irq_routing_table)) /
150 sizeof(struct irq_info);
152 if (!len)
153 return -1;
154 for (loop = 0; loop < len; loop++) {
155 if ((*cur_slot)->number == rtable->slots[loop].slot) {
156 if ((*cur_slot)->bus == rtable->slots[loop].bus) {
157 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
158 for (i = 0; i < 4; i++)
159 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
160 (int) (*cur_slot)->device, i);
162 debug("(*cur_slot)->irq[0] = %x\n",
163 (*cur_slot)->irq[0]);
164 debug("(*cur_slot)->irq[1] = %x\n",
165 (*cur_slot)->irq[1]);
166 debug("(*cur_slot)->irq[2] = %x\n",
167 (*cur_slot)->irq[2]);
168 debug("(*cur_slot)->irq[3] = %x\n",
169 (*cur_slot)->irq[3]);
171 debug("rtable->exlusive_irqs = %x\n",
172 rtable->exclusive_irqs);
173 debug("rtable->slots[loop].irq[0].bitmap = %x\n",
174 rtable->slots[loop].irq[0].bitmap);
175 debug("rtable->slots[loop].irq[1].bitmap = %x\n",
176 rtable->slots[loop].irq[1].bitmap);
177 debug("rtable->slots[loop].irq[2].bitmap = %x\n",
178 rtable->slots[loop].irq[2].bitmap);
179 debug("rtable->slots[loop].irq[3].bitmap = %x\n",
180 rtable->slots[loop].irq[3].bitmap);
182 debug("rtable->slots[loop].irq[0].link = %x\n",
183 rtable->slots[loop].irq[0].link);
184 debug("rtable->slots[loop].irq[1].link = %x\n",
185 rtable->slots[loop].irq[1].link);
186 debug("rtable->slots[loop].irq[2].link = %x\n",
187 rtable->slots[loop].irq[2].link);
188 debug("rtable->slots[loop].irq[3].link = %x\n",
189 rtable->slots[loop].irq[3].link);
190 debug("end of init_devno\n");
191 return 0;
196 return -1;
199 static inline int power_on(struct slot *slot_cur)
201 u8 cmd = HPC_SLOT_ON;
202 int retval;
204 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
205 if (retval) {
206 err("power on failed\n");
207 return retval;
209 if (CTLR_RESULT(slot_cur->ctrl->status)) {
210 err("command not completed successfully in power_on\n");
211 return -EIO;
213 msleep(3000); /* For ServeRAID cards, and some 66 PCI */
214 return 0;
217 static inline int power_off(struct slot *slot_cur)
219 u8 cmd = HPC_SLOT_OFF;
220 int retval;
222 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
223 if (retval) {
224 err("power off failed\n");
225 return retval;
227 if (CTLR_RESULT(slot_cur->ctrl->status)) {
228 err("command not completed successfully in power_off\n");
229 retval = -EIO;
231 return retval;
234 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
236 int rc = 0;
237 struct slot *pslot;
238 u8 cmd = 0x00; /* avoid compiler warning */
240 debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
241 (ulong) hotplug_slot, value);
242 ibmphp_lock_operations();
245 if (hotplug_slot) {
246 switch (value) {
247 case HPC_SLOT_ATTN_OFF:
248 cmd = HPC_SLOT_ATTNOFF;
249 break;
250 case HPC_SLOT_ATTN_ON:
251 cmd = HPC_SLOT_ATTNON;
252 break;
253 case HPC_SLOT_ATTN_BLINK:
254 cmd = HPC_SLOT_BLINKLED;
255 break;
256 default:
257 rc = -ENODEV;
258 err("set_attention_status - Error : invalid input [%x]\n",
259 value);
260 break;
262 if (rc == 0) {
263 pslot = hotplug_slot->private;
264 if (pslot)
265 rc = ibmphp_hpc_writeslot(pslot, cmd);
266 else
267 rc = -ENODEV;
269 } else
270 rc = -ENODEV;
272 ibmphp_unlock_operations();
274 debug("set_attention_status - Exit rc[%d]\n", rc);
275 return rc;
278 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
280 int rc = -ENODEV;
281 struct slot *pslot;
282 struct slot myslot;
284 debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
285 (ulong) hotplug_slot, (ulong) value);
287 ibmphp_lock_operations();
288 if (hotplug_slot && value) {
289 pslot = hotplug_slot->private;
290 if (pslot) {
291 memcpy(&myslot, pslot, sizeof(struct slot));
292 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
293 &(myslot.status));
294 if (!rc)
295 rc = ibmphp_hpc_readslot(pslot,
296 READ_EXTSLOTSTATUS,
297 &(myslot.ext_status));
298 if (!rc)
299 *value = SLOT_ATTN(myslot.status,
300 myslot.ext_status);
304 ibmphp_unlock_operations();
305 debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
306 return rc;
309 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
311 int rc = -ENODEV;
312 struct slot *pslot;
313 struct slot myslot;
315 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
316 (ulong) hotplug_slot, (ulong) value);
317 ibmphp_lock_operations();
318 if (hotplug_slot && value) {
319 pslot = hotplug_slot->private;
320 if (pslot) {
321 memcpy(&myslot, pslot, sizeof(struct slot));
322 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
323 &(myslot.status));
324 if (!rc)
325 *value = SLOT_LATCH(myslot.status);
329 ibmphp_unlock_operations();
330 debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
331 rc, rc, *value);
332 return rc;
336 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
338 int rc = -ENODEV;
339 struct slot *pslot;
340 struct slot myslot;
342 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
343 (ulong) hotplug_slot, (ulong) value);
344 ibmphp_lock_operations();
345 if (hotplug_slot && value) {
346 pslot = hotplug_slot->private;
347 if (pslot) {
348 memcpy(&myslot, pslot, sizeof(struct slot));
349 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
350 &(myslot.status));
351 if (!rc)
352 *value = SLOT_PWRGD(myslot.status);
356 ibmphp_unlock_operations();
357 debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
358 rc, rc, *value);
359 return rc;
362 static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
364 int rc = -ENODEV;
365 struct slot *pslot;
366 u8 present;
367 struct slot myslot;
369 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
370 (ulong) hotplug_slot, (ulong) value);
371 ibmphp_lock_operations();
372 if (hotplug_slot && value) {
373 pslot = hotplug_slot->private;
374 if (pslot) {
375 memcpy(&myslot, pslot, sizeof(struct slot));
376 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
377 &(myslot.status));
378 if (!rc) {
379 present = SLOT_PRESENT(myslot.status);
380 if (present == HPC_SLOT_EMPTY)
381 *value = 0;
382 else
383 *value = 1;
388 ibmphp_unlock_operations();
389 debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
390 return rc;
393 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
395 int rc = -ENODEV;
396 struct slot *pslot;
397 u8 mode = 0;
399 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
400 hotplug_slot, value);
402 ibmphp_lock_operations();
404 if (hotplug_slot && value) {
405 pslot = hotplug_slot->private;
406 if (pslot) {
407 rc = 0;
408 mode = pslot->supported_bus_mode;
409 *value = pslot->supported_speed;
410 switch (*value) {
411 case BUS_SPEED_33:
412 break;
413 case BUS_SPEED_66:
414 if (mode == BUS_MODE_PCIX)
415 *value += 0x01;
416 break;
417 case BUS_SPEED_100:
418 case BUS_SPEED_133:
419 *value = pslot->supported_speed + 0x01;
420 break;
421 default:
422 /* Note (will need to change): there would be soon 256, 512 also */
423 rc = -ENODEV;
428 ibmphp_unlock_operations();
429 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
430 return rc;
433 static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
435 int rc = -ENODEV;
436 struct slot *pslot;
437 u8 mode = 0;
439 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
440 hotplug_slot, value);
442 ibmphp_lock_operations();
444 if (hotplug_slot && value) {
445 pslot = hotplug_slot->private;
446 if (pslot) {
447 rc = get_cur_bus_info(&pslot);
448 if (!rc) {
449 mode = pslot->bus_on->current_bus_mode;
450 *value = pslot->bus_on->current_speed;
451 switch (*value) {
452 case BUS_SPEED_33:
453 break;
454 case BUS_SPEED_66:
455 if (mode == BUS_MODE_PCIX)
456 *value += 0x01;
457 else if (mode == BUS_MODE_PCI)
459 else
460 *value = PCI_SPEED_UNKNOWN;
461 break;
462 case BUS_SPEED_100:
463 case BUS_SPEED_133:
464 *value += 0x01;
465 break;
466 default:
467 /* Note of change: there would also be 256, 512 soon */
468 rc = -ENODEV;
474 ibmphp_unlock_operations();
475 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
476 return rc;
480 static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
482 int rc = -ENODEV;
483 struct slot *pslot;
484 struct slot myslot;
486 debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
487 (ulong)hotplug_slot, (ulong) value);
489 if (flag)
490 ibmphp_lock_operations();
492 if (hotplug_slot && value) {
493 pslot = hotplug_slot->private;
494 if (pslot) {
495 memcpy(&myslot, pslot, sizeof(struct slot));
496 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
497 &(myslot.status));
499 if (!(SLOT_LATCH (myslot.status)) &&
500 (SLOT_PRESENT (myslot.status))) {
501 rc = ibmphp_hpc_readslot(pslot,
502 READ_EXTSLOTSTATUS,
503 &(myslot.ext_status));
504 if (!rc)
505 *value = SLOT_SPEED(myslot.ext_status);
506 } else
507 *value = MAX_ADAPTER_NONE;
511 if (flag)
512 ibmphp_unlock_operations();
514 debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
515 return rc;
518 static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
520 int rc = -ENODEV;
521 struct slot *pslot = NULL;
523 debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
525 ibmphp_lock_operations();
527 if (hotplug_slot) {
528 pslot = hotplug_slot->private;
529 if (pslot) {
530 rc = 0;
531 snprintf(value, 100, "Bus %x", pslot->bus);
533 } else
534 rc = -ENODEV;
536 ibmphp_unlock_operations();
537 debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
538 return rc;
542 /****************************************************************************
543 * This routine will initialize the ops data structure used in the validate
544 * function. It will also power off empty slots that are powered on since BIOS
545 * leaves those on, albeit disconnected
546 ****************************************************************************/
547 static int __init init_ops(void)
549 struct slot *slot_cur;
550 struct list_head *tmp;
551 int retval;
552 int rc;
554 list_for_each(tmp, &ibmphp_slot_head) {
555 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
557 if (!slot_cur)
558 return -ENODEV;
560 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
561 slot_cur->number);
562 if (slot_cur->ctrl->revision == 0xFF)
563 if (get_ctrl_revision(slot_cur,
564 &slot_cur->ctrl->revision))
565 return -1;
567 if (slot_cur->bus_on->current_speed == 0xFF)
568 if (get_cur_bus_info(&slot_cur))
569 return -1;
571 if (slot_cur->ctrl->options == 0xFF)
572 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
573 return -1;
575 retval = slot_update(&slot_cur);
576 if (retval)
577 return retval;
579 debug("status = %x\n", slot_cur->status);
580 debug("ext_status = %x\n", slot_cur->ext_status);
581 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
582 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
583 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
585 if ((SLOT_PWRGD(slot_cur->status)) &&
586 !(SLOT_PRESENT(slot_cur->status)) &&
587 !(SLOT_LATCH(slot_cur->status))) {
588 debug("BEFORE POWER OFF COMMAND\n");
589 rc = power_off(slot_cur);
590 if (rc)
591 return rc;
593 /* retval = slot_update(&slot_cur);
594 * if (retval)
595 * return retval;
596 * ibmphp_update_slot_info(slot_cur);
600 init_flag = 0;
601 return 0;
604 /* This operation will check whether the slot is within the bounds and
605 * the operation is valid to perform on that slot
606 * Parameters: slot, operation
607 * Returns: 0 or error codes
609 static int validate(struct slot *slot_cur, int opn)
611 int number;
612 int retval;
614 if (!slot_cur)
615 return -ENODEV;
616 number = slot_cur->number;
617 if ((number > max_slots) || (number < 0))
618 return -EBADSLT;
619 debug("slot_number in validate is %d\n", slot_cur->number);
621 retval = slot_update(&slot_cur);
622 if (retval)
623 return retval;
625 switch (opn) {
626 case ENABLE:
627 if (!(SLOT_PWRGD(slot_cur->status)) &&
628 (SLOT_PRESENT(slot_cur->status)) &&
629 !(SLOT_LATCH(slot_cur->status)))
630 return 0;
631 break;
632 case DISABLE:
633 if ((SLOT_PWRGD(slot_cur->status)) &&
634 (SLOT_PRESENT(slot_cur->status)) &&
635 !(SLOT_LATCH(slot_cur->status)))
636 return 0;
637 break;
638 default:
639 break;
641 err("validate failed....\n");
642 return -EINVAL;
645 /****************************************************************************
646 * This routine is for updating the data structures in the hotplug core
647 * Parameters: struct slot
648 * Returns: 0 or error
649 ****************************************************************************/
650 int ibmphp_update_slot_info(struct slot *slot_cur)
652 struct hotplug_slot_info *info;
653 int rc;
654 u8 bus_speed;
655 u8 mode;
657 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
658 if (!info) {
659 err("out of system memory\n");
660 return -ENOMEM;
663 info->power_status = SLOT_PWRGD(slot_cur->status);
664 info->attention_status = SLOT_ATTN(slot_cur->status,
665 slot_cur->ext_status);
666 info->latch_status = SLOT_LATCH(slot_cur->status);
667 if (!SLOT_PRESENT(slot_cur->status)) {
668 info->adapter_status = 0;
669 /* info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
670 } else {
671 info->adapter_status = 1;
672 /* get_max_adapter_speed_1(slot_cur->hotplug_slot,
673 &info->max_adapter_speed_status, 0); */
676 bus_speed = slot_cur->bus_on->current_speed;
677 mode = slot_cur->bus_on->current_bus_mode;
679 switch (bus_speed) {
680 case BUS_SPEED_33:
681 break;
682 case BUS_SPEED_66:
683 if (mode == BUS_MODE_PCIX)
684 bus_speed += 0x01;
685 else if (mode == BUS_MODE_PCI)
687 else
688 bus_speed = PCI_SPEED_UNKNOWN;
689 break;
690 case BUS_SPEED_100:
691 case BUS_SPEED_133:
692 bus_speed += 0x01;
693 break;
694 default:
695 bus_speed = PCI_SPEED_UNKNOWN;
698 info->cur_bus_speed = bus_speed;
699 info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
700 // To do: bus_names
702 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
703 kfree(info);
704 return rc;
708 /******************************************************************************
709 * This function will return the pci_func, given bus and devfunc, or NULL. It
710 * is called from visit routines
711 ******************************************************************************/
713 static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
715 struct pci_func *func_cur;
716 struct slot *slot_cur;
717 struct list_head * tmp;
718 list_for_each(tmp, &ibmphp_slot_head) {
719 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
720 if (slot_cur->func) {
721 func_cur = slot_cur->func;
722 while (func_cur) {
723 if ((func_cur->busno == busno) &&
724 (func_cur->device == device) &&
725 (func_cur->function == function))
726 return func_cur;
727 func_cur = func_cur->next;
731 return NULL;
734 /*************************************************************
735 * This routine frees up memory used by struct slot, including
736 * the pointers to pci_func, bus, hotplug_slot, controller,
737 * and deregistering from the hotplug core
738 *************************************************************/
739 static void free_slots(void)
741 struct slot *slot_cur;
742 struct list_head * tmp;
743 struct list_head * next;
745 debug("%s -- enter\n", __FUNCTION__);
747 list_for_each_safe(tmp, next, &ibmphp_slot_head) {
748 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
749 pci_hp_deregister(slot_cur->hotplug_slot);
751 debug("%s -- exit\n", __FUNCTION__);
754 static void ibm_unconfigure_device(struct pci_func *func)
756 struct pci_dev *temp;
757 u8 j;
759 debug("inside %s\n", __FUNCTION__);
760 debug("func->device = %x, func->function = %x\n",
761 func->device, func->function);
762 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
764 for (j = 0; j < 0x08; j++) {
765 temp = pci_find_slot(func->busno, (func->device << 3) | j);
766 if (temp)
767 pci_remove_bus_device(temp);
772 * The following function is to fix kernel bug regarding
773 * getting bus entries, here we manually add those primary
774 * bus entries to kernel bus structure whenever apply
776 static u8 bus_structure_fixup(u8 busno)
778 struct pci_bus *bus;
779 struct pci_dev *dev;
780 u16 l;
782 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
783 return 1;
785 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
786 if (!bus) {
787 err("%s - out of memory\n", __FUNCTION__);
788 return 1;
790 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
791 if (!dev) {
792 kfree(bus);
793 err("%s - out of memory\n", __FUNCTION__);
794 return 1;
797 bus->number = busno;
798 bus->ops = ibmphp_pci_bus->ops;
799 dev->bus = bus;
800 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
801 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
802 (l != 0x0000) && (l != 0xffff)) {
803 debug("%s - Inside bus_struture_fixup()\n",
804 __FUNCTION__);
805 pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
806 break;
810 kfree(dev);
811 kfree(bus);
813 return 0;
816 static int ibm_configure_device(struct pci_func *func)
818 unsigned char bus;
819 struct pci_bus *child;
820 int num;
821 int flag = 0; /* this is to make sure we don't double scan the bus,
822 for bridged devices primarily */
824 if (!(bus_structure_fixup(func->busno)))
825 flag = 1;
826 if (func->dev == NULL)
827 func->dev = pci_find_slot(func->busno,
828 PCI_DEVFN(func->device, func->function));
830 if (func->dev == NULL) {
831 struct pci_bus *bus = pci_find_bus(0, func->busno);
832 if (!bus)
833 return 0;
835 num = pci_scan_slot(bus,
836 PCI_DEVFN(func->device, func->function));
837 if (num)
838 pci_bus_add_devices(bus);
840 func->dev = pci_find_slot(func->busno,
841 PCI_DEVFN(func->device, func->function));
842 if (func->dev == NULL) {
843 err("ERROR... : pci_dev still NULL\n");
844 return 0;
847 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
848 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
849 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
850 pci_do_scan_bus(child);
853 return 0;
856 /*******************************************************
857 * Returns whether the bus is empty or not
858 *******************************************************/
859 static int is_bus_empty(struct slot * slot_cur)
861 int rc;
862 struct slot * tmp_slot;
863 u8 i = slot_cur->bus_on->slot_min;
865 while (i <= slot_cur->bus_on->slot_max) {
866 if (i == slot_cur->number) {
867 i++;
868 continue;
870 tmp_slot = ibmphp_get_slot_from_physical_num(i);
871 if (!tmp_slot)
872 return 0;
873 rc = slot_update(&tmp_slot);
874 if (rc)
875 return 0;
876 if (SLOT_PRESENT(tmp_slot->status) &&
877 SLOT_PWRGD(tmp_slot->status))
878 return 0;
879 i++;
881 return 1;
884 /***********************************************************
885 * If the HPC permits and the bus currently empty, tries to set the
886 * bus speed and mode at the maximum card and bus capability
887 * Parameters: slot
888 * Returns: bus is set (0) or error code
889 ***********************************************************/
890 static int set_bus(struct slot * slot_cur)
892 int rc;
893 u8 speed;
894 u8 cmd = 0x0;
895 int retval;
896 static struct pci_device_id ciobx[] = {
897 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
898 { },
901 debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
902 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
903 rc = slot_update(&slot_cur);
904 if (rc)
905 return rc;
906 speed = SLOT_SPEED(slot_cur->ext_status);
907 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
908 switch (speed) {
909 case HPC_SLOT_SPEED_33:
910 cmd = HPC_BUS_33CONVMODE;
911 break;
912 case HPC_SLOT_SPEED_66:
913 if (SLOT_PCIX(slot_cur->ext_status)) {
914 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
915 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
916 cmd = HPC_BUS_66PCIXMODE;
917 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
918 /* if max slot/bus capability is 66 pci
919 and there's no bus mode mismatch, then
920 the adapter supports 66 pci */
921 cmd = HPC_BUS_66CONVMODE;
922 else
923 cmd = HPC_BUS_33CONVMODE;
924 } else {
925 if (slot_cur->supported_speed >= BUS_SPEED_66)
926 cmd = HPC_BUS_66CONVMODE;
927 else
928 cmd = HPC_BUS_33CONVMODE;
930 break;
931 case HPC_SLOT_SPEED_133:
932 switch (slot_cur->supported_speed) {
933 case BUS_SPEED_33:
934 cmd = HPC_BUS_33CONVMODE;
935 break;
936 case BUS_SPEED_66:
937 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
938 cmd = HPC_BUS_66PCIXMODE;
939 else
940 cmd = HPC_BUS_66CONVMODE;
941 break;
942 case BUS_SPEED_100:
943 cmd = HPC_BUS_100PCIXMODE;
944 break;
945 case BUS_SPEED_133:
946 /* This is to take care of the bug in CIOBX chip */
947 if (pci_dev_present(ciobx))
948 ibmphp_hpc_writeslot(slot_cur,
949 HPC_BUS_100PCIXMODE);
950 cmd = HPC_BUS_133PCIXMODE;
951 break;
952 default:
953 err("Wrong bus speed\n");
954 return -ENODEV;
956 break;
957 default:
958 err("wrong slot speed\n");
959 return -ENODEV;
961 debug("setting bus speed for slot %d, cmd %x\n",
962 slot_cur->number, cmd);
963 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
964 if (retval) {
965 err("setting bus speed failed\n");
966 return retval;
968 if (CTLR_RESULT(slot_cur->ctrl->status)) {
969 err("command not completed successfully in set_bus\n");
970 return -EIO;
973 /* This is for x440, once Brandon fixes the firmware,
974 will not need this delay */
975 msleep(1000);
976 debug("%s -Exit\n", __FUNCTION__);
977 return 0;
980 /* This routine checks the bus limitations that the slot is on from the BIOS.
981 * This is used in deciding whether or not to power up the slot.
982 * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
983 * same bus)
984 * Parameters: slot
985 * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
987 static int check_limitations(struct slot *slot_cur)
989 u8 i;
990 struct slot * tmp_slot;
991 u8 count = 0;
992 u8 limitation = 0;
994 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
995 tmp_slot = ibmphp_get_slot_from_physical_num(i);
996 if (!tmp_slot)
997 return -ENODEV;
998 if ((SLOT_PWRGD(tmp_slot->status)) &&
999 !(SLOT_CONNECT(tmp_slot->status)))
1000 count++;
1002 get_cur_bus_info(&slot_cur);
1003 switch (slot_cur->bus_on->current_speed) {
1004 case BUS_SPEED_33:
1005 limitation = slot_cur->bus_on->slots_at_33_conv;
1006 break;
1007 case BUS_SPEED_66:
1008 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1009 limitation = slot_cur->bus_on->slots_at_66_pcix;
1010 else
1011 limitation = slot_cur->bus_on->slots_at_66_conv;
1012 break;
1013 case BUS_SPEED_100:
1014 limitation = slot_cur->bus_on->slots_at_100_pcix;
1015 break;
1016 case BUS_SPEED_133:
1017 limitation = slot_cur->bus_on->slots_at_133_pcix;
1018 break;
1021 if ((count + 1) > limitation)
1022 return -EINVAL;
1023 return 0;
1026 static inline void print_card_capability(struct slot *slot_cur)
1028 info("capability of the card is ");
1029 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1030 info(" 133 MHz PCI-X\n");
1031 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1032 info(" 66 MHz PCI-X\n");
1033 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1034 info(" 66 MHz PCI\n");
1035 else
1036 info(" 33 MHz PCI\n");
1040 /* This routine will power on the slot, configure the device(s) and find the
1041 * drivers for them.
1042 * Parameters: hotplug_slot
1043 * Returns: 0 or failure codes
1045 static int enable_slot(struct hotplug_slot *hs)
1047 int rc, i, rcpr;
1048 struct slot *slot_cur;
1049 u8 function;
1050 struct pci_func *tmp_func;
1052 ibmphp_lock_operations();
1054 debug("ENABLING SLOT........\n");
1055 slot_cur = hs->private;
1057 if ((rc = validate(slot_cur, ENABLE))) {
1058 err("validate function failed\n");
1059 goto error_nopower;
1062 attn_LED_blink(slot_cur);
1064 rc = set_bus(slot_cur);
1065 if (rc) {
1066 err("was not able to set the bus\n");
1067 goto error_nopower;
1070 /*-----------------debugging------------------------------*/
1071 get_cur_bus_info(&slot_cur);
1072 debug("the current bus speed right after set_bus = %x\n",
1073 slot_cur->bus_on->current_speed);
1074 /*----------------------------------------------------------*/
1076 rc = check_limitations(slot_cur);
1077 if (rc) {
1078 err("Adding this card exceeds the limitations of this bus.\n");
1079 err("(i.e., >1 133MHz cards running on same bus, or "
1080 ">2 66 PCI cards running on same bus.\n");
1081 err("Try hot-adding into another bus\n");
1082 rc = -EINVAL;
1083 goto error_nopower;
1086 rc = power_on(slot_cur);
1088 if (rc) {
1089 err("something wrong when powering up... please see below for details\n");
1090 /* need to turn off before on, otherwise, blinking overwrites */
1091 attn_off(slot_cur);
1092 attn_on(slot_cur);
1093 if (slot_update(&slot_cur)) {
1094 attn_off(slot_cur);
1095 attn_on(slot_cur);
1096 rc = -ENODEV;
1097 goto exit;
1099 /* Check to see the error of why it failed */
1100 if ((SLOT_POWER(slot_cur->status)) &&
1101 !(SLOT_PWRGD(slot_cur->status)))
1102 err("power fault occurred trying to power up\n");
1103 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1104 err("bus speed mismatch occurred. please check "
1105 "current bus speed and card capability\n");
1106 print_card_capability(slot_cur);
1107 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1108 err("bus mode mismatch occurred. please check "
1109 "current bus mode and card capability\n");
1110 print_card_capability(slot_cur);
1112 ibmphp_update_slot_info(slot_cur);
1113 goto exit;
1115 debug("after power_on\n");
1116 /*-----------------------debugging---------------------------*/
1117 get_cur_bus_info(&slot_cur);
1118 debug("the current bus speed right after power_on = %x\n",
1119 slot_cur->bus_on->current_speed);
1120 /*----------------------------------------------------------*/
1122 rc = slot_update(&slot_cur);
1123 if (rc)
1124 goto error_power;
1126 rc = -EINVAL;
1127 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1128 err("power fault occurred trying to power up...\n");
1129 goto error_power;
1131 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1132 err("bus speed mismatch occurred. please check current bus "
1133 "speed and card capability\n");
1134 print_card_capability(slot_cur);
1135 goto error_power;
1137 /* Don't think this case will happen after above checks...
1138 * but just in case, for paranoia sake */
1139 if (!(SLOT_POWER(slot_cur->status))) {
1140 err("power on failed...\n");
1141 goto error_power;
1144 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1145 if (!slot_cur->func) {
1146 /* We cannot do update_slot_info here, since no memory for
1147 * kmalloc n.e.ways, and update_slot_info allocates some */
1148 err("out of system memory\n");
1149 rc = -ENOMEM;
1150 goto error_power;
1152 memset(slot_cur->func, 0, sizeof(struct pci_func));
1153 slot_cur->func->busno = slot_cur->bus;
1154 slot_cur->func->device = slot_cur->device;
1155 for (i = 0; i < 4; i++)
1156 slot_cur->func->irq[i] = slot_cur->irq[i];
1158 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1159 slot_cur->bus, slot_cur->device);
1161 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1162 err("configure_card was unsuccessful...\n");
1163 /* true because don't need to actually deallocate resources,
1164 * just remove references */
1165 ibmphp_unconfigure_card(&slot_cur, 1);
1166 debug("after unconfigure_card\n");
1167 slot_cur->func = NULL;
1168 rc = -ENOMEM;
1169 goto error_power;
1172 function = 0x00;
1173 do {
1174 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1175 function++);
1176 if (tmp_func && !(tmp_func->dev))
1177 ibm_configure_device(tmp_func);
1178 } while (tmp_func);
1180 attn_off(slot_cur);
1181 if (slot_update(&slot_cur)) {
1182 rc = -EFAULT;
1183 goto exit;
1185 ibmphp_print_test();
1186 rc = ibmphp_update_slot_info(slot_cur);
1187 exit:
1188 ibmphp_unlock_operations();
1189 return rc;
1191 error_nopower:
1192 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1193 attn_on(slot_cur);
1194 error_cont:
1195 rcpr = slot_update(&slot_cur);
1196 if (rcpr) {
1197 rc = rcpr;
1198 goto exit;
1200 ibmphp_update_slot_info(slot_cur);
1201 goto exit;
1203 error_power:
1204 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1205 attn_on(slot_cur);
1206 rcpr = power_off(slot_cur);
1207 if (rcpr) {
1208 rc = rcpr;
1209 goto exit;
1211 goto error_cont;
1214 /**************************************************************
1215 * HOT REMOVING ADAPTER CARD *
1216 * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE *
1217 * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE *
1218 DISABLE POWER , *
1219 **************************************************************/
1220 static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1222 struct slot *slot = hotplug_slot->private;
1223 int rc;
1225 ibmphp_lock_operations();
1226 rc = ibmphp_do_disable_slot(slot);
1227 ibmphp_unlock_operations();
1228 return rc;
1231 int ibmphp_do_disable_slot(struct slot *slot_cur)
1233 int rc;
1234 u8 flag;
1236 debug("DISABLING SLOT...\n");
1238 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1239 return -ENODEV;
1242 flag = slot_cur->flag;
1243 slot_cur->flag = TRUE;
1245 if (flag == TRUE) {
1246 rc = validate(slot_cur, DISABLE);
1247 /* checking if powered off already & valid slot # */
1248 if (rc)
1249 goto error;
1251 attn_LED_blink(slot_cur);
1253 if (slot_cur->func == NULL) {
1254 /* We need this for fncs's that were there on bootup */
1255 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1256 if (!slot_cur->func) {
1257 err("out of system memory\n");
1258 rc = -ENOMEM;
1259 goto error;
1261 memset(slot_cur->func, 0, sizeof(struct pci_func));
1262 slot_cur->func->busno = slot_cur->bus;
1263 slot_cur->func->device = slot_cur->device;
1266 ibm_unconfigure_device(slot_cur->func);
1268 /* If we got here from latch suddenly opening on operating card or
1269 a power fault, there's no power to the card, so cannot
1270 read from it to determine what resources it occupied. This operation
1271 is forbidden anyhow. The best we can do is remove it from kernel
1272 lists at least */
1274 if (!flag) {
1275 attn_off(slot_cur);
1276 return 0;
1279 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1280 slot_cur->func = NULL;
1281 debug("in disable_slot. after unconfigure_card\n");
1282 if (rc) {
1283 err("could not unconfigure card.\n");
1284 goto error;
1287 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1288 if (rc)
1289 goto error;
1291 attn_off(slot_cur);
1292 rc = slot_update(&slot_cur);
1293 if (rc)
1294 goto exit;
1296 rc = ibmphp_update_slot_info(slot_cur);
1297 ibmphp_print_test();
1298 exit:
1299 return rc;
1301 error:
1302 /* Need to turn off if was blinking b4 */
1303 attn_off(slot_cur);
1304 attn_on(slot_cur);
1305 if (slot_update(&slot_cur)) {
1306 rc = -EFAULT;
1307 goto exit;
1309 if (flag)
1310 ibmphp_update_slot_info(slot_cur);
1311 goto exit;
1314 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1315 .owner = THIS_MODULE,
1316 .set_attention_status = set_attention_status,
1317 .enable_slot = enable_slot,
1318 .disable_slot = ibmphp_disable_slot,
1319 .hardware_test = NULL,
1320 .get_power_status = get_power_status,
1321 .get_attention_status = get_attention_status,
1322 .get_latch_status = get_latch_status,
1323 .get_adapter_status = get_adapter_present,
1324 .get_max_bus_speed = get_max_bus_speed,
1325 .get_cur_bus_speed = get_cur_bus_speed,
1326 /* .get_max_adapter_speed = get_max_adapter_speed,
1327 .get_bus_name_status = get_bus_name,
1331 static void ibmphp_unload(void)
1333 free_slots();
1334 debug("after slots\n");
1335 ibmphp_free_resources();
1336 debug("after resources\n");
1337 ibmphp_free_bus_info_queue();
1338 debug("after bus info\n");
1339 ibmphp_free_ebda_hpc_queue();
1340 debug("after ebda hpc\n");
1341 ibmphp_free_ebda_pci_rsrc_queue();
1342 debug("after ebda pci rsrc\n");
1343 kfree(ibmphp_pci_bus);
1346 static int __init ibmphp_init(void)
1348 struct pci_bus *bus;
1349 int i = 0;
1350 int rc = 0;
1352 init_flag = 1;
1354 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1356 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1357 if (!ibmphp_pci_bus) {
1358 err("out of memory\n");
1359 rc = -ENOMEM;
1360 goto exit;
1363 bus = pci_find_bus(0, 0);
1364 if (!bus) {
1365 err("Can't find the root pci bus, can not continue\n");
1366 rc = -ENODEV;
1367 goto error;
1369 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1371 ibmphp_debug = debug;
1373 ibmphp_hpc_initvars();
1375 for (i = 0; i < 16; i++)
1376 irqs[i] = 0;
1378 if ((rc = ibmphp_access_ebda()))
1379 goto error;
1380 debug("after ibmphp_access_ebda()\n");
1382 if ((rc = ibmphp_rsrc_init()))
1383 goto error;
1384 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1386 max_slots = get_max_slots();
1388 if ((rc = ibmphp_register_pci()))
1389 goto error;
1391 if (init_ops()) {
1392 rc = -ENODEV;
1393 goto error;
1396 ibmphp_print_test();
1397 if ((rc = ibmphp_hpc_start_poll_thread())) {
1398 goto error;
1401 /* lock ourselves into memory with a module
1402 * count of -1 so that no one can unload us. */
1403 module_put(THIS_MODULE);
1405 exit:
1406 return rc;
1408 error:
1409 ibmphp_unload();
1410 goto exit;
1413 static void __exit ibmphp_exit(void)
1415 ibmphp_hpc_stop_poll_thread();
1416 debug("after polling\n");
1417 ibmphp_unload();
1418 debug("done\n");
1421 module_init(ibmphp_init);
1422 module_exit(ibmphp_exit);