Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/jk/spufs into...
[linux-2.6] / drivers / pci / hotplug / cpci_hotplug_core.c
1 /*
2  * CompactPCI Hot Plug Driver
3  *
4  * Copyright (C) 2002,2005 SOMA Networks, Inc.
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 <scottm@somanetworks.com>
26  */
27
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/slab.h>
31 #include <linux/pci.h>
32 #include <linux/pci_hotplug.h>
33 #include <linux/init.h>
34 #include <linux/interrupt.h>
35 #include <linux/smp_lock.h>
36 #include <asm/atomic.h>
37 #include <linux/delay.h>
38 #include <linux/kthread.h>
39 #include "cpci_hotplug.h"
40
41 #define DRIVER_AUTHOR   "Scott Murray <scottm@somanetworks.com>"
42 #define DRIVER_DESC     "CompactPCI Hot Plug Core"
43
44 #define MY_NAME "cpci_hotplug"
45
46 #define dbg(format, arg...)                                     \
47         do {                                                    \
48                 if (cpci_debug)                                 \
49                         printk (KERN_DEBUG "%s: " format "\n",  \
50                                 MY_NAME , ## arg);              \
51         } while (0)
52 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
53 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
54 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
55
56 /* local variables */
57 static DECLARE_RWSEM(list_rwsem);
58 static LIST_HEAD(slot_list);
59 static int slots;
60 static atomic_t extracting;
61 int cpci_debug;
62 static struct cpci_hp_controller *controller;
63 static struct task_struct *cpci_thread;
64 static int thread_finished;
65
66 static int enable_slot(struct hotplug_slot *slot);
67 static int disable_slot(struct hotplug_slot *slot);
68 static int set_attention_status(struct hotplug_slot *slot, u8 value);
69 static int get_power_status(struct hotplug_slot *slot, u8 * value);
70 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
71 static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
72 static int get_latch_status(struct hotplug_slot *slot, u8 * value);
73
74 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
75         .owner = THIS_MODULE,
76         .enable_slot = enable_slot,
77         .disable_slot = disable_slot,
78         .set_attention_status = set_attention_status,
79         .get_power_status = get_power_status,
80         .get_attention_status = get_attention_status,
81         .get_adapter_status = get_adapter_status,
82         .get_latch_status = get_latch_status,
83 };
84
85 static int
86 update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
87 {
88         struct hotplug_slot_info info;
89
90         memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
91         info.latch_status = value;
92         return pci_hp_change_slot_info(hotplug_slot, &info);
93 }
94
95 static int
96 update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
97 {
98         struct hotplug_slot_info info;
99
100         memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
101         info.adapter_status = value;
102         return pci_hp_change_slot_info(hotplug_slot, &info);
103 }
104
105 static int
106 enable_slot(struct hotplug_slot *hotplug_slot)
107 {
108         struct slot *slot = hotplug_slot->private;
109         int retval = 0;
110
111         dbg("%s - physical_slot = %s", __func__, slot_name(slot));
112
113         if (controller->ops->set_power)
114                 retval = controller->ops->set_power(slot, 1);
115         return retval;
116 }
117
118 static int
119 disable_slot(struct hotplug_slot *hotplug_slot)
120 {
121         struct slot *slot = hotplug_slot->private;
122         int retval = 0;
123
124         dbg("%s - physical_slot = %s", __func__, slot_name(slot));
125
126         down_write(&list_rwsem);
127
128         /* Unconfigure device */
129         dbg("%s - unconfiguring slot %s", __func__, slot_name(slot));
130         if ((retval = cpci_unconfigure_slot(slot))) {
131                 err("%s - could not unconfigure slot %s",
132                     __func__, slot_name(slot));
133                 goto disable_error;
134         }
135         dbg("%s - finished unconfiguring slot %s", __func__, slot_name(slot));
136
137         /* Clear EXT (by setting it) */
138         if (cpci_clear_ext(slot)) {
139                 err("%s - could not clear EXT for slot %s",
140                     __func__, slot_name(slot));
141                 retval = -ENODEV;
142                 goto disable_error;
143         }
144         cpci_led_on(slot);
145
146         if (controller->ops->set_power)
147                 if ((retval = controller->ops->set_power(slot, 0)))
148                         goto disable_error;
149
150         if (update_adapter_status(slot->hotplug_slot, 0))
151                 warn("failure to update adapter file");
152
153         if (slot->extracting) {
154                 slot->extracting = 0;
155                 atomic_dec(&extracting);
156         }
157 disable_error:
158         up_write(&list_rwsem);
159         return retval;
160 }
161
162 static u8
163 cpci_get_power_status(struct slot *slot)
164 {
165         u8 power = 1;
166
167         if (controller->ops->get_power)
168                 power = controller->ops->get_power(slot);
169         return power;
170 }
171
172 static int
173 get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
174 {
175         struct slot *slot = hotplug_slot->private;
176
177         *value = cpci_get_power_status(slot);
178         return 0;
179 }
180
181 static int
182 get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
183 {
184         struct slot *slot = hotplug_slot->private;
185
186         *value = cpci_get_attention_status(slot);
187         return 0;
188 }
189
190 static int
191 set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
192 {
193         return cpci_set_attention_status(hotplug_slot->private, status);
194 }
195
196 static int
197 get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
198 {
199         *value = hotplug_slot->info->adapter_status;
200         return 0;
201 }
202
203 static int
204 get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
205 {
206         *value = hotplug_slot->info->latch_status;
207         return 0;
208 }
209
210 static void release_slot(struct hotplug_slot *hotplug_slot)
211 {
212         struct slot *slot = hotplug_slot->private;
213
214         kfree(slot->hotplug_slot->info);
215         kfree(slot->hotplug_slot);
216         if (slot->dev)
217                 pci_dev_put(slot->dev);
218         kfree(slot);
219 }
220
221 #define SLOT_NAME_SIZE  6
222
223 int
224 cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
225 {
226         struct slot *slot;
227         struct hotplug_slot *hotplug_slot;
228         struct hotplug_slot_info *info;
229         char name[SLOT_NAME_SIZE];
230         int status = -ENOMEM;
231         int i;
232
233         if (!(controller && bus))
234                 return -ENODEV;
235
236         /*
237          * Create a structure for each slot, and register that slot
238          * with the pci_hotplug subsystem.
239          */
240         for (i = first; i <= last; ++i) {
241                 slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
242                 if (!slot)
243                         goto error;
244
245                 hotplug_slot =
246                         kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
247                 if (!hotplug_slot)
248                         goto error_slot;
249                 slot->hotplug_slot = hotplug_slot;
250
251                 info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
252                 if (!info)
253                         goto error_hpslot;
254                 hotplug_slot->info = info;
255
256                 slot->bus = bus;
257                 slot->number = i;
258                 slot->devfn = PCI_DEVFN(i, 0);
259
260                 snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i);
261
262                 hotplug_slot->private = slot;
263                 hotplug_slot->release = &release_slot;
264                 hotplug_slot->ops = &cpci_hotplug_slot_ops;
265
266                 /*
267                  * Initialize the slot info structure with some known
268                  * good values.
269                  */
270                 dbg("initializing slot %s", name);
271                 info->power_status = cpci_get_power_status(slot);
272                 info->attention_status = cpci_get_attention_status(slot);
273
274                 dbg("registering slot %s", name);
275                 status = pci_hp_register(slot->hotplug_slot, bus, i, name);
276                 if (status) {
277                         err("pci_hp_register failed with error %d", status);
278                         goto error_info;
279                 }
280                 dbg("slot registered with name: %s", slot_name(slot));
281
282                 /* Add slot to our internal list */
283                 down_write(&list_rwsem);
284                 list_add(&slot->slot_list, &slot_list);
285                 slots++;
286                 up_write(&list_rwsem);
287         }
288         return 0;
289 error_info:
290         kfree(info);
291 error_hpslot:
292         kfree(hotplug_slot);
293 error_slot:
294         kfree(slot);
295 error:
296         return status;
297 }
298
299 int
300 cpci_hp_unregister_bus(struct pci_bus *bus)
301 {
302         struct slot *slot;
303         struct slot *tmp;
304         int status = 0;
305
306         down_write(&list_rwsem);
307         if (!slots) {
308                 up_write(&list_rwsem);
309                 return -1;
310         }
311         list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
312                 if (slot->bus == bus) {
313                         list_del(&slot->slot_list);
314                         slots--;
315
316                         dbg("deregistering slot %s", slot_name(slot));
317                         status = pci_hp_deregister(slot->hotplug_slot);
318                         if (status) {
319                                 err("pci_hp_deregister failed with error %d",
320                                     status);
321                                 break;
322                         }
323                 }
324         }
325         up_write(&list_rwsem);
326         return status;
327 }
328
329 /* This is the interrupt mode interrupt handler */
330 static irqreturn_t
331 cpci_hp_intr(int irq, void *data)
332 {
333         dbg("entered cpci_hp_intr");
334
335         /* Check to see if it was our interrupt */
336         if ((controller->irq_flags & IRQF_SHARED) &&
337             !controller->ops->check_irq(controller->dev_id)) {
338                 dbg("exited cpci_hp_intr, not our interrupt");
339                 return IRQ_NONE;
340         }
341
342         /* Disable ENUM interrupt */
343         controller->ops->disable_irq();
344
345         /* Trigger processing by the event thread */
346         wake_up_process(cpci_thread);
347         return IRQ_HANDLED;
348 }
349
350 /*
351  * According to PICMG 2.1 R2.0, section 6.3.2, upon
352  * initialization, the system driver shall clear the
353  * INS bits of the cold-inserted devices.
354  */
355 static int
356 init_slots(int clear_ins)
357 {
358         struct slot *slot;
359         struct pci_dev* dev;
360
361         dbg("%s - enter", __func__);
362         down_read(&list_rwsem);
363         if (!slots) {
364                 up_read(&list_rwsem);
365                 return -1;
366         }
367         list_for_each_entry(slot, &slot_list, slot_list) {
368                 dbg("%s - looking at slot %s", __func__, slot_name(slot));
369                 if (clear_ins && cpci_check_and_clear_ins(slot))
370                         dbg("%s - cleared INS for slot %s",
371                             __func__, slot_name(slot));
372                 dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
373                 if (dev) {
374                         if (update_adapter_status(slot->hotplug_slot, 1))
375                                 warn("failure to update adapter file");
376                         if (update_latch_status(slot->hotplug_slot, 1))
377                                 warn("failure to update latch file");
378                         slot->dev = dev;
379                 }
380         }
381         up_read(&list_rwsem);
382         dbg("%s - exit", __func__);
383         return 0;
384 }
385
386 static int
387 check_slots(void)
388 {
389         struct slot *slot;
390         int extracted;
391         int inserted;
392         u16 hs_csr;
393
394         down_read(&list_rwsem);
395         if (!slots) {
396                 up_read(&list_rwsem);
397                 err("no slots registered, shutting down");
398                 return -1;
399         }
400         extracted = inserted = 0;
401         list_for_each_entry(slot, &slot_list, slot_list) {
402                 dbg("%s - looking at slot %s", __func__, slot_name(slot));
403                 if (cpci_check_and_clear_ins(slot)) {
404                         /*
405                          * Some broken hardware (e.g. PLX 9054AB) asserts
406                          * ENUM# twice...
407                          */
408                         if (slot->dev) {
409                                 warn("slot %s already inserted",
410                                      slot_name(slot));
411                                 inserted++;
412                                 continue;
413                         }
414
415                         /* Process insertion */
416                         dbg("%s - slot %s inserted", __func__, slot_name(slot));
417
418                         /* GSM, debug */
419                         hs_csr = cpci_get_hs_csr(slot);
420                         dbg("%s - slot %s HS_CSR (1) = %04x",
421                             __func__, slot_name(slot), hs_csr);
422
423                         /* Configure device */
424                         dbg("%s - configuring slot %s",
425                             __func__, slot_name(slot));
426                         if (cpci_configure_slot(slot)) {
427                                 err("%s - could not configure slot %s",
428                                     __func__, slot_name(slot));
429                                 continue;
430                         }
431                         dbg("%s - finished configuring slot %s",
432                             __func__, slot_name(slot));
433
434                         /* GSM, debug */
435                         hs_csr = cpci_get_hs_csr(slot);
436                         dbg("%s - slot %s HS_CSR (2) = %04x",
437                             __func__, slot_name(slot), hs_csr);
438
439                         if (update_latch_status(slot->hotplug_slot, 1))
440                                 warn("failure to update latch file");
441
442                         if (update_adapter_status(slot->hotplug_slot, 1))
443                                 warn("failure to update adapter file");
444
445                         cpci_led_off(slot);
446
447                         /* GSM, debug */
448                         hs_csr = cpci_get_hs_csr(slot);
449                         dbg("%s - slot %s HS_CSR (3) = %04x",
450                             __func__, slot_name(slot), hs_csr);
451
452                         inserted++;
453                 } else if (cpci_check_ext(slot)) {
454                         /* Process extraction request */
455                         dbg("%s - slot %s extracted",
456                             __func__, slot_name(slot));
457
458                         /* GSM, debug */
459                         hs_csr = cpci_get_hs_csr(slot);
460                         dbg("%s - slot %s HS_CSR = %04x",
461                             __func__, slot_name(slot), hs_csr);
462
463                         if (!slot->extracting) {
464                                 if (update_latch_status(slot->hotplug_slot, 0)) {
465                                         warn("failure to update latch file");
466                                 }
467                                 slot->extracting = 1;
468                                 atomic_inc(&extracting);
469                         }
470                         extracted++;
471                 } else if (slot->extracting) {
472                         hs_csr = cpci_get_hs_csr(slot);
473                         if (hs_csr == 0xffff) {
474                                 /*
475                                  * Hmmm, we're likely hosed at this point, should we
476                                  * bother trying to tell the driver or not?
477                                  */
478                                 err("card in slot %s was improperly removed",
479                                     slot_name(slot));
480                                 if (update_adapter_status(slot->hotplug_slot, 0))
481                                         warn("failure to update adapter file");
482                                 slot->extracting = 0;
483                                 atomic_dec(&extracting);
484                         }
485                 }
486         }
487         up_read(&list_rwsem);
488         dbg("inserted=%d, extracted=%d, extracting=%d",
489             inserted, extracted, atomic_read(&extracting));
490         if (inserted || extracted)
491                 return extracted;
492         else if (!atomic_read(&extracting)) {
493                 err("cannot find ENUM# source, shutting down");
494                 return -1;
495         }
496         return 0;
497 }
498
499 /* This is the interrupt mode worker thread body */
500 static int
501 event_thread(void *data)
502 {
503         int rc;
504
505         dbg("%s - event thread started", __func__);
506         while (1) {
507                 dbg("event thread sleeping");
508                 set_current_state(TASK_INTERRUPTIBLE);
509                 schedule();
510                 if (kthread_should_stop())
511                         break;
512                 do {
513                         rc = check_slots();
514                         if (rc > 0) {
515                                 /* Give userspace a chance to handle extraction */
516                                 msleep(500);
517                         } else if (rc < 0) {
518                                 dbg("%s - error checking slots", __func__);
519                                 thread_finished = 1;
520                                 goto out;
521                         }
522                 } while (atomic_read(&extracting) && !kthread_should_stop());
523                 if (kthread_should_stop())
524                         break;
525
526                 /* Re-enable ENUM# interrupt */
527                 dbg("%s - re-enabling irq", __func__);
528                 controller->ops->enable_irq();
529         }
530  out:
531         return 0;
532 }
533
534 /* This is the polling mode worker thread body */
535 static int
536 poll_thread(void *data)
537 {
538         int rc;
539
540         while (1) {
541                 if (kthread_should_stop() || signal_pending(current))
542                         break;
543                 if (controller->ops->query_enum()) {
544                         do {
545                                 rc = check_slots();
546                                 if (rc > 0) {
547                                         /* Give userspace a chance to handle extraction */
548                                         msleep(500);
549                                 } else if (rc < 0) {
550                                         dbg("%s - error checking slots", __func__);
551                                         thread_finished = 1;
552                                         goto out;
553                                 }
554                         } while (atomic_read(&extracting) && !kthread_should_stop());
555                 }
556                 msleep(100);
557         }
558  out:
559         return 0;
560 }
561
562 static int
563 cpci_start_thread(void)
564 {
565         if (controller->irq)
566                 cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd");
567         else
568                 cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld");
569         if (IS_ERR(cpci_thread)) {
570                 err("Can't start up our thread");
571                 return PTR_ERR(cpci_thread);
572         }
573         thread_finished = 0;
574         return 0;
575 }
576
577 static void
578 cpci_stop_thread(void)
579 {
580         kthread_stop(cpci_thread);
581         thread_finished = 1;
582 }
583
584 int
585 cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
586 {
587         int status = 0;
588
589         if (controller)
590                 return -1;
591         if (!(new_controller && new_controller->ops))
592                 return -EINVAL;
593         if (new_controller->irq) {
594                 if (!(new_controller->ops->enable_irq &&
595                      new_controller->ops->disable_irq))
596                         status = -EINVAL;
597                 if (request_irq(new_controller->irq,
598                                cpci_hp_intr,
599                                new_controller->irq_flags,
600                                MY_NAME,
601                                new_controller->dev_id)) {
602                         err("Can't get irq %d for the hotplug cPCI controller",
603                             new_controller->irq);
604                         status = -ENODEV;
605                 }
606                 dbg("%s - acquired controller irq %d",
607                     __func__, new_controller->irq);
608         }
609         if (!status)
610                 controller = new_controller;
611         return status;
612 }
613
614 static void
615 cleanup_slots(void)
616 {
617         struct slot *slot;
618         struct slot *tmp;
619
620         /*
621          * Unregister all of our slots with the pci_hotplug subsystem,
622          * and free up all memory that we had allocated.
623          */
624         down_write(&list_rwsem);
625         if (!slots)
626                 goto cleanup_null;
627         list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) {
628                 list_del(&slot->slot_list);
629                 pci_hp_deregister(slot->hotplug_slot);
630         }
631 cleanup_null:
632         up_write(&list_rwsem);
633         return;
634 }
635
636 int
637 cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
638 {
639         int status = 0;
640
641         if (controller) {
642                 if (!thread_finished)
643                         cpci_stop_thread();
644                 if (controller->irq)
645                         free_irq(controller->irq, controller->dev_id);
646                 controller = NULL;
647                 cleanup_slots();
648         } else
649                 status = -ENODEV;
650         return status;
651 }
652
653 int
654 cpci_hp_start(void)
655 {
656         static int first = 1;
657         int status;
658
659         dbg("%s - enter", __func__);
660         if (!controller)
661                 return -ENODEV;
662
663         down_read(&list_rwsem);
664         if (list_empty(&slot_list)) {
665                 up_read(&list_rwsem);
666                 return -ENODEV;
667         }
668         up_read(&list_rwsem);
669
670         status = init_slots(first);
671         if (first)
672                 first = 0;
673         if (status)
674                 return status;
675
676         status = cpci_start_thread();
677         if (status)
678                 return status;
679         dbg("%s - thread started", __func__);
680
681         if (controller->irq) {
682                 /* Start enum interrupt processing */
683                 dbg("%s - enabling irq", __func__);
684                 controller->ops->enable_irq();
685         }
686         dbg("%s - exit", __func__);
687         return 0;
688 }
689
690 int
691 cpci_hp_stop(void)
692 {
693         if (!controller)
694                 return -ENODEV;
695         if (controller->irq) {
696                 /* Stop enum interrupt processing */
697                 dbg("%s - disabling irq", __func__);
698                 controller->ops->disable_irq();
699         }
700         cpci_stop_thread();
701         return 0;
702 }
703
704 int __init
705 cpci_hotplug_init(int debug)
706 {
707         cpci_debug = debug;
708         return 0;
709 }
710
711 void __exit
712 cpci_hotplug_exit(void)
713 {
714         /*
715          * Clean everything up.
716          */
717         cpci_hp_stop();
718         cpci_hp_unregister_controller(controller);
719 }
720
721 EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
722 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
723 EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
724 EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
725 EXPORT_SYMBOL_GPL(cpci_hp_start);
726 EXPORT_SYMBOL_GPL(cpci_hp_stop);