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