Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / pci / hotplug / sgi_hotplug.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
7  *
8  * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
9  * Work to add BIOS PROM support was completed by Mike Habeck.
10  */
11
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/proc_fs.h>
17 #include <linux/types.h>
18 #include <linux/mutex.h>
19
20 #include <asm/sn/addrs.h>
21 #include <asm/sn/geo.h>
22 #include <asm/sn/l1.h>
23 #include <asm/sn/module.h>
24 #include <asm/sn/pcibr_provider.h>
25 #include <asm/sn/pcibus_provider_defs.h>
26 #include <asm/sn/pcidev.h>
27 #include <asm/sn/sn_feature_sets.h>
28 #include <asm/sn/sn_sal.h>
29 #include <asm/sn/types.h>
30
31 #include "../pci.h"
32 #include "pci_hotplug.h"
33
34 MODULE_LICENSE("GPL");
35 MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
36 MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
37
38 #define PCIIO_ASIC_TYPE_TIOCA           4
39 #define PCI_SLOT_ALREADY_UP             2       /* slot already up */
40 #define PCI_SLOT_ALREADY_DOWN           3       /* slot already down */
41 #define PCI_L1_ERR                      7       /* L1 console command error */
42 #define PCI_EMPTY_33MHZ                 15      /* empty 33 MHz bus */
43 #define PCI_L1_QSIZE                    128     /* our L1 message buffer size */
44 #define SN_MAX_HP_SLOTS                 32      /* max hotplug slots */
45 #define SGI_HOTPLUG_PROM_REV            0x0430  /* Min. required PROM version */
46 #define SN_SLOT_NAME_SIZE               33      /* size of name string */
47
48 /* internal list head */
49 static struct list_head sn_hp_list;
50
51 /* hotplug_slot struct's private pointer */
52 struct slot {
53         int device_num;
54         struct pci_bus *pci_bus;
55         /* this struct for glue internal only */
56         struct hotplug_slot *hotplug_slot;
57         struct list_head hp_list;
58         char physical_path[SN_SLOT_NAME_SIZE];
59 };
60
61 struct pcibr_slot_enable_resp {
62         int resp_sub_errno;
63         char resp_l1_msg[PCI_L1_QSIZE + 1];
64 };
65
66 struct pcibr_slot_disable_resp {
67         int resp_sub_errno;
68         char resp_l1_msg[PCI_L1_QSIZE + 1];
69 };
70
71 enum sn_pci_req_e {
72         PCI_REQ_SLOT_ELIGIBLE,
73         PCI_REQ_SLOT_DISABLE
74 };
75
76 static int enable_slot(struct hotplug_slot *slot);
77 static int disable_slot(struct hotplug_slot *slot);
78 static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
79
80 static struct hotplug_slot_ops sn_hotplug_slot_ops = {
81         .owner                  = THIS_MODULE,
82         .enable_slot            = enable_slot,
83         .disable_slot           = disable_slot,
84         .get_power_status       = get_power_status,
85 };
86
87 static DEFINE_MUTEX(sn_hotplug_mutex);
88
89 static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot,
90                           char *buf)
91 {
92         int retval = -ENOENT;
93         struct slot *slot = bss_hotplug_slot->private;
94
95         if (!slot)
96                 return retval;
97
98         retval = sprintf (buf, "%s\n", slot->physical_path);
99         return retval;
100 }
101
102 static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
103
104 static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
105 {
106         struct pcibus_info *pcibus_info;
107         u16 busnum, segment, ioboard_type;
108
109         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
110
111         /* Check to see if this is a valid slot on 'pci_bus' */
112         if (!(pcibus_info->pbi_valid_devices & (1 << device)))
113                 return -EPERM;
114
115         ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
116         busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
117         segment = pci_domain_nr(pci_bus) & 0xf;
118
119         /* Do not allow hotplug operations on base I/O cards */
120         if ((ioboard_type == L1_BRICKTYPE_IX ||
121              ioboard_type == L1_BRICKTYPE_IA) &&
122             (segment == 1 && busnum == 0 && device != 1))
123                 return -EPERM;
124
125         return 1;
126 }
127
128 static int sn_pci_bus_valid(struct pci_bus *pci_bus)
129 {
130         struct pcibus_info *pcibus_info;
131         u32 asic_type;
132         u16 ioboard_type;
133
134         /* Don't register slots hanging off the TIOCA bus */
135         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
136         asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
137         if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
138                 return -EPERM;
139
140         /* Only register slots in I/O Bricks that support hotplug */
141         ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
142         switch (ioboard_type) {
143                 case L1_BRICKTYPE_IX:
144                 case L1_BRICKTYPE_PX:
145                 case L1_BRICKTYPE_IA:
146                 case L1_BRICKTYPE_PA:
147                 case L1_BOARDTYPE_PCIX3SLOT:
148                         return 1;
149                         break;
150                 default:
151                         return -EPERM;
152                         break;
153         }
154
155         return -EIO;
156 }
157
158 static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
159                                     struct pci_bus *pci_bus, int device)
160 {
161         struct pcibus_info *pcibus_info;
162         struct slot *slot;
163
164         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
165
166         slot = kzalloc(sizeof(*slot), GFP_KERNEL);
167         if (!slot)
168                 return -ENOMEM;
169         bss_hotplug_slot->private = slot;
170
171         bss_hotplug_slot->name = kmalloc(SN_SLOT_NAME_SIZE, GFP_KERNEL);
172         if (!bss_hotplug_slot->name) {
173                 kfree(bss_hotplug_slot->private);
174                 return -ENOMEM;
175         }
176
177         slot->device_num = device;
178         slot->pci_bus = pci_bus;
179         sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
180                 pci_domain_nr(pci_bus),
181                 ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
182                 device + 1);
183
184         sn_generate_path(pci_bus, slot->physical_path);
185
186         slot->hotplug_slot = bss_hotplug_slot;
187         list_add(&slot->hp_list, &sn_hp_list);
188
189         return 0;
190 }
191
192 static struct hotplug_slot * sn_hp_destroy(void)
193 {
194         struct slot *slot;
195         struct hotplug_slot *bss_hotplug_slot = NULL;
196
197         list_for_each_entry(slot, &sn_hp_list, hp_list) {
198                 bss_hotplug_slot = slot->hotplug_slot;
199                 list_del(&((struct slot *)bss_hotplug_slot->private)->
200                          hp_list);
201                 sysfs_remove_file(&bss_hotplug_slot->kobj,
202                                   &sn_slot_path_attr.attr);
203                 break;
204         }
205         return bss_hotplug_slot;
206 }
207
208 static void sn_bus_alloc_data(struct pci_dev *dev)
209 {
210         struct pci_bus *subordinate_bus;
211         struct pci_dev *child;
212
213         sn_pci_fixup_slot(dev);
214
215         /* Recursively sets up the sn_irq_info structs */
216         if (dev->subordinate) {
217                 subordinate_bus = dev->subordinate;
218                 list_for_each_entry(child, &subordinate_bus->devices, bus_list)
219                         sn_bus_alloc_data(child);
220         }
221 }
222
223 static void sn_bus_free_data(struct pci_dev *dev)
224 {
225         struct pci_bus *subordinate_bus;
226         struct pci_dev *child;
227
228         /* Recursively clean up sn_irq_info structs */
229         if (dev->subordinate) {
230                 subordinate_bus = dev->subordinate;
231                 list_for_each_entry(child, &subordinate_bus->devices, bus_list)
232                         sn_bus_free_data(child);
233         }
234         /*
235          * Some drivers may use dma accesses during the
236          * driver remove function. We release the sysdata
237          * areas after the driver remove functions have
238          * been called.
239          */
240         sn_bus_store_sysdata(dev);
241         sn_pci_unfixup_slot(dev);
242 }
243
244 static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
245                           int device_num)
246 {
247         struct slot *slot = bss_hotplug_slot->private;
248         struct pcibus_info *pcibus_info;
249         struct pcibr_slot_enable_resp resp;
250         int rc;
251
252         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
253
254         /*
255          * Power-on and initialize the slot in the SN
256          * PCI infrastructure.
257          */
258         rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp);
259
260         if (rc == PCI_SLOT_ALREADY_UP) {
261                 dev_dbg(slot->pci_bus->self, "is already active\n");
262                 return 1; /* return 1 to user */
263         }
264
265         if (rc == PCI_L1_ERR) {
266                 dev_dbg(slot->pci_bus->self,
267                         "L1 failure %d with message: %s",
268                         resp.resp_sub_errno, resp.resp_l1_msg);
269                 return -EPERM;
270         }
271
272         if (rc) {
273                 dev_dbg(slot->pci_bus->self,
274                         "insert failed with error %d sub-error %d\n",
275                         rc, resp.resp_sub_errno);
276                 return -EIO;
277         }
278
279         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
280         pcibus_info->pbi_enabled_devices |= (1 << device_num);
281
282         return 0;
283 }
284
285 static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
286                            int device_num, int action)
287 {
288         struct slot *slot = bss_hotplug_slot->private;
289         struct pcibus_info *pcibus_info;
290         struct pcibr_slot_disable_resp resp;
291         int rc;
292
293         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
294
295         rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
296
297         if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
298             (rc == PCI_SLOT_ALREADY_DOWN)) {
299                 dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
300                 return 1; /* return 1 to user */
301         }
302
303         if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
304                 dev_dbg(slot->pci_bus->self,
305                         "Cannot remove last 33MHz card\n");
306                 return -EPERM;
307         }
308
309         if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
310                 dev_dbg(slot->pci_bus->self,
311                         "L1 failure %d with message \n%s\n",
312                         resp.resp_sub_errno, resp.resp_l1_msg);
313                 return -EPERM;
314         }
315
316         if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
317                 dev_dbg(slot->pci_bus->self,
318                         "remove failed with error %d sub-error %d\n",
319                         rc, resp.resp_sub_errno);
320                 return -EIO;
321         }
322
323         if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
324                 return 0;
325
326         if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
327                 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
328                 pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
329                 dev_dbg(slot->pci_bus->self, "remove successful\n");
330                 return 0;
331         }
332
333         if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
334                 dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
335         }
336
337         return rc;
338 }
339
340 static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
341 {
342         struct slot *slot = bss_hotplug_slot->private;
343         struct pci_bus *new_bus = NULL;
344         struct pci_dev *dev;
345         int func, num_funcs;
346         int new_ppb = 0;
347         int rc;
348
349         /* Serialize the Linux PCI infrastructure */
350         mutex_lock(&sn_hotplug_mutex);
351
352         /*
353          * Power-on and initialize the slot in the SN
354          * PCI infrastructure.
355          */
356         rc = sn_slot_enable(bss_hotplug_slot, slot->device_num);
357         if (rc) {
358                 mutex_unlock(&sn_hotplug_mutex);
359                 return rc;
360         }
361
362         num_funcs = pci_scan_slot(slot->pci_bus,
363                                   PCI_DEVFN(slot->device_num + 1, 0));
364         if (!num_funcs) {
365                 dev_dbg(slot->pci_bus->self, "no device in slot\n");
366                 mutex_unlock(&sn_hotplug_mutex);
367                 return -ENODEV;
368         }
369
370         sn_pci_controller_fixup(pci_domain_nr(slot->pci_bus),
371                                 slot->pci_bus->number,
372                                 slot->pci_bus);
373         /*
374          * Map SN resources for all functions on the card
375          * to the Linux PCI interface and tell the drivers
376          * about them.
377          */
378         for (func = 0; func < num_funcs;  func++) {
379                 dev = pci_get_slot(slot->pci_bus,
380                                    PCI_DEVFN(slot->device_num + 1,
381                                              PCI_FUNC(func)));
382                 if (dev) {
383                         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
384                                 unsigned char sec_bus;
385                                 pci_read_config_byte(dev, PCI_SECONDARY_BUS,
386                                                      &sec_bus);
387                                 new_bus = pci_add_new_bus(dev->bus, dev,
388                                                           sec_bus);
389                                 pci_scan_child_bus(new_bus);
390                                 sn_pci_controller_fixup(pci_domain_nr(new_bus),
391                                                         new_bus->number,
392                                                         new_bus);
393                                 new_ppb = 1;
394                         }
395                         sn_bus_alloc_data(dev);
396                         pci_dev_put(dev);
397                 }
398         }
399
400         /* Call the driver for the new device */
401         pci_bus_add_devices(slot->pci_bus);
402         /* Call the drivers for the new devices subordinate to PPB */
403         if (new_ppb)
404                 pci_bus_add_devices(new_bus);
405
406         mutex_unlock(&sn_hotplug_mutex);
407
408         if (rc == 0)
409                 dev_dbg(slot->pci_bus->self,
410                         "insert operation successful\n");
411         else
412                 dev_dbg(slot->pci_bus->self,
413                         "insert operation failed rc = %d\n", rc);
414
415         return rc;
416 }
417
418 static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
419 {
420         struct slot *slot = bss_hotplug_slot->private;
421         struct pci_dev *dev;
422         int func;
423         int rc;
424
425         /* Acquire update access to the bus */
426         mutex_lock(&sn_hotplug_mutex);
427
428         /* is it okay to bring this slot down? */
429         rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
430                              PCI_REQ_SLOT_ELIGIBLE);
431         if (rc)
432                 goto leaving;
433
434         /* Free the SN resources assigned to the Linux device.*/
435         for (func = 0; func < 8;  func++) {
436                 dev = pci_get_slot(slot->pci_bus,
437                                    PCI_DEVFN(slot->device_num + 1,
438                                              PCI_FUNC(func)));
439                 if (dev) {
440                         sn_bus_free_data(dev);
441                         pci_remove_bus_device(dev);
442                         pci_dev_put(dev);
443                 }
444         }
445
446         /* free the collected sysdata pointers */
447         sn_bus_free_sysdata();
448
449         /* Deactivate slot */
450         rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
451                              PCI_REQ_SLOT_DISABLE);
452  leaving:
453         /* Release the bus lock */
454         mutex_unlock(&sn_hotplug_mutex);
455
456         return rc;
457 }
458
459 static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
460                                    u8 *value)
461 {
462         struct slot *slot = bss_hotplug_slot->private;
463         struct pcibus_info *pcibus_info;
464         u32 power;
465
466         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
467         mutex_lock(&sn_hotplug_mutex);
468         power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
469         *value = power ? 1 : 0;
470         mutex_unlock(&sn_hotplug_mutex);
471         return 0;
472 }
473
474 static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
475 {
476         kfree(bss_hotplug_slot->info);
477         kfree(bss_hotplug_slot->name);
478         kfree(bss_hotplug_slot->private);
479         kfree(bss_hotplug_slot);
480 }
481
482 static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
483 {
484         int device;
485         struct hotplug_slot *bss_hotplug_slot;
486         int rc = 0;
487
488         /*
489          * Currently only four devices are supported,
490          * in the future there maybe more -- up to 32.
491          */
492
493         for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
494                 if (sn_pci_slot_valid(pci_bus, device) != 1)
495                         continue;
496
497                 bss_hotplug_slot = kzalloc(sizeof(*bss_hotplug_slot),
498                                            GFP_KERNEL);
499                 if (!bss_hotplug_slot) {
500                         rc = -ENOMEM;
501                         goto alloc_err;
502                 }
503
504                 bss_hotplug_slot->info =
505                         kzalloc(sizeof(struct hotplug_slot_info),
506                                 GFP_KERNEL);
507                 if (!bss_hotplug_slot->info) {
508                         rc = -ENOMEM;
509                         goto alloc_err;
510                 }
511
512                 if (sn_hp_slot_private_alloc(bss_hotplug_slot,
513                                              pci_bus, device)) {
514                         rc = -ENOMEM;
515                         goto alloc_err;
516                 }
517
518                 bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
519                 bss_hotplug_slot->release = &sn_release_slot;
520
521                 rc = pci_hp_register(bss_hotplug_slot);
522                 if (rc)
523                         goto register_err;
524
525                 rc = sysfs_create_file(&bss_hotplug_slot->kobj,
526                                        &sn_slot_path_attr.attr);
527                 if (rc)
528                         goto register_err;
529         }
530         dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
531         return rc;
532
533 register_err:
534         dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
535                 rc);
536
537 alloc_err:
538         if (rc == -ENOMEM)
539                 dev_dbg(pci_bus->self, "Memory allocation error\n");
540
541         /* destroy THIS element */
542         if (bss_hotplug_slot)
543                 sn_release_slot(bss_hotplug_slot);
544
545         /* destroy anything else on the list */
546         while ((bss_hotplug_slot = sn_hp_destroy()))
547                 pci_hp_deregister(bss_hotplug_slot);
548
549         return rc;
550 }
551
552 static int sn_pci_hotplug_init(void)
553 {
554         struct pci_bus *pci_bus = NULL;
555         int rc;
556         int registered = 0;
557
558         if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
559                 printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
560                        __FUNCTION__);
561                 return -EPERM;
562         }
563
564         INIT_LIST_HEAD(&sn_hp_list);
565
566         while ((pci_bus = pci_find_next_bus(pci_bus))) {
567                 if (!pci_bus->sysdata)
568                         continue;
569
570                 rc = sn_pci_bus_valid(pci_bus);
571                 if (rc != 1) {
572                         dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
573                         continue;
574                 }
575                 dev_dbg(pci_bus->self, "valid hotplug bus\n");
576
577                 rc = sn_hotplug_slot_register(pci_bus);
578                 if (!rc) {
579                         registered = 1;
580                 } else {
581                         registered = 0;
582                         break;
583                 }
584         }
585
586         return registered == 1 ? 0 : -ENODEV;
587 }
588
589 static void sn_pci_hotplug_exit(void)
590 {
591         struct hotplug_slot *bss_hotplug_slot;
592
593         while ((bss_hotplug_slot = sn_hp_destroy()))
594                 pci_hp_deregister(bss_hotplug_slot);
595
596         if (!list_empty(&sn_hp_list))
597                 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
598 }
599
600 module_init(sn_pci_hotplug_init);
601 module_exit(sn_pci_hotplug_exit);