PCI Hotplug: fakephp: add duplicate slot name debugging
[linux-2.6] / drivers / pci / hotplug / pciehp_ctrl.c
1 /*
2  * PCI Express 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  * Copyright (C) 2003-2004 Intel Corporation
8  *
9  * All rights reserved.
10  *
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.
15  *
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.
21  *
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.
25  *
26  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27  *
28  */
29
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/types.h>
33 #include <linux/smp_lock.h>
34 #include <linux/pci.h>
35 #include <linux/workqueue.h>
36 #include "../pci.h"
37 #include "pciehp.h"
38
39 static void interrupt_event_handler(struct work_struct *work);
40
41 static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
42 {
43         struct event_info *info;
44
45         info = kmalloc(sizeof(*info), GFP_ATOMIC);
46         if (!info)
47                 return -ENOMEM;
48
49         info->event_type = event_type;
50         info->p_slot = p_slot;
51         INIT_WORK(&info->work, interrupt_event_handler);
52
53         schedule_work(&info->work);
54
55         return 0;
56 }
57
58 u8 pciehp_handle_attention_button(struct slot *p_slot)
59 {
60         u32 event_type;
61         struct controller *ctrl = p_slot->ctrl;
62
63         /* Attention Button Change */
64         ctrl_dbg(ctrl, "Attention button interrupt received.\n");
65
66         /*
67          *  Button pressed - See if need to TAKE ACTION!!!
68          */
69         ctrl_info(ctrl, "Button pressed on Slot(%s)\n", slot_name(p_slot));
70         event_type = INT_BUTTON_PRESS;
71
72         queue_interrupt_event(p_slot, event_type);
73
74         return 0;
75 }
76
77 u8 pciehp_handle_switch_change(struct slot *p_slot)
78 {
79         u8 getstatus;
80         u32 event_type;
81         struct controller *ctrl = p_slot->ctrl;
82
83         /* Switch Change */
84         ctrl_dbg(ctrl, "Switch interrupt received.\n");
85
86         p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
87         if (getstatus) {
88                 /*
89                  * Switch opened
90                  */
91                 ctrl_info(ctrl, "Latch open on Slot(%s)\n", slot_name(p_slot));
92                 event_type = INT_SWITCH_OPEN;
93         } else {
94                 /*
95                  *  Switch closed
96                  */
97                 ctrl_info(ctrl, "Latch close on Slot(%s)\n", slot_name(p_slot));
98                 event_type = INT_SWITCH_CLOSE;
99         }
100
101         queue_interrupt_event(p_slot, event_type);
102
103         return 1;
104 }
105
106 u8 pciehp_handle_presence_change(struct slot *p_slot)
107 {
108         u32 event_type;
109         u8 presence_save;
110         struct controller *ctrl = p_slot->ctrl;
111
112         /* Presence Change */
113         ctrl_dbg(ctrl, "Presence/Notify input change.\n");
114
115         /* Switch is open, assume a presence change
116          * Save the presence state
117          */
118         p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
119         if (presence_save) {
120                 /*
121                  * Card Present
122                  */
123                 ctrl_info(ctrl, "Card present on Slot(%s)\n", slot_name(p_slot));
124                 event_type = INT_PRESENCE_ON;
125         } else {
126                 /*
127                  * Not Present
128                  */
129                 ctrl_info(ctrl, "Card not present on Slot(%s)\n",
130                           slot_name(p_slot));
131                 event_type = INT_PRESENCE_OFF;
132         }
133
134         queue_interrupt_event(p_slot, event_type);
135
136         return 1;
137 }
138
139 u8 pciehp_handle_power_fault(struct slot *p_slot)
140 {
141         u32 event_type;
142         struct controller *ctrl = p_slot->ctrl;
143
144         /* power fault */
145         ctrl_dbg(ctrl, "Power fault interrupt received.\n");
146
147         if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
148                 /*
149                  * power fault Cleared
150                  */
151                 ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
152                           slot_name(p_slot));
153                 event_type = INT_POWER_FAULT_CLEAR;
154         } else {
155                 /*
156                  *   power fault
157                  */
158                 ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot));
159                 event_type = INT_POWER_FAULT;
160                 ctrl_info(ctrl, "power fault bit %x set\n", 0);
161         }
162
163         queue_interrupt_event(p_slot, event_type);
164
165         return 1;
166 }
167
168 /* The following routines constitute the bulk of the
169    hotplug controller logic
170  */
171
172 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
173 {
174         /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
175         if (POWER_CTRL(ctrl)) {
176                 if (pslot->hpc_ops->power_off_slot(pslot)) {
177                         ctrl_err(ctrl,
178                                  "%s: Issue of Slot Power Off command failed\n",
179                                  __func__);
180                         return;
181                 }
182         }
183
184         /*
185          * After turning power off, we must wait for at least 1 second
186          * before taking any action that relies on power having been
187          * removed from the slot/adapter.
188          */
189         msleep(1000);
190
191         if (PWR_LED(ctrl))
192                 pslot->hpc_ops->green_led_off(pslot);
193
194         if (ATTN_LED(ctrl)) {
195                 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
196                         ctrl_err(ctrl, "%s: Issue of Set Attention "
197                                  "Led command failed\n", __func__);
198                         return;
199                 }
200         }
201 }
202
203 /**
204  * board_added - Called after a board has been added to the system.
205  * @p_slot: &slot where board is added
206  *
207  * Turns power on for the board.
208  * Configures board.
209  */
210 static int board_added(struct slot *p_slot)
211 {
212         int retval = 0;
213         struct controller *ctrl = p_slot->ctrl;
214
215         ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
216                  __func__, p_slot->device, ctrl->slot_device_offset,
217                  p_slot->hp_slot);
218
219         if (POWER_CTRL(ctrl)) {
220                 /* Power on slot */
221                 retval = p_slot->hpc_ops->power_on_slot(p_slot);
222                 if (retval)
223                         return retval;
224         }
225
226         if (PWR_LED(ctrl))
227                 p_slot->hpc_ops->green_led_blink(p_slot);
228
229         /* Wait for ~1 second */
230         msleep(1000);
231
232         /* Check link training status */
233         retval = p_slot->hpc_ops->check_lnk_status(ctrl);
234         if (retval) {
235                 ctrl_err(ctrl, "%s: Failed to check link status\n", __func__);
236                 set_slot_off(ctrl, p_slot);
237                 return retval;
238         }
239
240         /* Check for a power fault */
241         if (p_slot->hpc_ops->query_power_fault(p_slot)) {
242                 ctrl_dbg(ctrl, "%s: power fault detected\n", __func__);
243                 retval = POWER_FAILURE;
244                 goto err_exit;
245         }
246
247         retval = pciehp_configure_device(p_slot);
248         if (retval) {
249                 ctrl_err(ctrl, "Cannot add device 0x%x:%x\n",
250                          p_slot->bus, p_slot->device);
251                 goto err_exit;
252         }
253
254         /*
255          * Some PCI Express root ports require fixup after hot-plug operation.
256          */
257         if (pcie_mch_quirk)
258                 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
259         if (PWR_LED(ctrl))
260                 p_slot->hpc_ops->green_led_on(p_slot);
261
262         return 0;
263
264 err_exit:
265         set_slot_off(ctrl, p_slot);
266         return retval;
267 }
268
269 /**
270  * remove_board - Turns off slot and LEDs
271  * @p_slot: slot where board is being removed
272  */
273 static int remove_board(struct slot *p_slot)
274 {
275         int retval = 0;
276         struct controller *ctrl = p_slot->ctrl;
277
278         retval = pciehp_unconfigure_device(p_slot);
279         if (retval)
280                 return retval;
281
282         ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
283
284         if (POWER_CTRL(ctrl)) {
285                 /* power off slot */
286                 retval = p_slot->hpc_ops->power_off_slot(p_slot);
287                 if (retval) {
288                         ctrl_err(ctrl, "%s: Issue of Slot Disable command "
289                                  "failed\n", __func__);
290                         return retval;
291                 }
292         }
293
294         /*
295          * After turning power off, we must wait for at least 1 second
296          * before taking any action that relies on power having been
297          * removed from the slot/adapter.
298          */
299         msleep(1000);
300
301         if (PWR_LED(ctrl))
302                 /* turn off Green LED */
303                 p_slot->hpc_ops->green_led_off(p_slot);
304
305         return 0;
306 }
307
308 struct power_work_info {
309         struct slot *p_slot;
310         struct work_struct work;
311 };
312
313 /**
314  * pciehp_power_thread - handle pushbutton events
315  * @work: &struct work_struct describing work to be done
316  *
317  * Scheduled procedure to handle blocking stuff for the pushbuttons.
318  * Handles all pending events and exits.
319  */
320 static void pciehp_power_thread(struct work_struct *work)
321 {
322         struct power_work_info *info =
323                 container_of(work, struct power_work_info, work);
324         struct slot *p_slot = info->p_slot;
325
326         mutex_lock(&p_slot->lock);
327         switch (p_slot->state) {
328         case POWEROFF_STATE:
329                 mutex_unlock(&p_slot->lock);
330                 ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n",
331                          __func__, p_slot->bus, p_slot->device);
332                 pciehp_disable_slot(p_slot);
333                 mutex_lock(&p_slot->lock);
334                 p_slot->state = STATIC_STATE;
335                 break;
336         case POWERON_STATE:
337                 mutex_unlock(&p_slot->lock);
338                 if (pciehp_enable_slot(p_slot) &&
339                     PWR_LED(p_slot->ctrl))
340                         p_slot->hpc_ops->green_led_off(p_slot);
341                 mutex_lock(&p_slot->lock);
342                 p_slot->state = STATIC_STATE;
343                 break;
344         default:
345                 break;
346         }
347         mutex_unlock(&p_slot->lock);
348
349         kfree(info);
350 }
351
352 void pciehp_queue_pushbutton_work(struct work_struct *work)
353 {
354         struct slot *p_slot = container_of(work, struct slot, work.work);
355         struct power_work_info *info;
356
357         info = kmalloc(sizeof(*info), GFP_KERNEL);
358         if (!info) {
359                 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
360                          __func__);
361                 return;
362         }
363         info->p_slot = p_slot;
364         INIT_WORK(&info->work, pciehp_power_thread);
365
366         mutex_lock(&p_slot->lock);
367         switch (p_slot->state) {
368         case BLINKINGOFF_STATE:
369                 p_slot->state = POWEROFF_STATE;
370                 break;
371         case BLINKINGON_STATE:
372                 p_slot->state = POWERON_STATE;
373                 break;
374         default:
375                 goto out;
376         }
377         queue_work(pciehp_wq, &info->work);
378  out:
379         mutex_unlock(&p_slot->lock);
380 }
381
382 static int update_slot_info(struct slot *slot)
383 {
384         struct hotplug_slot_info *info;
385         int result;
386
387         info = kmalloc(sizeof(*info), GFP_KERNEL);
388         if (!info)
389                 return -ENOMEM;
390
391         slot->hpc_ops->get_power_status(slot, &(info->power_status));
392         slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
393         slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
394         slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
395
396         result = pci_hp_change_slot_info(slot->hotplug_slot, info);
397         kfree (info);
398         return result;
399 }
400
401 /*
402  * Note: This function must be called with slot->lock held
403  */
404 static void handle_button_press_event(struct slot *p_slot)
405 {
406         struct controller *ctrl = p_slot->ctrl;
407         u8 getstatus;
408
409         switch (p_slot->state) {
410         case STATIC_STATE:
411                 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
412                 if (getstatus) {
413                         p_slot->state = BLINKINGOFF_STATE;
414                         ctrl_info(ctrl,
415                                   "PCI slot #%s - powering off due to button "
416                                   "press.\n", slot_name(p_slot));
417                 } else {
418                         p_slot->state = BLINKINGON_STATE;
419                         ctrl_info(ctrl,
420                                   "PCI slot #%s - powering on due to button "
421                                   "press.\n", slot_name(p_slot));
422                 }
423                 /* blink green LED and turn off amber */
424                 if (PWR_LED(ctrl))
425                         p_slot->hpc_ops->green_led_blink(p_slot);
426                 if (ATTN_LED(ctrl))
427                         p_slot->hpc_ops->set_attention_status(p_slot, 0);
428
429                 schedule_delayed_work(&p_slot->work, 5*HZ);
430                 break;
431         case BLINKINGOFF_STATE:
432         case BLINKINGON_STATE:
433                 /*
434                  * Cancel if we are still blinking; this means that we
435                  * press the attention again before the 5 sec. limit
436                  * expires to cancel hot-add or hot-remove
437                  */
438                 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));
439                 ctrl_dbg(ctrl, "%s: button cancel\n", __func__);
440                 cancel_delayed_work(&p_slot->work);
441                 if (p_slot->state == BLINKINGOFF_STATE) {
442                         if (PWR_LED(ctrl))
443                                 p_slot->hpc_ops->green_led_on(p_slot);
444                 } else {
445                         if (PWR_LED(ctrl))
446                                 p_slot->hpc_ops->green_led_off(p_slot);
447                 }
448                 if (ATTN_LED(ctrl))
449                         p_slot->hpc_ops->set_attention_status(p_slot, 0);
450                 ctrl_info(ctrl, "PCI slot #%s - action canceled "
451                           "due to button press\n", slot_name(p_slot));
452                 p_slot->state = STATIC_STATE;
453                 break;
454         case POWEROFF_STATE:
455         case POWERON_STATE:
456                 /*
457                  * Ignore if the slot is on power-on or power-off state;
458                  * this means that the previous attention button action
459                  * to hot-add or hot-remove is undergoing
460                  */
461                 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
462                 update_slot_info(p_slot);
463                 break;
464         default:
465                 ctrl_warn(ctrl, "Not a valid state\n");
466                 break;
467         }
468 }
469
470 /*
471  * Note: This function must be called with slot->lock held
472  */
473 static void handle_surprise_event(struct slot *p_slot)
474 {
475         u8 getstatus;
476         struct power_work_info *info;
477
478         info = kmalloc(sizeof(*info), GFP_KERNEL);
479         if (!info) {
480                 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
481                          __func__);
482                 return;
483         }
484         info->p_slot = p_slot;
485         INIT_WORK(&info->work, pciehp_power_thread);
486
487         p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
488         if (!getstatus)
489                 p_slot->state = POWEROFF_STATE;
490         else
491                 p_slot->state = POWERON_STATE;
492
493         queue_work(pciehp_wq, &info->work);
494 }
495
496 static void interrupt_event_handler(struct work_struct *work)
497 {
498         struct event_info *info = container_of(work, struct event_info, work);
499         struct slot *p_slot = info->p_slot;
500         struct controller *ctrl = p_slot->ctrl;
501
502         mutex_lock(&p_slot->lock);
503         switch (info->event_type) {
504         case INT_BUTTON_PRESS:
505                 handle_button_press_event(p_slot);
506                 break;
507         case INT_POWER_FAULT:
508                 if (!POWER_CTRL(ctrl))
509                         break;
510                 if (ATTN_LED(ctrl))
511                         p_slot->hpc_ops->set_attention_status(p_slot, 1);
512                 if (PWR_LED(ctrl))
513                         p_slot->hpc_ops->green_led_off(p_slot);
514                 break;
515         case INT_PRESENCE_ON:
516         case INT_PRESENCE_OFF:
517                 if (!HP_SUPR_RM(ctrl))
518                         break;
519                 ctrl_dbg(ctrl, "Surprise Removal\n");
520                 update_slot_info(p_slot);
521                 handle_surprise_event(p_slot);
522                 break;
523         default:
524                 update_slot_info(p_slot);
525                 break;
526         }
527         mutex_unlock(&p_slot->lock);
528
529         kfree(info);
530 }
531
532 int pciehp_enable_slot(struct slot *p_slot)
533 {
534         u8 getstatus = 0;
535         int rc;
536         struct controller *ctrl = p_slot->ctrl;
537
538         /* Check to see if (latch closed, card present, power off) */
539         mutex_lock(&p_slot->ctrl->crit_sect);
540
541         rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
542         if (rc || !getstatus) {
543                 ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
544                           __func__, slot_name(p_slot));
545                 mutex_unlock(&p_slot->ctrl->crit_sect);
546                 return -ENODEV;
547         }
548         if (MRL_SENS(p_slot->ctrl)) {
549                 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
550                 if (rc || getstatus) {
551                         ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
552                                   __func__, slot_name(p_slot));
553                         mutex_unlock(&p_slot->ctrl->crit_sect);
554                         return -ENODEV;
555                 }
556         }
557
558         if (POWER_CTRL(p_slot->ctrl)) {
559                 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
560                 if (rc || getstatus) {
561                         ctrl_info(ctrl, "%s: already enabled on slot(%s)\n",
562                                   __func__, slot_name(p_slot));
563                         mutex_unlock(&p_slot->ctrl->crit_sect);
564                         return -EINVAL;
565                 }
566         }
567
568         p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
569
570         rc = board_added(p_slot);
571         if (rc) {
572                 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
573         }
574
575         update_slot_info(p_slot);
576
577         mutex_unlock(&p_slot->ctrl->crit_sect);
578         return rc;
579 }
580
581
582 int pciehp_disable_slot(struct slot *p_slot)
583 {
584         u8 getstatus = 0;
585         int ret = 0;
586         struct controller *ctrl = p_slot->ctrl;
587
588         if (!p_slot->ctrl)
589                 return 1;
590
591         /* Check to see if (latch closed, card present, power on) */
592         mutex_lock(&p_slot->ctrl->crit_sect);
593
594         if (!HP_SUPR_RM(p_slot->ctrl)) {
595                 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
596                 if (ret || !getstatus) {
597                         ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
598                                   __func__, slot_name(p_slot));
599                         mutex_unlock(&p_slot->ctrl->crit_sect);
600                         return -ENODEV;
601                 }
602         }
603
604         if (MRL_SENS(p_slot->ctrl)) {
605                 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
606                 if (ret || getstatus) {
607                         ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
608                                   __func__, slot_name(p_slot));
609                         mutex_unlock(&p_slot->ctrl->crit_sect);
610                         return -ENODEV;
611                 }
612         }
613
614         if (POWER_CTRL(p_slot->ctrl)) {
615                 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
616                 if (ret || !getstatus) {
617                         ctrl_info(ctrl, "%s: already disabled slot(%s)\n",
618                                   __func__, slot_name(p_slot));
619                         mutex_unlock(&p_slot->ctrl->crit_sect);
620                         return -EINVAL;
621                 }
622         }
623
624         ret = remove_board(p_slot);
625         update_slot_info(p_slot);
626
627         mutex_unlock(&p_slot->ctrl->crit_sect);
628         return ret;
629 }
630
631 int pciehp_sysfs_enable_slot(struct slot *p_slot)
632 {
633         int retval = -ENODEV;
634         struct controller *ctrl = p_slot->ctrl;
635
636         mutex_lock(&p_slot->lock);
637         switch (p_slot->state) {
638         case BLINKINGON_STATE:
639                 cancel_delayed_work(&p_slot->work);
640         case STATIC_STATE:
641                 p_slot->state = POWERON_STATE;
642                 mutex_unlock(&p_slot->lock);
643                 retval = pciehp_enable_slot(p_slot);
644                 mutex_lock(&p_slot->lock);
645                 p_slot->state = STATIC_STATE;
646                 break;
647         case POWERON_STATE:
648                 ctrl_info(ctrl, "Slot %s is already in powering on state\n",
649                           slot_name(p_slot));
650                 break;
651         case BLINKINGOFF_STATE:
652         case POWEROFF_STATE:
653                 ctrl_info(ctrl, "Already enabled on slot %s\n",
654                           slot_name(p_slot));
655                 break;
656         default:
657                 ctrl_err(ctrl, "Not a valid state on slot %s\n",
658                          slot_name(p_slot));
659                 break;
660         }
661         mutex_unlock(&p_slot->lock);
662
663         return retval;
664 }
665
666 int pciehp_sysfs_disable_slot(struct slot *p_slot)
667 {
668         int retval = -ENODEV;
669         struct controller *ctrl = p_slot->ctrl;
670
671         mutex_lock(&p_slot->lock);
672         switch (p_slot->state) {
673         case BLINKINGOFF_STATE:
674                 cancel_delayed_work(&p_slot->work);
675         case STATIC_STATE:
676                 p_slot->state = POWEROFF_STATE;
677                 mutex_unlock(&p_slot->lock);
678                 retval = pciehp_disable_slot(p_slot);
679                 mutex_lock(&p_slot->lock);
680                 p_slot->state = STATIC_STATE;
681                 break;
682         case POWEROFF_STATE:
683                 ctrl_info(ctrl, "Slot %s is already in powering off state\n",
684                           slot_name(p_slot));
685                 break;
686         case BLINKINGON_STATE:
687         case POWERON_STATE:
688                 ctrl_info(ctrl, "Already disabled on slot %s\n",
689                           slot_name(p_slot));
690                 break;
691         default:
692                 ctrl_err(ctrl, "Not a valid state on slot %s\n",
693                          slot_name(p_slot));
694                 break;
695         }
696         mutex_unlock(&p_slot->lock);
697
698         return retval;
699 }