5d188c558386b73aadd714c21cc9e305483c0d44
[sfrench/cifs-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/pci_hotplug.h>
17 #include <linux/proc_fs.h>
18 #include <linux/types.h>
19 #include <linux/mutex.h>
20
21 #include <asm/sn/addrs.h>
22 #include <asm/sn/geo.h>
23 #include <asm/sn/l1.h>
24 #include <asm/sn/module.h>
25 #include <asm/sn/pcibr_provider.h>
26 #include <asm/sn/pcibus_provider_defs.h>
27 #include <asm/sn/pcidev.h>
28 #include <asm/sn/sn_feature_sets.h>
29 #include <asm/sn/sn_sal.h>
30 #include <asm/sn/types.h>
31
32 #include "../pci.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_free_data(struct pci_dev *dev)
209 {
210         struct pci_bus *subordinate_bus;
211         struct pci_dev *child;
212
213         /* Recursively clean up sn_irq_info structs */
214         if (dev->subordinate) {
215                 subordinate_bus = dev->subordinate;
216                 list_for_each_entry(child, &subordinate_bus->devices, bus_list)
217                         sn_bus_free_data(child);
218         }
219         /*
220          * Some drivers may use dma accesses during the
221          * driver remove function. We release the sysdata
222          * areas after the driver remove functions have
223          * been called.
224          */
225         sn_bus_store_sysdata(dev);
226         sn_pci_unfixup_slot(dev);
227 }
228
229 static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
230                           int device_num)
231 {
232         struct slot *slot = bss_hotplug_slot->private;
233         struct pcibus_info *pcibus_info;
234         struct pcibr_slot_enable_resp resp;
235         int rc;
236
237         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
238
239         /*
240          * Power-on and initialize the slot in the SN
241          * PCI infrastructure.
242          */
243         rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp);
244
245         if (rc == PCI_SLOT_ALREADY_UP) {
246                 dev_dbg(slot->pci_bus->self, "is already active\n");
247                 return 1; /* return 1 to user */
248         }
249
250         if (rc == PCI_L1_ERR) {
251                 dev_dbg(slot->pci_bus->self,
252                         "L1 failure %d with message: %s",
253                         resp.resp_sub_errno, resp.resp_l1_msg);
254                 return -EPERM;
255         }
256
257         if (rc) {
258                 dev_dbg(slot->pci_bus->self,
259                         "insert failed with error %d sub-error %d\n",
260                         rc, resp.resp_sub_errno);
261                 return -EIO;
262         }
263
264         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
265         pcibus_info->pbi_enabled_devices |= (1 << device_num);
266
267         return 0;
268 }
269
270 static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
271                            int device_num, int action)
272 {
273         struct slot *slot = bss_hotplug_slot->private;
274         struct pcibus_info *pcibus_info;
275         struct pcibr_slot_disable_resp resp;
276         int rc;
277
278         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
279
280         rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
281
282         if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
283             (rc == PCI_SLOT_ALREADY_DOWN)) {
284                 dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
285                 return 1; /* return 1 to user */
286         }
287
288         if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
289                 dev_dbg(slot->pci_bus->self,
290                         "Cannot remove last 33MHz card\n");
291                 return -EPERM;
292         }
293
294         if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
295                 dev_dbg(slot->pci_bus->self,
296                         "L1 failure %d with message \n%s\n",
297                         resp.resp_sub_errno, resp.resp_l1_msg);
298                 return -EPERM;
299         }
300
301         if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
302                 dev_dbg(slot->pci_bus->self,
303                         "remove failed with error %d sub-error %d\n",
304                         rc, resp.resp_sub_errno);
305                 return -EIO;
306         }
307
308         if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
309                 return 0;
310
311         if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
312                 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
313                 pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
314                 dev_dbg(slot->pci_bus->self, "remove successful\n");
315                 return 0;
316         }
317
318         if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
319                 dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
320         }
321
322         return rc;
323 }
324
325 /*
326  * Power up and configure the slot via a SAL call to PROM.
327  * Scan slot (and any children), do any platform specific fixup,
328  * and find device driver.
329  */
330 static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
331 {
332         struct slot *slot = bss_hotplug_slot->private;
333         struct pci_bus *new_bus = NULL;
334         struct pci_dev *dev;
335         int func, num_funcs;
336         int new_ppb = 0;
337         int rc;
338         void pcibios_fixup_device_resources(struct pci_dev *);
339
340         /* Serialize the Linux PCI infrastructure */
341         mutex_lock(&sn_hotplug_mutex);
342
343         /*
344          * Power-on and initialize the slot in the SN
345          * PCI infrastructure.
346          */
347         rc = sn_slot_enable(bss_hotplug_slot, slot->device_num);
348         if (rc) {
349                 mutex_unlock(&sn_hotplug_mutex);
350                 return rc;
351         }
352
353         num_funcs = pci_scan_slot(slot->pci_bus,
354                                   PCI_DEVFN(slot->device_num + 1, 0));
355         if (!num_funcs) {
356                 dev_dbg(slot->pci_bus->self, "no device in slot\n");
357                 mutex_unlock(&sn_hotplug_mutex);
358                 return -ENODEV;
359         }
360
361         /*
362          * Map SN resources for all functions on the card
363          * to the Linux PCI interface and tell the drivers
364          * about them.
365          */
366         for (func = 0; func < num_funcs;  func++) {
367                 dev = pci_get_slot(slot->pci_bus,
368                                    PCI_DEVFN(slot->device_num + 1,
369                                              PCI_FUNC(func)));
370                 if (dev) {
371                         /* Need to do slot fixup on PPB before fixup of children
372                          * (PPB's pcidev_info needs to be in pcidev_info list
373                          * before child's SN_PCIDEV_INFO() call to setup
374                          * pdi_host_pcidev_info).
375                          */
376                         pcibios_fixup_device_resources(dev);
377                         sn_pci_fixup_slot(dev);
378                         if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
379                                 unsigned char sec_bus;
380                                 pci_read_config_byte(dev, PCI_SECONDARY_BUS,
381                                                      &sec_bus);
382                                 new_bus = pci_add_new_bus(dev->bus, dev,
383                                                           sec_bus);
384                                 pci_scan_child_bus(new_bus);
385                                 new_ppb = 1;
386                         }
387                         pci_dev_put(dev);
388                 }
389         }
390
391         /* Call the driver for the new device */
392         pci_bus_add_devices(slot->pci_bus);
393         /* Call the drivers for the new devices subordinate to PPB */
394         if (new_ppb)
395                 pci_bus_add_devices(new_bus);
396
397         mutex_unlock(&sn_hotplug_mutex);
398
399         if (rc == 0)
400                 dev_dbg(slot->pci_bus->self,
401                         "insert operation successful\n");
402         else
403                 dev_dbg(slot->pci_bus->self,
404                         "insert operation failed rc = %d\n", rc);
405
406         return rc;
407 }
408
409 static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
410 {
411         struct slot *slot = bss_hotplug_slot->private;
412         struct pci_dev *dev;
413         int func;
414         int rc;
415
416         /* Acquire update access to the bus */
417         mutex_lock(&sn_hotplug_mutex);
418
419         /* is it okay to bring this slot down? */
420         rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
421                              PCI_REQ_SLOT_ELIGIBLE);
422         if (rc)
423                 goto leaving;
424
425         /* Free the SN resources assigned to the Linux device.*/
426         for (func = 0; func < 8;  func++) {
427                 dev = pci_get_slot(slot->pci_bus,
428                                    PCI_DEVFN(slot->device_num + 1,
429                                              PCI_FUNC(func)));
430                 if (dev) {
431                         sn_bus_free_data(dev);
432                         pci_remove_bus_device(dev);
433                         pci_dev_put(dev);
434                 }
435         }
436
437         /* free the collected sysdata pointers */
438         sn_bus_free_sysdata();
439
440         /* Deactivate slot */
441         rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
442                              PCI_REQ_SLOT_DISABLE);
443  leaving:
444         /* Release the bus lock */
445         mutex_unlock(&sn_hotplug_mutex);
446
447         return rc;
448 }
449
450 static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
451                                    u8 *value)
452 {
453         struct slot *slot = bss_hotplug_slot->private;
454         struct pcibus_info *pcibus_info;
455         u32 power;
456
457         pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
458         mutex_lock(&sn_hotplug_mutex);
459         power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
460         *value = power ? 1 : 0;
461         mutex_unlock(&sn_hotplug_mutex);
462         return 0;
463 }
464
465 static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
466 {
467         kfree(bss_hotplug_slot->info);
468         kfree(bss_hotplug_slot->name);
469         kfree(bss_hotplug_slot->private);
470         kfree(bss_hotplug_slot);
471 }
472
473 static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
474 {
475         int device;
476         struct hotplug_slot *bss_hotplug_slot;
477         int rc = 0;
478
479         /*
480          * Currently only four devices are supported,
481          * in the future there maybe more -- up to 32.
482          */
483
484         for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
485                 if (sn_pci_slot_valid(pci_bus, device) != 1)
486                         continue;
487
488                 bss_hotplug_slot = kzalloc(sizeof(*bss_hotplug_slot),
489                                            GFP_KERNEL);
490                 if (!bss_hotplug_slot) {
491                         rc = -ENOMEM;
492                         goto alloc_err;
493                 }
494
495                 bss_hotplug_slot->info =
496                         kzalloc(sizeof(struct hotplug_slot_info),
497                                 GFP_KERNEL);
498                 if (!bss_hotplug_slot->info) {
499                         rc = -ENOMEM;
500                         goto alloc_err;
501                 }
502
503                 if (sn_hp_slot_private_alloc(bss_hotplug_slot,
504                                              pci_bus, device)) {
505                         rc = -ENOMEM;
506                         goto alloc_err;
507                 }
508
509                 bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
510                 bss_hotplug_slot->release = &sn_release_slot;
511
512                 rc = pci_hp_register(bss_hotplug_slot);
513                 if (rc)
514                         goto register_err;
515
516                 rc = sysfs_create_file(&bss_hotplug_slot->kobj,
517                                        &sn_slot_path_attr.attr);
518                 if (rc)
519                         goto register_err;
520         }
521         dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
522         return rc;
523
524 register_err:
525         dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
526                 rc);
527
528 alloc_err:
529         if (rc == -ENOMEM)
530                 dev_dbg(pci_bus->self, "Memory allocation error\n");
531
532         /* destroy THIS element */
533         if (bss_hotplug_slot)
534                 sn_release_slot(bss_hotplug_slot);
535
536         /* destroy anything else on the list */
537         while ((bss_hotplug_slot = sn_hp_destroy()))
538                 pci_hp_deregister(bss_hotplug_slot);
539
540         return rc;
541 }
542
543 static int sn_pci_hotplug_init(void)
544 {
545         struct pci_bus *pci_bus = NULL;
546         int rc;
547         int registered = 0;
548
549         if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
550                 printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
551                        __FUNCTION__);
552                 return -EPERM;
553         }
554
555         INIT_LIST_HEAD(&sn_hp_list);
556
557         while ((pci_bus = pci_find_next_bus(pci_bus))) {
558                 if (!pci_bus->sysdata)
559                         continue;
560
561                 rc = sn_pci_bus_valid(pci_bus);
562                 if (rc != 1) {
563                         dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
564                         continue;
565                 }
566                 dev_dbg(pci_bus->self, "valid hotplug bus\n");
567
568                 rc = sn_hotplug_slot_register(pci_bus);
569                 if (!rc) {
570                         registered = 1;
571                 } else {
572                         registered = 0;
573                         break;
574                 }
575         }
576
577         return registered == 1 ? 0 : -ENODEV;
578 }
579
580 static void sn_pci_hotplug_exit(void)
581 {
582         struct hotplug_slot *bss_hotplug_slot;
583
584         while ((bss_hotplug_slot = sn_hp_destroy()))
585                 pci_hp_deregister(bss_hotplug_slot);
586
587         if (!list_empty(&sn_hp_list))
588                 printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
589 }
590
591 module_init(sn_pci_hotplug_init);
592 module_exit(sn_pci_hotplug_exit);