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