ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / pci / hotplug / cpci_hotplug_pci.c
1 /*
2  * CompactPCI Hot Plug Driver PCI functions
3  *
4  * Copyright (C) 2002 by SOMA Networks, Inc.
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16  * NON INFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send feedback to <scottm@somanetworks.com>
24  */
25
26 #include <linux/config.h>
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/pci.h>
30 #include <linux/proc_fs.h>
31 #include "../pci.h"
32 #include "pci_hotplug.h"
33 #include "cpci_hotplug.h"
34
35 #if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
36 #define MY_NAME "cpci_hotplug"
37 #else
38 #define MY_NAME THIS_MODULE->name
39 #endif
40
41 extern int cpci_debug;
42
43 #define dbg(format, arg...)                                     \
44         do {                                                    \
45                 if(cpci_debug)                                  \
46                         printk (KERN_DEBUG "%s: " format "\n",  \
47                                 MY_NAME , ## arg);              \
48         } while(0)
49 #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
50 #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
51 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
52
53 #define ROUND_UP(x, a)          (((x) + (a) - 1) & ~((a) - 1))
54
55
56 u8 cpci_get_attention_status(struct slot* slot)
57 {
58         int hs_cap;
59         u16 hs_csr;
60
61         hs_cap = pci_bus_find_capability(slot->bus,
62                                          slot->devfn,
63                                          PCI_CAP_ID_CHSWP);
64         if(!hs_cap) {
65                 return 0;
66         }
67
68         if(pci_bus_read_config_word(slot->bus,
69                                      slot->devfn,
70                                      hs_cap + 2,
71                                      &hs_csr)) {
72                 return 0;
73         }
74         return hs_csr & 0x0008 ? 1 : 0;
75 }
76
77 int cpci_set_attention_status(struct slot* slot, int status)
78 {
79         int hs_cap;
80         u16 hs_csr;
81
82         hs_cap = pci_bus_find_capability(slot->bus,
83                                          slot->devfn,
84                                          PCI_CAP_ID_CHSWP);
85         if(!hs_cap) {
86                 return 0;
87         }
88
89         if(pci_bus_read_config_word(slot->bus,
90                                      slot->devfn,
91                                      hs_cap + 2,
92                                      &hs_csr)) {
93                 return 0;
94         }
95         if(status) {
96                 hs_csr |= HS_CSR_LOO;
97         } else {
98                 hs_csr &= ~HS_CSR_LOO;
99         }
100         if(pci_bus_write_config_word(slot->bus,
101                                       slot->devfn,
102                                       hs_cap + 2,
103                                       hs_csr)) {
104                 return 0;
105         }
106         return 1;
107 }
108
109 u16 cpci_get_hs_csr(struct slot* slot)
110 {
111         int hs_cap;
112         u16 hs_csr;
113
114         hs_cap = pci_bus_find_capability(slot->bus,
115                                          slot->devfn,
116                                          PCI_CAP_ID_CHSWP);
117         if(!hs_cap) {
118                 return 0xFFFF;
119         }
120
121         if(pci_bus_read_config_word(slot->bus,
122                                      slot->devfn,
123                                      hs_cap + 2,
124                                      &hs_csr)) {
125                 return 0xFFFF;
126         }
127         return hs_csr;
128 }
129
130 u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
131 {
132         int hs_cap;
133         u16 new_hs_csr;
134
135         hs_cap = pci_bus_find_capability(slot->bus,
136                                          slot->devfn,
137                                          PCI_CAP_ID_CHSWP);
138         if(!hs_cap) {
139                 return 0xFFFF;
140         }
141
142         /* Write out the new value */
143         if(pci_bus_write_config_word(slot->bus,
144                                       slot->devfn,
145                                       hs_cap + 2,
146                                       hs_csr)) {
147                 return 0xFFFF;
148         }
149
150         /* Read back what we just wrote out */
151         if(pci_bus_read_config_word(slot->bus,
152                                      slot->devfn,
153                                      hs_cap + 2,
154                                      &new_hs_csr)) {
155                 return 0xFFFF;
156         }
157         return new_hs_csr;
158 }
159
160 int cpci_check_and_clear_ins(struct slot* slot)
161 {
162         int hs_cap;
163         u16 hs_csr;
164         int ins = 0;
165
166         hs_cap = pci_bus_find_capability(slot->bus,
167                                          slot->devfn,
168                                          PCI_CAP_ID_CHSWP);
169         if(!hs_cap) {
170                 return 0;
171         }
172         if(pci_bus_read_config_word(slot->bus,
173                                      slot->devfn,
174                                      hs_cap + 2,
175                                      &hs_csr)) {
176                 return 0;
177         }
178         if(hs_csr & HS_CSR_INS) {
179                 /* Clear INS (by setting it) */
180                 if(pci_bus_write_config_word(slot->bus,
181                                               slot->devfn,
182                                               hs_cap + 2,
183                                               hs_csr)) {
184                         ins = 0;
185                 }
186                 ins = 1;
187         }
188         return ins;
189 }
190
191 int cpci_check_ext(struct slot* slot)
192 {
193         int hs_cap;
194         u16 hs_csr;
195         int ext = 0;
196
197         hs_cap = pci_bus_find_capability(slot->bus,
198                                          slot->devfn,
199                                          PCI_CAP_ID_CHSWP);
200         if(!hs_cap) {
201                 return 0;
202         }
203         if(pci_bus_read_config_word(slot->bus,
204                                      slot->devfn,
205                                      hs_cap + 2,
206                                      &hs_csr)) {
207                 return 0;
208         }
209         if(hs_csr & HS_CSR_EXT) {
210                 ext = 1;
211         }
212         return ext;
213 }
214
215 int cpci_clear_ext(struct slot* slot)
216 {
217         int hs_cap;
218         u16 hs_csr;
219
220         hs_cap = pci_bus_find_capability(slot->bus,
221                                          slot->devfn,
222                                          PCI_CAP_ID_CHSWP);
223         if(!hs_cap) {
224                 return -ENODEV;
225         }
226         if(pci_bus_read_config_word(slot->bus,
227                                      slot->devfn,
228                                      hs_cap + 2,
229                                      &hs_csr)) {
230                 return -ENODEV;
231         }
232         if(hs_csr & HS_CSR_EXT) {
233                 /* Clear EXT (by setting it) */
234                 if(pci_bus_write_config_word(slot->bus,
235                                               slot->devfn,
236                                               hs_cap + 2,
237                                               hs_csr)) {
238                         return -ENODEV;
239                 }
240         }
241         return 0;
242 }
243
244 int cpci_led_on(struct slot* slot)
245 {
246         int hs_cap;
247         u16 hs_csr;
248
249         hs_cap = pci_bus_find_capability(slot->bus,
250                                          slot->devfn,
251                                          PCI_CAP_ID_CHSWP);
252         if(!hs_cap) {
253                 return -ENODEV;
254         }
255         if(pci_bus_read_config_word(slot->bus,
256                                      slot->devfn,
257                                      hs_cap + 2,
258                                      &hs_csr)) {
259                 return -ENODEV;
260         }
261         if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
262                 /* Set LOO */
263                 hs_csr |= HS_CSR_LOO;
264                 if(pci_bus_write_config_word(slot->bus,
265                                               slot->devfn,
266                                               hs_cap + 2,
267                                               hs_csr)) {
268                         err("Could not set LOO for slot %s",
269                             slot->hotplug_slot->name);
270                         return -ENODEV;
271                 }
272         }
273         return 0;
274 }
275
276 int cpci_led_off(struct slot* slot)
277 {
278         int hs_cap;
279         u16 hs_csr;
280
281         hs_cap = pci_bus_find_capability(slot->bus,
282                                          slot->devfn,
283                                          PCI_CAP_ID_CHSWP);
284         if(!hs_cap) {
285                 return -ENODEV;
286         }
287         if(pci_bus_read_config_word(slot->bus,
288                                      slot->devfn,
289                                      hs_cap + 2,
290                                      &hs_csr)) {
291                 return -ENODEV;
292         }
293         if(hs_csr & HS_CSR_LOO) {
294                 /* Clear LOO */
295                 hs_csr &= ~HS_CSR_LOO;
296                 if(pci_bus_write_config_word(slot->bus,
297                                               slot->devfn,
298                                               hs_cap + 2,
299                                               hs_csr)) {
300                         err("Could not clear LOO for slot %s",
301                             slot->hotplug_slot->name);
302                         return -ENODEV;
303                 }
304         }
305         return 0;
306 }
307
308
309 /*
310  * Device configuration functions
311  */
312
313 static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
314 {
315         u8 irq_pin;
316         int r;
317
318         dbg("%s - enter", __FUNCTION__);
319
320         /* NOTE: device already setup from prior scan */
321
322         /* FIXME: How would we know if we need to enable the expansion ROM? */
323         pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
324
325         /* Assign resources */
326         dbg("assigning resources for %02x:%02x.%x",
327             dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
328         for (r = 0; r < 6; r++) {
329                 struct resource *res = dev->resource + r;
330                 if(res->flags)
331                         pci_assign_resource(dev, r);
332         }
333         dbg("finished assigning resources for %02x:%02x.%x",
334             dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
335
336         /* Does this function have an interrupt at all? */
337         dbg("checking for function interrupt");
338         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
339         if(irq_pin) {
340                 dbg("function uses interrupt pin %d", irq_pin);
341         }
342
343         /*
344          * Need to explicitly set irq field to 0 so that it'll get assigned
345          * by the pcibios platform dependent code called by pci_enable_device.
346          */
347         dev->irq = 0;
348
349         dbg("enabling device");
350         pci_enable_device(dev); /* XXX check return */
351         dbg("now dev->irq = %d", dev->irq);
352         if(irq_pin && dev->irq) {
353                 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
354         }
355
356         /* Can't use pci_insert_device at the moment, do it manually for now */
357         pci_proc_attach_device(dev);
358         dbg("notifying drivers");
359         //pci_announce_device_to_drivers(dev);
360         dbg("%s - exit", __FUNCTION__);
361         return 0;
362 }
363
364 static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
365 {
366         int rc;
367         struct pci_bus* child;
368         struct resource* r;
369         u8 max, n;
370         u16 command;
371
372         dbg("%s - enter", __FUNCTION__);
373
374         /* Do basic bridge initialization */
375         rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
376         if(rc) {
377                 printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
378         }
379         rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
380         if(rc) {
381                 printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
382         }
383         rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
384         if(rc) {
385                 printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
386         }
387
388         /*
389          * Set parent bridge's subordinate field so that configuration space
390          * access will work in pci_scan_bridge and friends.
391          */
392         max = pci_max_busnr();
393         bus->subordinate = max + 1;
394         pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
395
396         /* Scan behind bridge */
397         n = pci_scan_bridge(bus, dev, max, 2);
398         child = pci_find_bus(0, max + 1);
399         if (!child)
400                 return -ENODEV;
401         pci_proc_attach_bus(child);
402
403         /*
404          * Update parent bridge's subordinate field if there were more bridges
405          * behind the bridge that was scanned.
406          */
407         if(n > max) {
408                 bus->subordinate = n;
409                 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
410         }
411
412         /*
413          * Update the bridge resources of the bridge to accommodate devices
414          * behind it.
415          */
416         pci_bus_size_bridges(child);
417         pci_bus_assign_resources(child);
418
419         /* Enable resource mapping via command register */
420         command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
421         r = child->resource[0];
422         if(r && r->start) {
423                 command |= PCI_COMMAND_IO;
424         }
425         r = child->resource[1];
426         if(r && r->start) {
427                 command |= PCI_COMMAND_MEMORY;
428         }
429         r = child->resource[2];
430         if(r && r->start) {
431                 command |= PCI_COMMAND_MEMORY;
432         }
433         rc = pci_write_config_word(dev, PCI_COMMAND, command);
434         if(rc) {
435                 err("Error setting command register");
436                 return rc;
437         }
438
439         /* Set bridge control register */
440         command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
441         rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
442         if(rc) {
443                 err("Error setting bridge control register");
444                 return rc;
445         }
446         dbg("%s - exit", __FUNCTION__);
447         return 0;
448 }
449
450 static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
451                                    struct pci_bus_wrapped *wrapped_bus)
452 {
453         int rc;
454         struct pci_dev *dev = wrapped_dev->dev;
455         struct pci_bus *bus = wrapped_bus->bus;
456         struct slot* slot;
457
458         dbg("%s - enter", __FUNCTION__);
459
460         /*
461          * We need to fix up the hotplug representation with the Linux
462          * representation.
463          */
464         if(wrapped_dev->data) {
465                 slot = (struct slot*) wrapped_dev->data;
466                 slot->dev = dev;
467         }
468
469         /* If it's a bridge, scan behind it for devices */
470         if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
471                 rc = cpci_configure_bridge(bus, dev);
472                 if(rc)
473                         return rc;
474         }
475
476         /* Actually configure device */
477         if(dev) {
478                 rc = cpci_configure_dev(bus, dev);
479                 if(rc)
480                         return rc;
481         }
482         dbg("%s - exit", __FUNCTION__);
483         return 0;
484 }
485
486 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
487                                             struct pci_bus_wrapped *wrapped_bus)
488 {
489         struct pci_dev *dev = wrapped_dev->dev;
490         struct slot* slot;
491
492         dbg("%s - enter", __FUNCTION__);
493         if(!dev)
494                 return -ENODEV;
495
496         /* Remove the Linux representation */
497         if(pci_remove_device_safe(dev)) {
498                 err("Could not remove device\n");
499                 return -1;
500         }
501
502         /*
503          * Now remove the hotplug representation.
504          */
505         if(wrapped_dev->data) {
506                 slot = (struct slot*) wrapped_dev->data;
507                 slot->dev = NULL;
508         } else {
509                 dbg("No hotplug representation for %02x:%02x.%x",
510                     dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
511         }
512         dbg("%s - exit", __FUNCTION__);
513         return 0;
514 }
515
516 static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
517                                             struct pci_dev_wrapped *wrapped_dev)
518 {
519         struct pci_bus *bus = wrapped_bus->bus;
520         struct pci_bus *parent = bus->self->bus;
521
522         dbg("%s - enter", __FUNCTION__);
523
524         /* The cleanup code for proc entries regarding buses should be in the kernel... */
525         if(bus->procdir)
526                 dbg("detach_pci_bus %s", bus->procdir->name);
527         pci_proc_detach_bus(bus);
528
529         /* The cleanup code should live in the kernel... */
530         bus->self->subordinate = NULL;
531
532         /* unlink from parent bus */
533         list_del(&bus->node);
534
535         /* Now, remove */
536         if(bus)
537                 kfree(bus);
538
539         /* Update parent's subordinate field */
540         if(parent) {
541                 u8 n = pci_bus_max_busnr(parent);
542                 if(n < parent->subordinate) {
543                         parent->subordinate = n;
544                         pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
545                 }
546         }
547         dbg("%s - exit", __FUNCTION__);
548         return 0;
549 }
550
551 static struct pci_visit configure_functions = {
552         .visit_pci_dev = configure_visit_pci_dev,
553 };
554
555 static struct pci_visit unconfigure_functions_phase2 = {
556         .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
557         .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
558 };
559
560
561 int cpci_configure_slot(struct slot* slot)
562 {
563         int rc = 0;
564
565         dbg("%s - enter", __FUNCTION__);
566
567         if(slot->dev == NULL) {
568                 dbg("pci_dev null, finding %02x:%02x:%x",
569                     slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
570                 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
571         }
572
573         /* Still NULL? Well then scan for it! */
574         if(slot->dev == NULL) {
575                 int n;
576                 dbg("pci_dev still null");
577
578                 /*
579                  * This will generate pci_dev structures for all functions, but
580                  * we will only call this case when lookup fails.
581                  */
582                 n = pci_scan_slot(slot->bus, slot->devfn);
583                 dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
584                 if(n > 0)
585                         pci_bus_add_devices(slot->bus);
586                 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
587                 if(slot->dev == NULL) {
588                         err("Could not find PCI device for slot %02x", slot->number);
589                         return 0;
590                 }
591         }
592         dbg("slot->dev = %p", slot->dev);
593         if(slot->dev) {
594                 struct pci_dev *dev;
595                 struct pci_dev_wrapped wrapped_dev;
596                 struct pci_bus_wrapped wrapped_bus;
597                 int i;
598
599                 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
600                 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
601
602                 for (i = 0; i < 8; i++) {
603                         dev = pci_find_slot(slot->bus->number,
604                                             PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
605                         if(!dev)
606                                 continue;
607                         wrapped_dev.dev = dev;
608                         wrapped_bus.bus = slot->dev->bus;
609                         if(i)
610                                 wrapped_dev.data = NULL;
611                         else
612                                 wrapped_dev.data = (void*) slot;
613                         rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
614                 }
615         }
616
617         dbg("%s - exit, rc = %d", __FUNCTION__, rc);
618         return rc;
619 }
620
621 int cpci_unconfigure_slot(struct slot* slot)
622 {
623         int rc = 0;
624         int i;
625         struct pci_dev_wrapped wrapped_dev;
626         struct pci_bus_wrapped wrapped_bus;
627         struct pci_dev *dev;
628
629         dbg("%s - enter", __FUNCTION__);
630
631         if(!slot->dev) {
632                 err("No device for slot %02x\n", slot->number);
633                 return -ENODEV;
634         }
635
636         memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
637         memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
638
639         for (i = 0; i < 8; i++) {
640                 dev = pci_find_slot(slot->bus->number,
641                                     PCI_DEVFN(PCI_SLOT(slot->devfn), i));
642                 if(dev) {
643                         wrapped_dev.dev = dev;
644                         wrapped_bus.bus = dev->bus;
645                         if(i)
646                                 wrapped_dev.data = NULL;
647                         else
648                                 wrapped_dev.data = (void*) slot;
649                         dbg("%s - unconfigure phase 2", __FUNCTION__);
650                         rc = pci_visit_dev(&unconfigure_functions_phase2,
651                                            &wrapped_dev,
652                                            &wrapped_bus);
653                         if(rc)
654                                 break;
655                 }
656         }
657         dbg("%s - exit, rc = %d", __FUNCTION__, rc);
658         return rc;
659 }