OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [cardbus.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*======================================================================
2
 
3
    Cardbus device configuration
4
 
5
    cardbus.c 1.87 2002/10/24 06:11:41
6
 
7
    The contents of this file are subject to the Mozilla Public
8
    License Version 1.1 (the "License"); you may not use this file
9
    except in compliance with the License. You may obtain a copy of
10
    the License at http://www.mozilla.org/MPL/
11
 
12
    Software distributed under the License is distributed on an "AS
13
    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14
    implied. See the License for the specific language governing
15
    rights and limitations under the License.
16
 
17
    The initial developer of the original code is David A. Hinds
18
    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
19
    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
20
 
21
    Alternatively, the contents of this file may be used under the
22
    terms of the GNU General Public License version 2 (the "GPL"), in which
23
    case the provisions of the GPL are applicable instead of the
24
    above.  If you wish to allow the use of your version of this file
25
    only under the terms of the GPL and not to allow others to use
26
    your version of this file under the MPL, indicate your decision
27
    by deleting the provisions above and replace them with the notice
28
    and other provisions required by the GPL.  If you do not delete
29
    the provisions above, a recipient may use your version of this
30
    file under either the MPL or the GPL.
31
 
32
    These routines handle allocating resources for Cardbus cards, as
33
    well as setting up and shutting down Cardbus sockets.  They are
34
    called from cs.c in response to Request/ReleaseConfiguration and
35
    Request/ReleaseIO calls.
36
 
37
======================================================================*/
38
 
39
/*
40
 * This file is going away.  Cardbus handling has been re-written to be
41
 * more of a PCI bridge thing, and the PCI code basically does all the
42
 * resource handling. This has wrappers to make the rest of the PCMCIA
43
 * subsystem not notice that it's not here any more.
44
 *
45
 *              Linus, Jan 2000
46
 */
47
 
48
 
49
#define __NO_VERSION__
50
 
51
#include <linux/module.h>
52
#include <linux/kernel.h>
53
#include <linux/string.h>
54
#include <linux/slab.h>
55
#include <linux/mm.h>
56
#include <linux/pci.h>
57
#include <linux/ioport.h>
58
#include <asm/irq.h>
59
#include <asm/io.h>
60
 
61
#define IN_CARD_SERVICES
62
#include <pcmcia/version.h>
63
#include <pcmcia/cs_types.h>
64
#include <pcmcia/ss.h>
65
#include <pcmcia/cs.h>
66
#include <pcmcia/bulkmem.h>
67
#include <pcmcia/cistpl.h>
68
#include "cs_internal.h"
69
 
70
#ifdef PCMCIA_DEBUG
71
static int pc_debug = PCMCIA_DEBUG;
72
#endif
73
 
74
/*====================================================================*/
75
 
76
#define FIND_FIRST_BIT(n)       ((n) - ((n) & ((n)-1)))
77
 
78
#define pci_readb               pci_read_config_byte
79
#define pci_writeb              pci_write_config_byte
80
#define pci_readw               pci_read_config_word
81
#define pci_writew              pci_write_config_word
82
#define pci_readl               pci_read_config_dword
83
#define pci_writel              pci_write_config_dword
84
 
85
/* Offsets in the Expansion ROM Image Header */
86
#define ROM_SIGNATURE           0x0000  /* 2 bytes */
87
#define ROM_DATA_PTR            0x0018  /* 2 bytes */
88
 
89
/* Offsets in the CardBus PC Card Data Structure */
90
#define PCDATA_SIGNATURE        0x0000  /* 4 bytes */
91
#define PCDATA_VPD_PTR          0x0008  /* 2 bytes */
92
#define PCDATA_LENGTH           0x000a  /* 2 bytes */
93
#define PCDATA_REVISION         0x000c
94
#define PCDATA_IMAGE_SZ         0x0010  /* 2 bytes */
95
#define PCDATA_ROM_LEVEL        0x0012  /* 2 bytes */
96
#define PCDATA_CODE_TYPE        0x0014
97
#define PCDATA_INDICATOR        0x0015
98
 
99
typedef struct cb_config_t {
100
        struct pci_dev dev;
101
} cb_config_t;
102
 
103
/*=====================================================================
104
 
105
    Expansion ROM's have a special layout, and pointers specify an
106
    image number and an offset within that image.  xlate_rom_addr()
107
    converts an image/offset address to an absolute offset from the
108
    ROM's base address.
109
 
110
=====================================================================*/
111
 
112
static u_int xlate_rom_addr(u_char * b, u_int addr)
113
{
114
        u_int img = 0, ofs = 0, sz;
115
        u_short data;
116
        while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
117
                if (img == (addr >> 28))
118
                        return (addr & 0x0fffffff) + ofs;
119
                data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
120
                sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
121
                            (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
122
                if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
123
                        break;
124
                b += sz;
125
                ofs += sz;
126
                img++;
127
        }
128
        return 0;
129
}
130
 
131
/*=====================================================================
132
 
133
    These are similar to setup_cis_mem and release_cis_mem for 16-bit
134
    cards.  The "result" that is used externally is the cb_cis_virt
135
    pointer in the socket_info_t structure.
136
 
137
=====================================================================*/
138
 
139
void cb_release_cis_mem(socket_info_t * s)
140
{
141
        if (s->cb_cis_virt) {
142
                DEBUG(1, "cs: cb_release_cis_mem()\n");
143
                iounmap(s->cb_cis_virt);
144
                s->cb_cis_virt = NULL;
145
                s->cb_cis_res = 0;
146
        }
147
}
148
 
149
static int cb_setup_cis_mem(socket_info_t * s, struct pci_dev *dev, struct resource *res)
150
{
151
        unsigned int start, size;
152
 
153
        if (res == s->cb_cis_res)
154
                return 0;
155
 
156
        if (s->cb_cis_res)
157
                cb_release_cis_mem(s);
158
 
159
        start = res->start;
160
        size = res->end - start + 1;
161
        s->cb_cis_virt = ioremap(start, size);
162
 
163
        if (!s->cb_cis_virt)
164
                return -1;
165
 
166
        s->cb_cis_res = res;
167
 
168
        return 0;
169
}
170
 
171
/*=====================================================================
172
 
173
    This is used by the CIS processing code to read CIS information
174
    from a CardBus device.
175
 
176
=====================================================================*/
177
 
178
int read_cb_mem(socket_info_t * s, u_char fn, int space,
179
                u_int addr, u_int len, void *ptr)
180
{
181
        struct pci_dev *dev;
182
        struct resource *res;
183
 
184
        DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len);
185
 
186
        if (!s->cb_config)
187
                goto fail;
188
 
189
        dev = &s->cb_config[fn].dev;
190
 
191
        /* Config space? */
192
        if (space == 0) {
193
                if (addr + len > 0x100)
194
                        goto fail;
195
                for (; len; addr++, ptr++, len--)
196
                        pci_readb(dev, addr, (u_char *) ptr);
197
                return 0;
198
        }
199
 
200
        res = dev->resource + space - 1;
201
        if (!res->flags)
202
                goto fail;
203
 
204
        if (cb_setup_cis_mem(s, dev, res) != 0)
205
                goto fail;
206
 
207
        if (space == 7) {
208
                addr = xlate_rom_addr(s->cb_cis_virt, addr);
209
                if (addr == 0)
210
                        goto fail;
211
        }
212
 
213
        if (addr + len > res->end - res->start)
214
                goto fail;
215
 
216
        memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
217
        return 0;
218
 
219
fail:
220
        memset(ptr, 0xff, len);
221
        return -1;
222
}
223
 
224
struct pci_dev *cb_scan_slot(struct pci_dev *temp, struct list_head *list)
225
{
226
        struct pci_dev *dev;
227
        struct pci_dev *first_dev = NULL;
228
        int func = 0;
229
        int is_multi = 0;
230
        u8 hdr_type;
231
 
232
        for (func = 0; func < 8; func++, temp->devfn++) {
233
                if (func && !is_multi)          /* not a multi-function device */
234
                        continue;
235
                if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
236
                        continue;
237
                temp->hdr_type = hdr_type & 0x7f;
238
 
239
                dev = pci_scan_device(temp);
240
                if (!dev)
241
                        continue;
242
                sprintf(dev->name, "PCI device %04x:%04x", dev->vendor, dev->device);
243
                if (!func) {
244
                        is_multi = hdr_type & 0x80;
245
                        first_dev = dev;
246
                }
247
 
248
                list_add_tail(&dev->global_list, list);
249
                /* Fix up broken headers */
250
//FIXME         pci_fixup_device(PCI_FIXUP_HEADER, dev);
251
        }
252
        return first_dev;
253
}
254
 
255
static unsigned int cb_scan_new_bus(struct pci_bus *bus, int irq);
256
 
257
static int cb_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int irq)
258
{
259
        unsigned int buses;
260
        unsigned short cr;
261
        struct pci_bus *child;
262
        int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
263
 
264
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
265
        printk("Scanning behind PCI bridge %s, config %06x\n", dev->slot_name, buses & 0xffffff);
266
        /*
267
         * We need to assign a number to this bus which we always
268
         * do in the second pass. We also keep all address decoders
269
         * on the bridge disabled during scanning.  FIXME: Why?
270
         */
271
        pci_read_config_word(dev, PCI_COMMAND, &cr);
272
        pci_write_config_word(dev, PCI_COMMAND, 0x0000);
273
        pci_write_config_word(dev, PCI_STATUS, 0xffff);
274
 
275
        child = pci_add_new_bus(bus, dev, ++max);
276
        buses = (buses & 0xff000000)
277
              | ((unsigned int)(child->primary)     <<  0)
278
              | ((unsigned int)(child->secondary)   <<  8)
279
              | ((unsigned int)(child->subordinate) << 16);
280
        /*
281
         * We need to blast all three values with a single write.
282
         */
283
        pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
284
        if (!is_cardbus) {
285
                /* Now we can scan all subordinate buses... */
286
                max = cb_scan_new_bus(child, irq);
287
        } else {
288
                /*
289
                 * For CardBus bridges, we leave 4 bus numbers
290
                 * as cards with a PCI-to-PCI bridge can be
291
                 * inserted later.
292
                 */
293
                max += 3;
294
        }
295
        /*
296
         * Set the subordinate bus number to its real value.
297
         */
298
        child->subordinate = max;
299
        pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
300
        pci_write_config_word(dev, PCI_COMMAND, cr);
301
        sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
302
        return max;
303
}
304
 
305
static unsigned int cb_scan_new_bus(struct pci_bus *bus, int irq)
306
{
307
        unsigned int devfn, max;
308
        struct list_head *ln, *ln_tmp;
309
        struct pci_dev *dev, dev0;
310
        struct list_head found;
311
 
312
        INIT_LIST_HEAD(&found);
313
 
314
        printk("Scanning bus %02x\n", bus->number);
315
        max = bus->secondary;
316
 
317
        /* Create a device template */
318
        memset(&dev0, 0, sizeof(dev0));
319
        dev0.bus = bus;
320
        dev0.sysdata = bus->sysdata;
321
 
322
        /* Go find them, Rover! */
323
        for (devfn = 0; devfn < 0x100; devfn += 8) {
324
                dev0.devfn = devfn;
325
                cb_scan_slot(&dev0, &found);
326
        }
327
 
328
        /*
329
         * After performing arch-dependent fixup of the bus, look behind
330
         * all PCI-to-PCI bridges on this bus.
331
         */
332
        printk("Fixups for bus %02x\n", bus->number);
333
        pci_read_bridge_bases(bus);
334
 
335
        list_for_each_safe(ln, ln_tmp, &found)
336
        {
337
                int i;
338
                u8 irq_pin;
339
                dev = pci_dev_g(ln);
340
                pci_set_power_state(dev, 0);
341
                for(i=0;i<6;i++)
342
                {
343
                        struct resource *r = dev->resource + i;
344
                        if(!r->start && r->end)
345
                                pci_assign_resource(dev, i);
346
                }
347
                /* Does this function have an interrupt at all? */
348
                pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
349
                if (irq_pin) {
350
                        dev->irq = irq;
351
                        pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
352
                }
353
 
354
                pci_enable_device(dev); /* XXX check return */
355
                pci_insert_device(dev, bus);
356
                if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
357
                        max = cb_scan_bridge(bus, dev, max, irq);
358
        }
359
 
360
        /*
361
         * We've scanned the bus and so we know all about what's on
362
         * the other side of any bridges that may be on this bus plus
363
         * any devices.
364
         *
365
         * Return how far we've got finding sub-buses.
366
         */
367
        printk("Bus scan for %02x returning with max=%02x\n", bus->number, max);
368
        return max;
369
}
370
 
371
static void program_bridge(struct pci_dev *bridge)
372
{
373
        u32 l;
374
 
375
        /* Set up the top and bottom of the PCI I/O segment for this bus. */
376
        pci_read_config_dword(bridge, PCI_IO_BASE, &l);
377
        l &= 0xffff0000;
378
        l |= (bridge->resource[7].start >> 8) & 0x00f0;
379
        l |= bridge->resource[7].end & 0xf000;
380
        pci_write_config_dword(bridge, PCI_IO_BASE, l);
381
 
382
        /* Clear upper 16 bits of I/O base/limit. */
383
        pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
384
 
385
        /* Clear out the upper 32 bits of PREF base/limit. */
386
        pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
387
        pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
388
 
389
        /* Set up the top and bottom of the PCI Memory segment
390
           for this bus. */
391
        l = (bridge->resource[8].start >> 16) & 0xfff0;
392
        l |= bridge->resource[8].end & 0xfff00000;
393
        pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
394
 
395
        /* Set up PREF base/limit. */
396
        l = (bridge->resource[9].start >> 16) & 0xfff0;
397
        l |= bridge->resource[9].end & 0xfff00000;
398
        pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
399
 
400
        /* FIXME - 0x0c if our ISA VGA is behind it. It looks like X
401
           can handle this itself - CHECK */
402
        l = 0x04;
403
        pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
404
}
405
 
406
 
407
/*=====================================================================
408
 
409
    cb_alloc() and cb_free() allocate and free the kernel data
410
    structures for a Cardbus device, and handle the lowest level PCI
411
    device setup issues.
412
 
413
=====================================================================*/
414
 
415
int cb_alloc(socket_info_t * s)
416
{
417
        struct pci_bus *bus;
418
        struct pci_dev tmp;
419
        u_short vend, v, dev;
420
        u_char i, hdr, fn;
421
        cb_config_t *c;
422
        int irq;
423
 
424
        bus = s->cap.cb_dev->subordinate;
425
        memset(&tmp, 0, sizeof(tmp));
426
        tmp.bus = bus;
427
        tmp.sysdata = bus->sysdata;
428
        tmp.devfn = 0;
429
 
430
        pci_readw(&tmp, PCI_VENDOR_ID, &vend);
431
        pci_readw(&tmp, PCI_DEVICE_ID, &dev);
432
        printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
433
               "device 0x%04x\n", bus->number, vend, dev);
434
 
435
        pci_readb(&tmp, PCI_HEADER_TYPE, &hdr);
436
        fn = 1;
437
        if (hdr & 0x80) {
438
                do {
439
                        tmp.devfn = fn;
440
                        if (pci_readw(&tmp, PCI_VENDOR_ID, &v) || !v || v == 0xffff)
441
                                break;
442
                        fn++;
443
                } while (fn < 8);
444
        }
445
        s->functions = fn;
446
 
447
        c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
448
        if (!c)
449
                return CS_OUT_OF_RESOURCE;
450
        memset(c, 0, fn * sizeof(struct cb_config_t));
451
 
452
        irq = s->cap.pci_irq;
453
        for (i = 0; i < fn; i++) {
454
                struct pci_dev *dev = &c[i].dev;
455
                u8 irq_pin;
456
                int r;
457
 
458
                dev->bus = bus;
459
                dev->sysdata = bus->sysdata;
460
                dev->devfn = i;
461
                dev->vendor = vend;
462
                pci_readw(dev, PCI_DEVICE_ID, &dev->device);
463
                dev->hdr_type = hdr & 0x7f;
464
 
465
                pci_setup_device(dev);
466
 
467
                if(dev->hdr_type == 1)
468
                {
469
                        int max = bus->secondary;
470
                        int idx;
471
                        struct resource *res, *pres;
472
                        printk(KERN_INFO "Cardbus: Bridge found - we suck.\n");
473
                        pci_read_bridge_bases(bus);
474
                        for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_BRIDGE_RESOURCES + 3; idx++) {
475
                                res = &dev->resource[idx];
476
                                /* This is ugly - pci_read_bridge_bases should have
477
                                   done it for us. Need to find out why it doesnt
478
                                   before fixing it */
479
                                if(idx == PCI_BRIDGE_RESOURCES)
480
                                        res->flags = IORESOURCE_IO | PCI_IO_RANGE_TYPE_32;
481
                                if(idx == PCI_BRIDGE_RESOURCES+1)
482
                                        res->flags |= IORESOURCE_MEM;
483
                                if(idx == PCI_BRIDGE_RESOURCES+2)
484
                                        res->flags |= IORESOURCE_MEM|IORESOURCE_PREFETCH;
485
                                /* Ignore any existing values in the chip */
486
                                res->start = 0;
487
                                /* Find the parent resource */
488
                                pres = pci_find_parent_resource(dev, res);
489
                                if(!pres)
490
                                {
491
                                        printk(KERN_ERR "No parent resource for %lx\n", res->flags);
492
                                        continue;
493
                                }
494
                                printk(KERN_ERR "Allocating for type %lx, in bus resource.\n", res->flags);
495
                                /* Hog the entire space */
496
                                res->start = pres->start;
497
                                if(idx != PCI_BRIDGE_RESOURCES)
498
                                        res->end = pres->end;
499
                                else    /* Still working this out - FIXME */
500
                                        res->end = res->start + 255;
501
                                if (!pres || request_resource(pres, res) < 0)
502
                                        printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
503
                        }
504
                        program_bridge(dev);
505
                        max = cb_scan_bridge(bus, dev, max, irq);
506
                        printk(KERN_INFO "Cardbus: Bridge scanned.\n");
507
                }
508
                else
509
                {
510
                        /* FIXME: Do we need to enable the expansion ROM? */
511
                        for (r = 0; r < 7; r++) {
512
                                struct resource *res = dev->resource + r;
513
                                if (res->flags)
514
                                        pci_assign_resource(dev, r);
515
                        }
516
                }
517
                /* Does this function have an interrupt at all? */
518
                pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
519
                if (irq_pin) {
520
                        dev->irq = irq;
521
                        pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
522
                }
523
 
524
                pci_enable_device(dev); /* XXX check return */
525
                pci_insert_device(dev, bus);
526
        }
527
 
528
        s->cb_config = c;
529
        s->irq.AssignedIRQ = irq;
530
        return CS_SUCCESS;
531
}
532
 
533
void cb_free(socket_info_t * s)
534
{
535
        cb_config_t *c = s->cb_config;
536
 
537
        if (c) {
538
                int i;
539
 
540
                s->cb_config = NULL;
541
                for (i = 0 ; i < s->functions ; i++)
542
                        pci_remove_device(&c[i].dev);
543
 
544
                kfree(c);
545
                printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
546
        }
547
}
548
 
549
/*=====================================================================
550
 
551
    cb_config() has the job of allocating all system resources that
552
    a Cardbus card requires.  Rather than using the CIS (which seems
553
    to not always be present), it treats the card as an ordinary PCI
554
    device, and probes the base address registers to determine each
555
    function's IO and memory space needs.
556
 
557
    It is called from the RequestIO card service.
558
 
559
======================================================================*/
560
 
561
int cb_config(socket_info_t * s)
562
{
563
        return CS_SUCCESS;
564
}
565
 
566
/*======================================================================
567
 
568
    cb_release() releases all the system resources (IO and memory
569
    space, and interrupt) committed for a Cardbus card by a prior call
570
    to cb_config().
571
 
572
    It is called from the ReleaseIO() service.
573
 
574
======================================================================*/
575
 
576
void cb_release(socket_info_t * s)
577
{
578
        DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
579
}
580
 
581
/*=====================================================================
582
 
583
    cb_enable() has the job of configuring a socket for a Cardbus
584
    card, and initializing the card's PCI configuration registers.
585
 
586
    It first sets up the Cardbus bridge windows, for IO and memory
587
    accesses.  Then, it initializes each card function's base address
588
    registers, interrupt line register, and command register.
589
 
590
    It is called as part of the RequestConfiguration card service.
591
    It should be called after a previous call to cb_config() (via the
592
    RequestIO service).
593
 
594
======================================================================*/
595
 
596
void cb_enable(socket_info_t * s)
597
{
598
        struct pci_dev *dev;
599
        u_char i;
600
 
601
        DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number);
602
 
603
        /* Configure bridge */
604
        cb_release_cis_mem(s);
605
 
606
        /* Set up PCI interrupt and command registers */
607
        for (i = 0; i < s->functions; i++) {
608
                dev = &s->cb_config[i].dev;
609
                pci_writeb(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
610
                           PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
611
                pci_writeb(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
612
        }
613
 
614
        if (s->irq.AssignedIRQ) {
615
                for (i = 0; i < s->functions; i++) {
616
                        dev = &s->cb_config[i].dev;
617
                        pci_writeb(dev, PCI_INTERRUPT_LINE, s->irq.AssignedIRQ);
618
                }
619
                s->socket.io_irq = s->irq.AssignedIRQ;
620
                s->ss_entry->set_socket(s->sock, &s->socket);
621
        }
622
}
623
 
624
/*======================================================================
625
 
626
    cb_disable() unconfigures a Cardbus card previously set up by
627
    cb_enable().
628
 
629
    It is called from the ReleaseConfiguration service.
630
 
631
======================================================================*/
632
 
633
void cb_disable(socket_info_t * s)
634
{
635
        DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
636
 
637
        /* Turn off bridge windows */
638
        cb_release_cis_mem(s);
639
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.