linux/arch/arm26/kernel/ecard.c History
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm26/kernel/ecard.c
   3 *
   4 *  Copyright 1995-2001 Russell King
   5 *  Copyright 2003 Ian Molton
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 *  Find all installed expansion cards, and handle interrupts from them.
  12 *
  13 *  Created from information from Acorns RiscOS3 PRMs
  14 *  15-Jun-2003 IM      Modified from ARM32 (RiscPC capable) version
  15 *  10-Jan-1999 RMK     Run loaders in a simulated RISC OS environment.
  16 *  06-May-1997 RMK     Added blacklist for cards whose loader doesn't work.
  17 *  12-Sep-1997 RMK     Created new handling of interrupt enables/disables
  18 *                      - cards can now register their own routine to control
  19 *                      interrupts (recommended).
  20 *  29-Sep-1997 RMK     Expansion card interrupt hardware not being re-enabled
  21 *                      on reset from Linux. (Caused cards not to respond
  22 *                      under RiscOS without hard reset).
  23 *
  24 */
  25#define ECARD_C
  26
  27#include <linux/config.h>
  28#include <linux/module.h>
  29#include <linux/kernel.h>
  30#include <linux/types.h>
  31#include <linux/sched.h>
  32#include <linux/interrupt.h>
  33#include <linux/reboot.h>
  34#include <linux/mm.h>
  35#include <linux/slab.h>
  36#include <linux/proc_fs.h>
  37#include <linux/device.h>
  38#include <linux/init.h>
  39
  40#include <asm/dma.h>
  41#include <asm/ecard.h>
  42#include <asm/hardware.h>
  43#include <asm/io.h>
  44#include <asm/irq.h>
  45#include <asm/mmu_context.h>
  46#include <asm/irqchip.h>
  47#include <asm/tlbflush.h>
  48
  49enum req {
  50        req_readbytes,
  51        req_reset
  52};
  53
  54struct ecard_request {
  55        enum req        req;
  56        ecard_t         *ec;
  57        unsigned int    address;
  58        unsigned int    length;
  59        unsigned int    use_loader;
  60        void            *buffer;
  61};
  62
  63struct expcard_blacklist {
  64        unsigned short   manufacturer;
  65        unsigned short   product;
  66        const char      *type;
  67};
  68
  69static ecard_t *cards;
  70static ecard_t *slot_to_expcard[MAX_ECARDS];
  71static unsigned int ectcr;
  72
  73/* List of descriptions of cards which don't have an extended
  74 * identification, or chunk directories containing a description.
  75 */
  76static struct expcard_blacklist __initdata blacklist[] = {
  77        { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
  78};
  79
  80asmlinkage extern int
  81ecard_loader_reset(volatile unsigned char *pa, loader_t loader);
  82asmlinkage extern int
  83ecard_loader_read(int off, volatile unsigned char *pa, loader_t loader);
  84
  85static const struct ecard_id *
  86ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec);
  87
  88static inline unsigned short
  89ecard_getu16(unsigned char *v)
  90{
  91        return v[0] | v[1] << 8;
  92}
  93
  94static inline signed long
  95ecard_gets24(unsigned char *v)
  96{
  97        return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
  98}
  99
 100static inline ecard_t *
 101slot_to_ecard(unsigned int slot)
 102{
 103        return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
 104}
 105
 106/* ===================== Expansion card daemon ======================== */
 107/*
 108 * Since the loader programs on the expansion cards need to be run
 109 * in a specific environment, create a separate task with this
 110 * environment up, and pass requests to this task as and when we
 111 * need to.
 112 *
 113 * This should allow 99% of loaders to be called from Linux.
 114 *
 115 * From a security standpoint, we trust the card vendors.  This
 116 * may be a misplaced trust.
 117 */
 118#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
 119#define POD_INT_ADDR(x) ((volatile unsigned char *)\
 120                         ((BUS_ADDR((x)) - IO_BASE) + IO_START))
 121
 122static inline void ecard_task_reset(struct ecard_request *req)
 123{
 124        struct expansion_card *ec = req->ec;
 125        if (ec->loader)
 126                ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader);
 127}
 128
 129static void
 130ecard_task_readbytes(struct ecard_request *req)
 131{
 132        unsigned char *buf = (unsigned char *)req->buffer;
 133        volatile unsigned char *base_addr =
 134                (volatile unsigned char *)POD_INT_ADDR(req->ec->podaddr);
 135        unsigned int len = req->length;
 136        unsigned int off = req->address;
 137
 138        if (!req->use_loader || !req->ec->loader) {
 139                off *= 4;
 140                while (len--) {
 141                        *buf++ = base_addr[off];
 142                        off += 4;
 143                }
 144        } else {
 145                while(len--) {
 146                        /*
 147                         * The following is required by some
 148                         * expansion card loader programs.
 149                         */
 150                        *(unsigned long *)0x108 = 0;
 151                        *buf++ = ecard_loader_read(off++, base_addr,
 152                                                   req->ec->loader);
 153                }
 154        }
 155}
 156
 157static void ecard_do_request(struct ecard_request *req)
 158{
 159        switch (req->req) {
 160        case req_readbytes:
 161                ecard_task_readbytes(req);
 162                break;
 163
 164        case req_reset:
 165                ecard_task_reset(req);
 166                break;
 167        }
 168}
 169
 170/*
 171 * On 26-bit processors, we don't need the kcardd thread to access the
 172 * expansion card loaders.  We do it directly.
 173 */
 174#define ecard_call(req) ecard_do_request(req)
 175
 176/* ======================= Mid-level card control ===================== */
 177
 178static void
 179ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
 180{
 181        struct ecard_request req;
 182
 183        req.req         = req_readbytes;
 184        req.ec          = ec;
 185        req.address     = off;
 186        req.length      = len;
 187        req.use_loader  = useld;
 188        req.buffer      = addr;
 189
 190        ecard_call(&req);
 191}
 192
 193int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
 194{
 195        struct ex_chunk_dir excd;
 196        int index = 16;
 197        int useld = 0;
 198
 199        if (!ec->cid.cd)
 200                return 0;
 201
 202        while(1) {
 203                ecard_readbytes(&excd, ec, index, 8, useld);
 204                index += 8;
 205                if (c_id(&excd) == 0) {
 206                        if (!useld && ec->loader) {
 207                                useld = 1;
 208                                index = 0;
 209                                continue;
 210                        }
 211                        return 0;
 212                }
 213                if (c_id(&excd) == 0xf0) { /* link */
 214                        index = c_start(&excd);
 215                        continue;
 216                }
 217                if (c_id(&excd) == 0x80) { /* loader */
 218                        if (!ec->loader) {
 219                                ec->loader = (loader_t)kmalloc(c_len(&excd),
 220                                                               GFP_KERNEL);
 221                                if (ec->loader)
 222                                        ecard_readbytes(ec->loader, ec,
 223                                                        (int)c_start(&excd),
 224                                                        c_len(&excd), useld);
 225                                else
 226                                        return 0;
 227                        }
 228                        continue;
 229                }
 230                if (c_id(&excd) == id && num-- == 0)
 231                        break;
 232        }
 233
 234        if (c_id(&excd) & 0x80) {
 235                switch (c_id(&excd) & 0x70) {
 236                case 0x70:
 237                        ecard_readbytes((unsigned char *)excd.d.string, ec,
 238                                        (int)c_start(&excd), c_len(&excd),
 239                                        useld);
 240                        break;
 241                case 0x00:
 242                        break;
 243                }
 244        }
 245        cd->start_offset = c_start(&excd);
 246        memcpy(cd->d.string, excd.d.string, 256);
 247        return 1;
 248}
 249
 250/* ======================= Interrupt control ============================ */
 251
 252static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
 253{
 254}
 255
 256static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
 257{
 258}
 259
 260static int ecard_def_irq_pending(ecard_t *ec)
 261{
 262        return !ec->irqmask || ec->irqaddr[0] & ec->irqmask;
 263}
 264
 265static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
 266{
 267        panic("ecard_def_fiq_enable called - impossible");
 268}
 269
 270static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
 271{
 272        panic("ecard_def_fiq_disable called - impossible");
 273}
 274
 275static int ecard_def_fiq_pending(ecard_t *ec)
 276{
 277        return !ec->fiqmask || ec->fiqaddr[0] & ec->fiqmask;
 278}
 279
 280static expansioncard_ops_t ecard_default_ops = {
 281        ecard_def_irq_enable,
 282        ecard_def_irq_disable,
 283        ecard_def_irq_pending,
 284        ecard_def_fiq_enable,
 285        ecard_def_fiq_disable,
 286        ecard_def_fiq_pending
 287};
 288
 289/*
 290 * Enable and disable interrupts from expansion cards.
 291 * (interrupts are disabled for these functions).
 292 *
 293 * They are not meant to be called directly, but via enable/disable_irq.
 294 */
 295static void ecard_irq_unmask(unsigned int irqnr)
 296{
 297        ecard_t *ec = slot_to_ecard(irqnr - 32);
 298
 299        if (ec) {
 300                if (!ec->ops)
 301                        ec->ops = &ecard_default_ops;
 302
 303                if (ec->claimed && ec->ops->irqenable)
 304                        ec->ops->irqenable(ec, irqnr);
 305                else
 306                        printk(KERN_ERR "ecard: rejecting request to "
 307                                "enable IRQs for %d\n", irqnr);
 308        }
 309}
 310
 311static void ecard_irq_mask(unsigned int irqnr)
 312{
 313        ecard_t *ec = slot_to_ecard(irqnr - 32);
 314
 315        if (ec) {
 316                if (!ec->ops)
 317                        ec->ops = &ecard_default_ops;
 318
 319                if (ec->ops && ec->ops->irqdisable)
 320                        ec->ops->irqdisable(ec, irqnr);
 321        }
 322}
 323
 324static struct irqchip ecard_chip = {
 325        .ack    = ecard_irq_mask,
 326        .mask   = ecard_irq_mask,
 327        .unmask = ecard_irq_unmask,
 328};
 329
 330void ecard_enablefiq(unsigned int fiqnr)
 331{
 332        ecard_t *ec = slot_to_ecard(fiqnr);
 333
 334        if (ec) {
 335                if (!ec->ops)
 336                        ec->ops = &ecard_default_ops;
 337
 338                if (ec->claimed && ec->ops->fiqenable)
 339                        ec->ops->fiqenable(ec, fiqnr);
 340                else
 341                        printk(KERN_ERR "ecard: rejecting request to "
 342                                "enable FIQs for %d\n", fiqnr);
 343        }
 344}
 345
 346void ecard_disablefiq(unsigned int fiqnr)
 347{
 348        ecard_t *ec = slot_to_ecard(fiqnr);
 349
 350        if (ec) {
 351                if (!ec->ops)
 352                        ec->ops = &ecard_default_ops;
 353
 354                if (ec->ops->fiqdisable)
 355                        ec->ops->fiqdisable(ec, fiqnr);
 356        }
 357}
 358
 359static void
 360ecard_dump_irq_state(ecard_t *ec)
 361{
 362        printk("  %d: %sclaimed, ",
 363               ec->slot_no,
 364               ec->claimed ? "" : "not ");
 365
 366        if (ec->ops && ec->ops->irqpending &&
 367            ec->ops != &ecard_default_ops)
 368                printk("irq %spending\n",
 369                       ec->ops->irqpending(ec) ? "" : "not ");
 370        else
 371                printk("irqaddr %p, mask = %02X, status = %02X\n",
 372                       ec->irqaddr, ec->irqmask, *ec->irqaddr);
 373}
 374
 375static void ecard_check_lockup(struct irqdesc *desc)
 376{
 377        static int last, lockup;
 378        ecard_t *ec;
 379
 380        /*
 381         * If the timer interrupt has not run since the last million
 382         * unrecognised expansion card interrupts, then there is
 383         * something seriously wrong.  Disable the expansion card
 384         * interrupts so at least we can continue.
 385         *
 386         * Maybe we ought to start a timer to re-enable them some time
 387         * later?
 388         */
 389        if (last == jiffies) {
 390                lockup += 1;
 391                if (lockup > 1000000) {
 392                        printk(KERN_ERR "\nInterrupt lockup detected - "
 393                               "disabling all expansion card interrupts\n");
 394
 395                        desc->chip->mask(IRQ_EXPANSIONCARD);
 396
 397                        printk("Expansion card IRQ state:\n");
 398
 399                        for (ec = cards; ec; ec = ec->next)
 400                                ecard_dump_irq_state(ec);
 401                }
 402        } else
 403                lockup = 0;
 404
 405        /*
 406         * If we did not recognise the source of this interrupt,
 407         * warn the user, but don't flood the user with these messages.
 408         */
 409        if (!last || time_after(jiffies, (unsigned long)(last + 5*HZ))) {
 410                last = jiffies;
 411                printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
 412        }
 413}
 414
 415static void
 416ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 417{
 418        ecard_t *ec;
 419        int called = 0;
 420
 421        desc->chip->mask(irq);
 422        for (ec = cards; ec; ec = ec->next) {
 423                int pending;
 424
 425                if (!ec->claimed || ec->irq == NO_IRQ)
 426                        continue;
 427
 428                if (ec->ops && ec->ops->irqpending)
 429                        pending = ec->ops->irqpending(ec);
 430                else
 431                        pending = ecard_default_ops.irqpending(ec);
 432
 433                if (pending) {
 434                        struct irqdesc *d = irq_desc + ec->irq;
 435                        d->handle(ec->irq, d, regs);
 436                        called ++;
 437                }
 438        }
 439        desc->chip->unmask(irq);
 440
 441        if (called == 0)
 442                ecard_check_lockup(desc);
 443}
 444
 445#define ecard_irqexp_handler NULL
 446#define ecard_probeirqhw() (0)
 447
 448unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
 449{
 450        unsigned long address = 0;
 451        int slot = ec->slot_no;
 452
 453        ectcr &= ~(1 << slot);
 454
 455        switch (type) {
 456        case ECARD_MEMC:
 457                address = IO_EC_MEMC_BASE + (slot << 12);
 458                break;
 459
 460        case ECARD_IOC:
 461                address = IO_EC_IOC_BASE + (slot << 12) + (speed << 17);
 462                break;
 463
 464        default:
 465                break;
 466        }
 467
 468        return address;
 469}
 470
 471static int ecard_prints(char *buffer, ecard_t *ec)
 472{
 473        char *start = buffer;
 474
 475        buffer += sprintf(buffer, "  %d: ", ec->slot_no);
 476
 477        if (ec->cid.id == 0) {
 478                struct in_chunk_dir incd;
 479
 480                buffer += sprintf(buffer, "[%04X:%04X] ",
 481                        ec->cid.manufacturer, ec->cid.product);
 482
 483                if (!ec->card_desc && ec->cid.cd &&
 484                    ecard_readchunk(&incd, ec, 0xf5, 0)) {
 485                        ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
 486
 487                        if (ec->card_desc)
 488                                strcpy((char *)ec->card_desc, incd.d.string);
 489                }
 490
 491                buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
 492        } else
 493                buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id);
 494
 495        return buffer - start;
 496}
 497
 498static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count)
 499{
 500        ecard_t *ec = cards;
 501        off_t at = 0;
 502        int len, cnt;
 503
 504        cnt = 0;
 505        while (ec && count > cnt) {
 506                len = ecard_prints(buf, ec);
 507                at += len;
 508                if (at >= pos) {
 509                        if (!*start) {
 510                                *start = buf + (pos - (at - len));
 511                                cnt = at - pos;
 512                        } else
 513                                cnt += len;
 514                        buf += len;
 515                }
 516                ec = ec->next;
 517        }
 518        return (count > cnt) ? cnt : count;
 519}
 520
 521static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
 522
 523static void ecard_proc_init(void)
 524{
 525        proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
 526        create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
 527                get_ecard_dev_info);
 528}
 529
 530#define ec_set_resource(ec,nr,st,sz,flg)                        \
 531        do {                                                    \
 532                (ec)->resource[nr].name = ec->dev.bus_id;       \
 533                (ec)->resource[nr].start = st;                  \
 534                (ec)->resource[nr].end = (st) + (sz) - 1;       \
 535                (ec)->resource[nr].flags = flg;                 \
 536        } while (0)
 537
 538static void __init ecard_init_resources(struct expansion_card *ec)
 539{
 540        unsigned long base = PODSLOT_IOC0_BASE;
 541        unsigned int slot = ec->slot_no;
 542        int i;
 543
 544        ec_set_resource(ec, ECARD_RES_MEMC,
 545                        PODSLOT_MEMC_BASE + (slot << 14),
 546                        PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
 547
 548        for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
 549                ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
 550                                base + (slot << 14) + (i << 19),
 551                                PODSLOT_IOC_SIZE, IORESOURCE_MEM);
 552        }
 553
 554        for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
 555                if (ec->resource[i].start &&
 556                    request_resource(&iomem_resource, &ec->resource[i])) {
 557                        printk(KERN_ERR "%s: resource(s) not available\n",
 558                                ec->dev.bus_id);
 559                        ec->resource[i].end -= ec->resource[i].start;
 560                        ec->resource[i].start = 0;
 561                }
 562        }
 563}
 564
 565static ssize_t ecard_show_irq(struct device *dev, char *buf)
 566{
 567        struct expansion_card *ec = ECARD_DEV(dev);
 568        return sprintf(buf, "%u\n", ec->irq);
 569}
 570
 571static ssize_t ecard_show_vendor(struct device *dev, char *buf)
 572{
 573        struct expansion_card *ec = ECARD_DEV(dev);
 574        return sprintf(buf, "%u\n", ec->cid.manufacturer);
 575}
 576
 577static ssize_t ecard_show_device(struct device *dev, char *buf)
 578{
 579        struct expansion_card *ec = ECARD_DEV(dev);
 580        return sprintf(buf, "%u\n", ec->cid.product);
 581}
 582
 583static ssize_t ecard_show_dma(struct device *dev, char *buf)
 584{
 585        struct expansion_card *ec = ECARD_DEV(dev);
 586        return sprintf(buf, "%u\n", ec->dma);
 587}
 588
 589static ssize_t ecard_show_resources(struct device *dev, char *buf)
 590{
 591        struct expansion_card *ec = ECARD_DEV(dev);
 592        char *str = buf;
 593        int i;
 594
 595        for (i = 0; i < ECARD_NUM_RESOURCES; i++)
 596                str += sprintf(str, "%08lx %08lx %08lx\n",
 597                                ec->resource[i].start,
 598                                ec->resource[i].end,
 599                                ec->resource[i].flags);
 600
 601        return str - buf;
 602}
 603
 604static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
 605static DEVICE_ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL);
 606static DEVICE_ATTR(device, S_IRUGO, ecard_show_device, NULL);
 607static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
 608static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
 609
 610/*
 611 * Probe for an expansion card.
 612 *
 613 * If bit 1 of the first byte of the card is set, then the
 614 * card does not exist.
 615 */
 616static int __init
 617ecard_probe(int slot, card_type_t type)
 618{
 619        ecard_t **ecp;
 620        ecard_t *ec;
 621        struct ex_ecid cid;
 622        int i, rc = -ENOMEM;
 623
 624        ec = kmalloc(sizeof(ecard_t), GFP_KERNEL);
 625        if (!ec)
 626                goto nomem;
 627
 628        memset(ec, 0, sizeof(ecard_t));
 629
 630        ec->slot_no     = slot;
 631        ec->type        = type;
 632        ec->irq         = NO_IRQ;
 633        ec->fiq         = NO_IRQ;
 634        ec->dma         = NO_DMA;
 635        ec->card_desc   = NULL;
 636        ec->ops         = &ecard_default_ops;
 637
 638        rc = -ENODEV;
 639        if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0)
 640                goto nodev;
 641
 642        cid.r_zero = 1;
 643        ecard_readbytes(&cid, ec, 0, 16, 0);
 644        if (cid.r_zero)
 645                goto nodev;
 646
 647        ec->cid.id      = cid.r_id;
 648        ec->cid.cd      = cid.r_cd;
 649        ec->cid.is      = cid.r_is;
 650        ec->cid.w       = cid.r_w;
 651        ec->cid.manufacturer = ecard_getu16(cid.r_manu);
 652        ec->cid.product = ecard_getu16(cid.r_prod);
 653        ec->cid.country = cid.r_country;
 654        ec->cid.irqmask = cid.r_irqmask;
 655        ec->cid.irqoff  = ecard_gets24(cid.r_irqoff);
 656        ec->cid.fiqmask = cid.r_fiqmask;
 657        ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
 658        ec->fiqaddr     =
 659        ec->irqaddr     = (unsigned char *)ioaddr(ec->podaddr);
 660
 661        if (ec->cid.is) {
 662                ec->irqmask = ec->cid.irqmask;
 663                ec->irqaddr += ec->cid.irqoff;
 664                ec->fiqmask = ec->cid.fiqmask;
 665                ec->fiqaddr += ec->cid.fiqoff;
 666        } else {
 667                ec->irqmask = 1;
 668                ec->fiqmask = 4;
 669        }
 670
 671        for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
 672                if (blacklist[i].manufacturer == ec->cid.manufacturer &&
 673                    blacklist[i].product == ec->cid.product) {
 674                        ec->card_desc = blacklist[i].type;
 675                        break;
 676                }
 677
 678        snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
 679        ec->dev.parent = NULL;
 680        ec->dev.bus    = &ecard_bus_type;
 681        ec->dev.dma_mask = &ec->dma_mask;
 682        ec->dma_mask = (u64)0xffffffff;
 683
 684        ecard_init_resources(ec);
 685
 686        /*
 687         * hook the interrupt handlers
 688         */
 689        ec->irq = 32 + slot;
 690        set_irq_chip(ec->irq, &ecard_chip);
 691        set_irq_handler(ec->irq, do_level_IRQ);
 692        set_irq_flags(ec->irq, IRQF_VALID);
 693
 694        for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
 695
 696        *ecp = ec;
 697        slot_to_expcard[slot] = ec;
 698
 699        device_register(&ec->dev);
 700        device_create_file(&ec->dev, &dev_attr_dma);
 701        device_create_file(&ec->dev, &dev_attr_irq);
 702        device_create_file(&ec->dev, &dev_attr_resource);
 703        device_create_file(&ec->dev, &dev_attr_vendor);
 704        device_create_file(&ec->dev, &dev_attr_device); 
 705
 706        return 0;
 707
 708nodev:
 709        kfree(ec);
 710nomem:
 711        return rc;
 712}
 713
 714/*
 715 * Initialise the expansion card system.
 716 * Locate all hardware - interrupt management and
 717 * actual cards.
 718 */
 719static int __init ecard_init(void)
 720{
 721        int slot, irqhw;
 722
 723        printk("Probing expansion cards\n");
 724
 725        for (slot = 0; slot < MAX_ECARDS; slot ++) {
 726                ecard_probe(slot, ECARD_IOC);
 727        }
 728
 729        irqhw = ecard_probeirqhw();
 730
 731        set_irq_chained_handler(IRQ_EXPANSIONCARD,
 732                                irqhw ? ecard_irqexp_handler : ecard_irq_handler);
 733
 734        ecard_proc_init();
 735
 736        return 0;
 737}
 738
 739subsys_initcall(ecard_init);
 740
 741/*
 742 *      ECARD "bus"
 743 */
 744static const struct ecard_id *
 745ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
 746{
 747        int i;
 748
 749        for (i = 0; ids[i].manufacturer != 65535; i++)
 750                if (ec->cid.manufacturer == ids[i].manufacturer &&
 751                    ec->cid.product == ids[i].product)
 752                        return ids + i;
 753
 754        return NULL;
 755}
 756
 757static int ecard_drv_probe(struct device *dev)
 758{
 759        struct expansion_card *ec = ECARD_DEV(dev);
 760        struct ecard_driver *drv = ECARD_DRV(dev->driver);
 761        const struct ecard_id *id;
 762        int ret;
 763
 764        id = ecard_match_device(drv->id_table, ec);
 765
 766        ecard_claim(ec);
 767        ret = drv->probe(ec, id);
 768        if (ret)
 769                ecard_release(ec);
 770        return ret;
 771}
 772
 773static int ecard_drv_remove(struct device *dev)
 774{
 775        struct expansion_card *ec = ECARD_DEV(dev);
 776        struct ecard_driver *drv = ECARD_DRV(dev->driver);
 777
 778        drv->remove(ec);
 779        ecard_release(ec);
 780
 781        return 0;
 782}
 783
 784/*
 785 * Before rebooting, we must make sure that the expansion card is in a
 786 * sensible state, so it can be re-detected.  This means that the first
 787 * page of the ROM must be visible.  We call the expansion cards reset
 788 * handler, if any.
 789 */
 790static void ecard_drv_shutdown(struct device *dev)
 791{
 792        struct expansion_card *ec = ECARD_DEV(dev);
 793        struct ecard_driver *drv = ECARD_DRV(dev->driver);
 794        struct ecard_request req;
 795
 796        if (drv->shutdown)
 797                drv->shutdown(ec);
 798        ecard_release(ec);
 799        req.req = req_reset;
 800        req.ec = ec;
 801        ecard_call(&req);
 802}
 803
 804int ecard_register_driver(struct ecard_driver *drv)
 805{
 806        drv->drv.bus = &ecard_bus_type;
 807        drv->drv.probe = ecard_drv_probe;
 808        drv->drv.remove = ecard_drv_remove;
 809        drv->drv.shutdown = ecard_drv_shutdown;
 810
 811        return driver_register(&drv->drv);
 812}
 813
 814void ecard_remove_driver(struct ecard_driver *drv)
 815{
 816        driver_unregister(&drv->drv);
 817}
 818
 819static int ecard_match(struct device *_dev, struct device_driver *_drv)
 820{
 821        struct expansion_card *ec = ECARD_DEV(_dev);
 822        struct ecard_driver *drv = ECARD_DRV(_drv);
 823        int ret;
 824
 825        if (drv->id_table) {
 826                ret = ecard_match_device(drv->id_table, ec) != NULL;
 827        } else {
 828                ret = ec->cid.id == drv->id;
 829        }
 830
 831        return ret;
 832}
 833
 834struct bus_type ecard_bus_type = {
 835        .name   = "ecard",
 836        .match  = ecard_match,
 837};
 838
 839static int ecard_bus_init(void)
 840{
 841        return bus_register(&ecard_bus_type);
 842}
 843
 844postcore_initcall(ecard_bus_init);
 845
 846EXPORT_SYMBOL(ecard_readchunk);
 847EXPORT_SYMBOL(ecard_address);
 848EXPORT_SYMBOL(ecard_register_driver);
 849EXPORT_SYMBOL(ecard_remove_driver);
 850EXPORT_SYMBOL(ecard_bus_type);
 851
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.