[BACK]Return to cardbus_exrom.c CVS log [TXT][DIR] Up to [local] / sys / dev / cardbus

Annotation of sys/dev/cardbus/cardbus_exrom.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: cardbus_exrom.c,v 1.4 2005/09/13 18:44:38 fgsch Exp $ */
                      2: /*     $NetBSD: cardbus_exrom.c,v 1.4 2000/02/03 06:47:31 thorpej Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1999 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to
                      9:  * The NetBSD Foundation by Johan Danielsson.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  *
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  *
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  *
                     22:  * 3. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: #include <sys/param.h>
                     40: #include <sys/systm.h>
                     41: #include <sys/queue.h>
                     42: #include <sys/malloc.h>
                     43:
                     44: #include <machine/bus.h>
                     45:
                     46: #include <dev/cardbus/cardbus_exrom.h>
                     47:
                     48: #if defined(CARDBUS_DEBUG)
                     49: #define        DPRINTF(a)      printf a
                     50: #else
                     51: #define        DPRINTF(a)
                     52: #endif
                     53:
                     54: #define READ_INT16(T, H, O)  \
                     55:        (bus_space_read_1((T), (H), (O)) | \
                     56:         (bus_space_read_1((T), (H), (O) + 1) << 8))
                     57:
                     58: /*
                     59:  *  A PCI ROM is divided into a number of images. Each image has two
                     60:  *  data structures, a header located at the start of the image, and a
                     61:  *  `data structure' at some offset into it.
                     62:  *
                     63:  *  The header is a 26 byte structure:
                     64:  *
                     65:  *  Offset     Length  Description
                     66:  *  0x00          1    signature byte 1 (0x55)
                     67:  *  0x01          1    signature byte 2 (0xAA)
                     68:  *  0x02         22    processor architecture data
                     69:  *  0x18          2    pointer to the data structure
                     70:  *
                     71:  *  The data structure is a 24 byte structure:
                     72:  *
                     73:  *  Offset     Length  Description
                     74:  *  0x00          4    signature (PCIR)
                     75:  *  0x04          2    vendor id
                     76:  *  0x06          2    device id
                     77:  *  0x08          2    reserved
                     78:  *  0x0A          2    data structure length
                     79:  *  0x0C          1    data structure revision (0)
                     80:  *  0x0D          3    class code
                     81:  *  0x10          2    image length (in 512 byte blocks)
                     82:  *  0x12          2    code revision level
                     83:  *  0x14          1    code type
                     84:  *  0x15          1    indicator (bit 7 indicates final image)
                     85:  *  0x16          2    reserved
                     86:  *
                     87:  */
                     88:
                     89: /*
                     90:  *  Scan through a PCI expansion ROM, and create subregions for each
                     91:  *  ROM image. This function assumes that the ROM is mapped at
                     92:  *  (tag,handle), and that the expansion ROM address decoder is
                     93:  *  enabled. The PCI specification requires that no other BAR should
                     94:  *  be accessed while the ROM is enabled, so interrupts should be
                     95:  *  disabled.
                     96:  *
                     97:  * XXX This routine is way too pessimistic and returns as soon as it encounters
                     98:  * a problem, although not being able to malloc or read a particular image
                     99:  * may not prevent further images from being read successfully.
                    100:  */
                    101: int
                    102: cardbus_read_exrom(bus_space_tag_t romt, bus_space_handle_t romh,
                    103:     struct cardbus_rom_image_head *head)
                    104: {
                    105:        size_t addr = 0; /* offset of current rom image */
                    106:        size_t dataptr;
                    107:        unsigned int rom_image = 0;
                    108:        size_t image_size;
                    109:        struct cardbus_rom_image *image;
                    110:        u_int16_t val;
                    111:
                    112:        SIMPLEQ_INIT(head);
                    113:        do {
                    114:                val = READ_INT16(romt, romh, addr + CARDBUS_EXROM_SIGNATURE);
                    115:                if (val != 0xaa55) {
                    116:                        DPRINTF(("%s: bad header signature in ROM image "
                    117:                            "%u: 0x%04x\n", __func__, rom_image, val));
                    118:                        return (1);
                    119:                }
                    120:                dataptr = addr + READ_INT16(romt, romh,
                    121:                    addr + CARDBUS_EXROM_DATA_PTR);
                    122:
                    123:                /* get the ROM image size, in blocks */
                    124:                image_size = READ_INT16(romt, romh,
                    125:                    dataptr + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
                    126:                /* XXX
                    127:                 * Some ROMs seem to have this as zero, can we assume
                    128:                 * this means 1 block?
                    129:                 */
                    130:                if (image_size == 0)
                    131:                        image_size = 1;
                    132:                image_size <<= 9;
                    133:
                    134:                image = malloc(sizeof(*image), M_DEVBUF, M_NOWAIT);
                    135:                if (image == NULL) {
                    136:                        DPRINTF(("%s: out of memory\n", __func__));
                    137:                        return (1);
                    138:                }
                    139:                image->rom_image = rom_image;
                    140:                image->image_size = image_size;
                    141:                image->romt = romt;
                    142:                if (bus_space_subregion(romt, romh, addr,
                    143:                    image_size, &image->romh)) {
                    144:                        DPRINTF(("%s: bus_space_subregion failed", __func__));
                    145:                        free(image, M_DEVBUF);
                    146:                        return (1);
                    147:                }
                    148:                SIMPLEQ_INSERT_TAIL(head, image, next);
                    149:                addr += image_size;
                    150:                rom_image++;
                    151:        } while ((bus_space_read_1(romt, romh,
                    152:            dataptr + CARDBUS_EXROM_DATA_INDICATOR) & 0x80) == 0);
                    153:
                    154:        return (0);
                    155: }

CVSweb