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

Annotation of sys/dev/pci/if_sandrv.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: if_sandrv.c,v 1.11 2006/04/20 20:31:12 miod Exp $     */
                      2:
                      3: /*-
                      4:  * Copyright (c) 2001-2004 Sangoma Technologies (SAN)
                      5:  * All rights reserved.  www.sangoma.com
                      6:  *
                      7:  * This code is written by Alex Feldman <al.feldman@sangoma.com> for SAN.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above
                     15:  *    copyright notice, this list of conditions and the following disclaimer
                     16:  *    in the documentation and/or other materials provided with the
                     17:  *    distribution.
                     18:  * 3. Neither the name of Sangoma Technologies nor the names of its
                     19:  *    contributors may be used to endorse or promote products derived
                     20:  *    from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY SANGOMA TECHNOLOGIES AND CONTRIBUTORS
                     23:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     24:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     25:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     26:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     32:  * THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #define __SDLA_HW_LEVEL
                     36: #define __SDLADRV__
                     37:
                     38: #include <sys/types.h>
                     39: #include <sys/param.h>
                     40: #include <sys/systm.h>
                     41: #include <sys/syslog.h>
                     42: #include <sys/malloc.h>
                     43: #include <sys/kernel.h>
                     44:
                     45: #include <dev/pci/pcireg.h>
                     46: #include <dev/pci/pcivar.h>
                     47: #include <dev/pci/if_san_front_end.h>
                     48: #include <dev/pci/if_sandrv.h>
                     49:
                     50: #define        EXEC_DELAY      20      /* shared memory access delay, mks */
                     51: #define EXEC_TIMEOUT   (hz*2)
                     52: #define MAX_NLOOPS     (EXEC_DELAY*2000)
                     53:                        /* timeout used if jiffies are stopped
                     54:                        ** EXEC_DELAY=20
                     55:                        ** EXEC_TIMEOUT=EXEC_DELAY*2000 = 40000
                     56:                        ** 40000 ~= 80 jiffies = EXEC_TIMEOUT */
                     57:
                     58: #define        EXEC_HZ_DIVISOR 8/10
                     59:                        /* We don't want to wait a full second on sdla_exec
                     60:                        ** timeout, thus use HZ * EXEC_HZ_DIVISOR to get
                     61:                        ** the number of jiffies we would like to wait */
                     62:
                     63: #define IS_SUPPORTED_ADAPTER(hw)       ((hw)->type == SDLA_AFT)
                     64:
                     65: #define SDLA_CTYPE_NAME(type)                  \
                     66:        ((type) == SDLA_AFT) ? "AFT" : "Unknown"
                     67:
                     68: #define IS_AFT(hw)     (hw->type == SDLA_AFT)
                     69:
                     70: /* Definitions for identifying and finding S514 PCI adapters */
                     71: #define V3_VENDOR_ID           0x11B0          /* V3 vendor ID number */
                     72: #define V3_DEVICE_ID           0x0002          /* V3 device ID number */
                     73: #define SANGOMA_SUBSYS_VENDOR  0x4753          /* ID for Sangoma */
                     74:
                     75: /* Definition for identifying and finding XILINX PCI adapters */
                     76: #define SANGOMA_PCI_VENDOR     0x1923          /* Old value -> 0x11B0 */
                     77: #define SANGOMA_PCI_VENDOR_OLD 0x10EE          /* Old value -> 0x11B0 */
                     78: #define SANGOMA_PCI_DEVICE     0x0300          /* Old value -> 0x0200 */
                     79:
                     80: #define A101_1TE1_SUBSYS_VENDOR        0xA010  /* A101 with T1/E1 1 line  */
                     81: #define A101_2TE1_SUBSYS_VENDOR        0xA011  /* A101 with T1/E1 2 lines */
                     82: #define A105_T3_SUBSYS_VENDOR  0xA020  /* A102 with T3 */
                     83:
                     84: /* Read PCI SUBVENDOR ID */
                     85: #define PCI_SUBVENDOR_MASK     0xFFFF
                     86: #define PCI_SUBVENDOR(pa)      (pci_conf_read(pa->pa_pc, pa->pa_tag,   \
                     87:                                    PCI_SUBSYS_ID_REG) & PCI_SUBVENDOR_MASK)
                     88: #define PCI_DEVICE_MASK                0xFFFF0000
                     89: #define PCI_DEVICE(id)         ((id & PCI_DEVICE_MASK ) >> 16)
                     90:
                     91: /* Status values */
                     92: #define SDLA_MEM_RESERVED      0x0001
                     93: #define SDLA_MEM_MAPPED                0x0002
                     94: #define SDLA_IO_MAPPED         0x0004
                     95: #define SDLA_PCI_ENABLE                0x0008
                     96:
                     97: struct san_softc {
                     98:        struct device           dev;
                     99:        struct pci_attach_args  pa;
                    100: };
                    101:
                    102: typedef struct sdla_hw_probe {
                    103:        int                             used;
                    104:        unsigned char                   hw_info[100];
                    105:        LIST_ENTRY(sdla_hw_probe)       next;
                    106: } sdla_hw_probe_t;
                    107:
                    108: /*
                    109:  * This structure keeps common parameters per physical card.
                    110:  */
                    111: typedef struct sdlahw_card {
                    112:        int                     used;
                    113:        unsigned int            type;           /* S50x/S514/ADSL/XILINX */
                    114:        unsigned int            atype;          /* SubVendor ID */
                    115:        unsigned char           core_id;        /* SubSystem ID [0..7] */
                    116:        unsigned char           core_rev;       /* SubSystem ID [8..15] */
                    117:        unsigned char           pci_extra_ver;
                    118:        unsigned int            slot_no;
                    119:        unsigned int            bus_no;
                    120:        bus_space_tag_t         memt;
                    121:        struct pci_attach_args  pa;     /* PCI config header info */
                    122:        pci_intr_handle_t       ih;
                    123:        LIST_ENTRY(sdlahw_card) next;
                    124: } sdlahw_card_t;
                    125:
                    126: /*
                    127:  * Adapter hardware configuration. Pointer to this structure is passed to all
                    128:  * APIs.
                    129:  */
                    130: typedef struct sdlahw {
                    131:        int                      used;
                    132:        unsigned                 magic;
                    133:        char                     devname[20];
                    134:        u_int16_t                status;
                    135:        int                      irq;           /* interrupt request level */
                    136:        unsigned int             cpu_no;        /* PCI CPU Number */
                    137:        char                     auto_pci_cfg;  /* Auto PCI configuration */
                    138:        bus_addr_t               mem_base_addr;
                    139:        bus_space_handle_t       dpmbase;       /* dual-port memory base */
                    140:        unsigned                 dpmsize;       /* dual-port memory size */
                    141:        unsigned long            memory;        /* memory size */
                    142:
                    143:        unsigned                 reserved[5];
                    144:        unsigned char            hw_info[100];
                    145:
                    146:        u_int16_t                configured;
                    147:        void                    *arg;           /* card structure */
                    148:        sdla_hw_probe_t         *hwprobe;
                    149:        sdlahw_card_t           *hwcard;
                    150:        LIST_ENTRY(sdlahw)       next;
                    151: } sdlahw_t;
                    152:
                    153: /* Entry Point for Low-Level function */
                    154: int sdladrv_init(void);
                    155: int sdladrv_exit(void);
                    156:
                    157: static int sdla_pci_probe(int, struct pci_attach_args *);
                    158:
                    159: /* PCI bus interface function */
                    160: static int sdla_pci_write_config_word(void *, int, u_int16_t);
                    161: static int sdla_pci_write_config_dword(void *, int, u_int32_t);
                    162: static int sdla_pci_read_config_byte(void *, int, u_int8_t *);
                    163: static int sdla_pci_read_config_word(void *, int, u_int16_t *);
                    164: static int sdla_pci_read_config_dword(void *, int, u_int32_t *);
                    165:
                    166: static int sdla_detect (sdlahw_t *);
                    167: static int sdla_detect_aft(sdlahw_t *);
                    168: static int sdla_exec(sdlahw_t *, unsigned long);
                    169: static void sdla_peek_by_4(sdlahw_t *, unsigned long, void *, unsigned int);
                    170: static void sdla_poke_by_4(sdlahw_t *, unsigned long, void *, unsigned int);
                    171:
                    172: static sdlahw_card_t* sdla_card_register(u_int16_t, int, int);
                    173: #if 0
                    174: static int sdla_card_unregister (unsigned char, int, int, int);
                    175: #endif
                    176: static sdlahw_card_t* sdla_card_search(u_int16_t, int, int);
                    177:
                    178: static sdlahw_t* sdla_hw_register(sdlahw_card_t *, int, int, void *);
                    179: #if 0
                    180: static int sdla_hw_unregister(sdlahw_card_t*, int);
                    181: #endif
                    182: static sdlahw_t* sdla_hw_search(u_int16_t, int, int, int);
                    183:
                    184: static sdlahw_t* sdla_aft_hw_select (sdlahw_card_t *, int, int,
                    185:     struct pci_attach_args *);
                    186: static void sdla_save_hw_probe (sdlahw_t*, int);
                    187:
                    188: /* SDLA PCI device relative entry point */
                    189: int    san_match(struct device *, void *, void *);
                    190: void   san_attach(struct device *, struct device *, void *);
                    191:
                    192:
                    193: struct cfdriver san_cd = {
                    194:        NULL, "san", DV_IFNET
                    195: };
                    196:
                    197: struct cfattach san_ca = {
                    198:        sizeof(struct san_softc), san_match, san_attach
                    199: };
                    200:
                    201: extern int ticks;
                    202:
                    203: /* SDLA ISA/PCI varibles */
                    204: static int       Sangoma_cards_no = 0;
                    205: static int       Sangoma_devices_no = 0;
                    206: static int       Sangoma_PCI_cards_no = 0;
                    207:
                    208: /* private data */
                    209: char           *san_drvname = "san";
                    210:
                    211: /* Array of already initialized PCI slots */
                    212: static int pci_slot_ar[MAX_S514_CARDS];
                    213:
                    214: LIST_HEAD(, sdlahw_card) sdlahw_card_head =
                    215:        LIST_HEAD_INITIALIZER(sdlahw_card_head);
                    216: LIST_HEAD(, sdlahw) sdlahw_head =
                    217:        LIST_HEAD_INITIALIZER(sdlahw_head);
                    218: LIST_HEAD(, sdla_hw_probe) sdlahw_probe_head =
                    219:        LIST_HEAD_INITIALIZER(sdlahw_probe_head);
                    220: static sdla_hw_type_cnt_t sdla_adapter_cnt;
                    221:
                    222:
                    223:
                    224: /*
                    225:  * PCI Device Driver Entry Points
                    226:  */
                    227: int
                    228: san_match(struct device *parent, void *match, void *aux)
                    229: {
                    230:        struct pci_attach_args* pa = aux;
                    231:        u_int16_t               vendor_id = PCI_VENDOR(pa->pa_id);
                    232:        u_int16_t               device_id = PCI_DEVICE(pa->pa_id);
                    233:
                    234:        if ((vendor_id == SANGOMA_PCI_VENDOR ||
                    235:            vendor_id == SANGOMA_PCI_VENDOR_OLD) &&
                    236:            device_id == SANGOMA_PCI_DEVICE) {
                    237:                return (1);
                    238:        }
                    239:        return (0);
                    240: }
                    241:
                    242: #define PCI_CBIO       0x10
                    243: void
                    244: san_attach(struct device *parent, struct device *self, void *aux)
                    245: {
                    246:        struct pci_attach_args*         pa = aux;
                    247:        u_int16_t                       vendor_id = PCI_VENDOR(pa->pa_id);
                    248:        u_int16_t                       subvendor_id = PCI_SUBVENDOR(pa);
                    249:        int                             atype = 0x00;
                    250:
                    251:        atype = PCI_PRODUCT(pci_conf_read(pa->pa_pc, pa->pa_tag,
                    252:            PCI_SUBSYS_ID_REG));
                    253:        switch (vendor_id) {
                    254:        case SANGOMA_PCI_VENDOR_OLD:
                    255:        case SANGOMA_PCI_VENDOR:
                    256:                switch (subvendor_id) {
                    257:                case A101_1TE1_SUBSYS_VENDOR:
                    258:                        atype   = A101_ADPTR_1TE1;
                    259:                        break;
                    260:                case A101_2TE1_SUBSYS_VENDOR:
                    261:                        atype   = A101_ADPTR_2TE1;
                    262:                        break;
                    263:                default:
                    264:                        return;
                    265:                }
                    266:                break;
                    267:        default:
                    268:                return;
                    269:        }
                    270:
                    271:        if (sdla_pci_probe(atype, pa)) {
                    272:                printf(": PCI probe FAILED!\n");
                    273:                return;
                    274:        }
                    275:
                    276: #ifdef DEBUG
                    277:        switch (PCI_VENDOR(pa->pa_id)) {
                    278:        case V3_VENDOR_ID:
                    279:                switch (atype) {
                    280:                case S5141_ADPTR_1_CPU_SERIAL:
                    281:                        log(LOG_INFO, "%s: Sangoma S5141/FT1 (Single CPU) "
                    282:                            "adapter\n", self->dv_xname);
                    283:                        break;
                    284:                case S5142_ADPTR_2_CPU_SERIAL:
                    285:                        log(LOG_INFO, "%s: Sangoma S5142 (Dual CPU) adapter\n",
                    286:                            self->dv_xname);
                    287:                        break;
                    288:                case S5143_ADPTR_1_CPU_FT1:
                    289:                        log(LOG_INFO, "%s: Sangoma S5143 (Single CPU) "
                    290:                            "FT1 adapter\n", self->dv_xname);
                    291:                        break;
                    292:                case S5144_ADPTR_1_CPU_T1E1:
                    293:                case S5148_ADPTR_1_CPU_T1E1:
                    294:                        log(LOG_INFO, "%s: Sangoma S5144 (Single CPU) "
                    295:                            "T1/E1 adapter\n", self->dv_xname);
                    296:                        break;
                    297:                case S5145_ADPTR_1_CPU_56K:
                    298:                        log(LOG_INFO, "%s: Sangoma S5145 (Single CPU) "
                    299:                            "56K adapter\n", self->dv_xname);
                    300:                        break;
                    301:                case S5147_ADPTR_2_CPU_T1E1:
                    302:                        log(LOG_INFO, "%s: Sangoma S5147 (Dual CPU) "
                    303:                            "T1/E1 adapter\n", self->dv_xname);
                    304:                        break;
                    305:                }
                    306:                break;
                    307:
                    308:        case SANGOMA_PCI_VENDOR_OLD:
                    309:                switch (atype) {
                    310:                case A101_ADPTR_1TE1:
                    311:                        log(LOG_INFO, "%s: Sangoma AFT (1 channel) "
                    312:                            "T1/E1 adapter\n", self->dv_xname);
                    313:                        break;
                    314:                case A101_ADPTR_2TE1:
                    315:                        log(LOG_INFO, "%s: Sangoma AFT (2 channels) "
                    316:                            "T1/E1 adapter\n", self->dv_xname);
                    317:                        break;
                    318:                }
                    319:                break;
                    320:        }
                    321: #endif
                    322:        return;
                    323: }
                    324:
                    325: /*
                    326:  * Module init point.
                    327:  */
                    328: int
                    329: sdladrv_init(void)
                    330: {
                    331:        int volatile i = 0;
                    332:
                    333:        /* Initialize the PCI Card array, which
                    334:         * will store flags, used to mark
                    335:         * card initialization state */
                    336:        for (i=0; i<MAX_S514_CARDS; i++)
                    337:                pci_slot_ar[i] = 0xFF;
                    338:
                    339:        bzero(&sdla_adapter_cnt, sizeof(sdla_hw_type_cnt_t));
                    340:
                    341:        return (0);
                    342: }
                    343:
                    344: /*
                    345:  * Module deinit point.
                    346:  * o release all remaining system resources
                    347:  */
                    348: int
                    349: sdladrv_exit(void)
                    350: {
                    351: #if 0
                    352:        sdla_hw_probe_t *elm_hw_probe;
                    353:        sdlahw_t        *elm_hw;
                    354:        sdlahw_card_t   *elm_hw_card;
                    355:
                    356:
                    357:        elm_hw = LIST_FIRST(&sdlahw_head);
                    358:        while (elm_hw) {
                    359:                sdlahw_t        *tmp = elm_hw;
                    360:                elm_hw = LIST_NEXT(elm_hw, next);
                    361:                if (sdla_hw_unregister(tmp->hwcard, tmp->cpu_no) == EBUSY)
                    362:                        return EBUSY;
                    363:        }
                    364:        LIST_INIT(&sdlahw_head);
                    365:
                    366:        elm_hw_card = LIST_FIRST(&sdlahw_card_head);
                    367:        while (elm_hw_card) {
                    368:                sdlahw_card_t   *tmp = elm_hw_card;
                    369:                elm_hw_card = LIST_NEXT(elm_hw_card, next);
                    370:                if (sdla_card_unregister(tmp->hw_type,
                    371:                                         tmp->slot_no,
                    372:                                         tmp->bus_no,
                    373:                                         tmp->ioport) == EBUSY)
                    374:                        return EBUSY;
                    375:        }
                    376:        LIST_INIT(&sdlahw_card_head);
                    377:
                    378:        elm_hw_probe = LIST_FIRST(&sdlahw_probe_head);
                    379:        while (elm_hw_probe) {
                    380:                sdla_hw_probe_t *tmp = elm_hw_probe;
                    381:                elm_hw_probe = LIST_NEXT(elm_hw_probe, next);
                    382:                if (tmp->used){
                    383:                        log(LOG_INFO, "HW probe info is in used (%s)\n",
                    384:                                        elm_hw_probe->hw_info);
                    385:                        return EBUSY;
                    386:                }
                    387:                LIST_REMOVE(tmp, next);
                    388:                free(tmp, M_DEVBUF);
                    389:        }
                    390: #endif
                    391:        return (0);
                    392: }
                    393:
                    394: static void
                    395: sdla_save_hw_probe(sdlahw_t *hw, int port)
                    396: {
                    397:        sdla_hw_probe_t *tmp_hw_probe;
                    398:
                    399:        tmp_hw_probe = malloc(sizeof(sdla_hw_probe_t), M_DEVBUF, M_NOWAIT);
                    400:        if (tmp_hw_probe == NULL)
                    401:                return;
                    402:
                    403:        bzero(tmp_hw_probe, sizeof(sdla_hw_probe_t));
                    404:
                    405:        snprintf(tmp_hw_probe->hw_info, sizeof(tmp_hw_probe->hw_info),
                    406:                "%s : SLOT=%d : BUS=%d : IRQ=%d : CPU=%c : PORT=%s",
                    407:                SDLA_ADPTR_DECODE(hw->hwcard->atype), hw->hwcard->slot_no,
                    408:                hw->hwcard->bus_no, hw->irq, SDLA_GET_CPU(hw->cpu_no), "PRI");
                    409:
                    410:        hw->hwprobe = tmp_hw_probe;
                    411:        tmp_hw_probe->used++;
                    412:        LIST_INSERT_HEAD(&sdlahw_probe_head, tmp_hw_probe, next);
                    413: }
                    414:
                    415: static sdlahw_t*
                    416: sdla_aft_hw_select(sdlahw_card_t *hwcard, int cpu_no,
                    417:     int irq, struct pci_attach_args *pa)
                    418: {
                    419:        sdlahw_t*       hw = NULL;
                    420:        int             number_of_cards = 0;
                    421:
                    422:        hwcard->type = SDLA_AFT;
                    423:        switch (hwcard->atype) {
                    424:        case A101_ADPTR_1TE1:
                    425:                hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
                    426:                sdla_save_hw_probe(hw, 0);
                    427:                number_of_cards += 1;
                    428: #ifdef DEBUG
                    429:                log(LOG_INFO, "%s: %s T1/E1 card found (%s rev.%d), "
                    430:                    "cpu(s) 1, bus #%d, slot #%d, irq #%d\n", san_drvname,
                    431:                     SDLA_ADPTR_DECODE(hwcard->atype),
                    432:                     AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev,
                    433:                     hwcard->bus_no, hwcard->slot_no, irq);
                    434: #endif /* DEBUG */
                    435:                break;
                    436:        case A101_ADPTR_2TE1:
                    437:                hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
                    438:                sdla_save_hw_probe(hw, 0);
                    439:                number_of_cards += 1;
                    440: #ifdef DEBUG
                    441:                log(LOG_INFO, "%s: %s T1/E1 card found (%s rev.%d), "
                    442:                    "cpu(s) 2, bus #%d, slot #%d, irq #%d\n", san_drvname,
                    443:                    SDLA_ADPTR_DECODE(hwcard->atype),
                    444:                    AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev,
                    445:                    hwcard->bus_no, hwcard->slot_no, irq);
                    446: #endif /* DEBUG */
                    447:                break;
                    448:        case A105_ADPTR_1_CHN_T3E3:
                    449:
                    450:                hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
                    451:                sdla_save_hw_probe(hw, 0);
                    452:                number_of_cards += 1;
                    453: #ifdef DEBUG
                    454:                log(LOG_INFO, "%s: %s T3/E3 card found, cpu(s) 1,"
                    455:                     "bus #%d, slot #%d, irq #%d\n", san_drvname,
                    456:                     SDLA_ADPTR_DECODE(hwcard->atype),
                    457:                     hwcard->bus_no, hwcard->slot_no, irq);
                    458: #endif /* DEBUG */
                    459:                break;
                    460:        default:
                    461:                log(LOG_INFO, "%s: Unknown adapter %04X "
                    462:                    "(bus #%d, slot #%d, irq #%d)!\n", san_drvname,
                    463:                    hwcard->atype, hwcard->bus_no, hwcard->slot_no, irq);
                    464:                break;
                    465:        }
                    466:
                    467:        return (hw);
                    468: }
                    469:
                    470:
                    471: static int
                    472: sdla_pci_probe(int atype, struct pci_attach_args *pa)
                    473: {
                    474:        sdlahw_card_t*  hwcard;
                    475:        sdlahw_t*       hw;
                    476:        /*sdladev_t*    dev = NULL;*/
                    477:        int dual_cpu = 0;
                    478:        int bus, slot, cpu = SDLA_CPU_A;
                    479:        u_int16_t vendor_id, subvendor_id, device_id;
                    480:        u_int8_t irq;
                    481:        pci_intr_handle_t       ih;
                    482:        const char*                     intrstr = NULL;
                    483:
                    484:        bus = pa->pa_bus;
                    485:        slot = pa->pa_device;
                    486:        vendor_id = PCI_VENDOR(pa->pa_id);
                    487:        subvendor_id = PCI_SUBVENDOR(pa);
                    488:        device_id = PCI_DEVICE(pa->pa_id);
                    489:        irq = (u_int8_t)pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_INTLINE);
                    490:
                    491:        /* Map and establish the interrupt */
                    492:        if (pci_intr_map(pa, &ih)) {
                    493:                printf(": couldn't map interrupt\n");
                    494:                return (EINVAL);
                    495:        }
                    496:        intrstr = pci_intr_string(pa->pa_pc, ih);
                    497:        if (intrstr != NULL)
                    498:                printf(" %s\n", intrstr);
                    499:
                    500:        Sangoma_cards_no ++;
                    501: reg_new_card:
                    502:        Sangoma_PCI_cards_no ++;
                    503:        hwcard = sdla_card_register(atype, slot, bus);
                    504:        if (hwcard == NULL)
                    505:                return (EINVAL);
                    506:
                    507:        hwcard->memt    = pa->pa_memt;
                    508:        hwcard->ih      = ih;
                    509:        hwcard->pa      = *pa;
                    510:        /* Increment number of available Sangoma devices */
                    511:        Sangoma_devices_no ++;
                    512:        switch (atype) {
                    513:        case A101_ADPTR_1TE1:
                    514:        case A101_ADPTR_2TE1:
                    515:                hw = sdla_aft_hw_select(hwcard, cpu, irq, pa);
                    516:                sdla_adapter_cnt.AFT_adapters++;
                    517:                if (atype == A101_ADPTR_2TE1)
                    518:                        dual_cpu = 1;
                    519:                break;
                    520:
                    521:        }
                    522:
                    523:        if (hw == NULL)
                    524:            return (EINVAL);
                    525:        if (san_dev_attach(hw, hw->devname, sizeof(hw->devname)))
                    526:                return (EINVAL);
                    527:
                    528:        hw->used++;
                    529:
                    530:        if (dual_cpu && cpu == SDLA_CPU_A) {
                    531:                cpu = SDLA_CPU_B;
                    532:                goto reg_new_card;
                    533:        }
                    534:
                    535:        return (0);
                    536: }
                    537:
                    538: int
                    539: sdla_intr_establish(void *phw, int (*intr_func)(void*), void* intr_arg)
                    540: {
                    541:        sdlahw_t        *hw = (sdlahw_t*)phw;
                    542:        sdlahw_card_t   *hwcard;
                    543:
                    544:        WAN_ASSERT(hw == NULL);
                    545:        hwcard = hw->hwcard;
                    546:        if (pci_intr_establish(hwcard->pa.pa_pc, hwcard->ih, IPL_NET,
                    547:            intr_func, intr_arg, "san") == NULL)
                    548:                return (EINVAL);
                    549:
                    550:        return 0;
                    551: }
                    552:
                    553: int
                    554: sdla_intr_disestablish(void *phw)
                    555: {
                    556:        sdlahw_t        *hw = (sdlahw_t*)phw;
                    557:
                    558:        log(LOG_INFO, "%s: Disestablish interrupt is not defined!\n",
                    559:            hw->devname);
                    560:        return (EINVAL);
                    561: }
                    562:
                    563: int
                    564: sdla_get_hw_devices(void)
                    565: {
                    566:        return (Sangoma_devices_no);
                    567: }
                    568:
                    569: void*
                    570: sdla_get_hw_adptr_cnt(void)
                    571: {
                    572:        return (&sdla_adapter_cnt);
                    573: }
                    574:
                    575: static sdlahw_card_t*
                    576: sdla_card_register(u_int16_t atype, int slot_no, int bus_no)
                    577: {
                    578:        sdlahw_card_t   *new_hwcard, *last_hwcard;
                    579:
                    580:        new_hwcard = sdla_card_search(atype, slot_no, bus_no);
                    581:        if (new_hwcard)
                    582:                return (new_hwcard);
                    583:
                    584:        new_hwcard = malloc(sizeof(sdlahw_card_t), M_DEVBUF, M_NOWAIT);
                    585:        if (!new_hwcard)
                    586:                return (NULL);
                    587:
                    588:        bzero(new_hwcard, sizeof(sdlahw_card_t));
                    589:
                    590:        new_hwcard->atype       = atype;
                    591:        new_hwcard->slot_no     = slot_no;
                    592:        new_hwcard->bus_no      = bus_no;
                    593:
                    594:        if (LIST_EMPTY(&sdlahw_card_head)) {
                    595:                /* Initialize SAN HW parameters */
                    596:                sdladrv_init();
                    597:        }
                    598:        LIST_FOREACH(last_hwcard, &sdlahw_card_head, next) {
                    599:                if (!LIST_NEXT(last_hwcard, next))
                    600:                        break;
                    601:        }
                    602:
                    603:        if (last_hwcard)
                    604:                LIST_INSERT_AFTER(last_hwcard, new_hwcard, next);
                    605:        else
                    606:                LIST_INSERT_HEAD(&sdlahw_card_head, new_hwcard, next);
                    607:
                    608:        return (new_hwcard);
                    609: }
                    610:
                    611: #if 0
                    612: static int
                    613: sdla_card_unregister(u_int16_t atype, int slot_no, int bus_no, int ioport)
                    614: {
                    615:        sdlahw_card_t*  tmp_card;
                    616:
                    617:        LIST_FOREACH(tmp_card, &sdlahw_card_head, next){
                    618:                if (tmp_card->atype != atype){
                    619:                        continue;
                    620:                }
                    621:                if (tmp_card->slot_no == slot_no &&
                    622:                                        tmp_card->bus_no == bus_no){
                    623:                        break;
                    624:                }
                    625:        }
                    626:        if (tmp_card == NULL){
                    627:                log(LOG_INFO,
                    628:                "Error: Card didn't find %04X card (slot=%d, bus=%d)\n"
                    629:                                atype, slot_no, bus_no);
                    630:                return (EFAULT)
                    631:        }
                    632:        if (tmp_card->used){
                    633:                log(LOG_INFO,
                    634:                "Error: Card is still in used (slot=%d,bus=%d,used=%d)\n",
                    635:                                slot_no, bus_no, tmp_card->used);
                    636:                return (EBUSY);
                    637:        }
                    638:        LIST_REMOVE(tmp_card, next);
                    639:        free(tmp_card, M_DEVBUF);
                    640:        return 0;
                    641: }
                    642: #endif
                    643:
                    644: static sdlahw_card_t*
                    645: sdla_card_search(u_int16_t atype, int slot_no, int bus_no)
                    646: {
                    647:        sdlahw_card_t*  tmp_card;
                    648:
                    649:        LIST_FOREACH(tmp_card, &sdlahw_card_head, next) {
                    650:                if (tmp_card->atype != atype)
                    651:                        continue;
                    652:
                    653:                if (tmp_card->slot_no == slot_no &&
                    654:                    tmp_card->bus_no == bus_no)
                    655:                        return (tmp_card);
                    656:        }
                    657:        return (NULL);
                    658: }
                    659:
                    660: static sdlahw_t*
                    661: sdla_hw_register(sdlahw_card_t *card, int cpu_no, int irq, void *dev)
                    662: {
                    663:        sdlahw_t        *new_hw, *last_hw;
                    664:
                    665:        new_hw = sdla_hw_search(card->atype, card->slot_no,
                    666:            card->bus_no, cpu_no);
                    667:        if (new_hw)
                    668:                return (new_hw);
                    669:
                    670:        new_hw = malloc(sizeof(sdlahw_t), M_DEVBUF, M_NOWAIT);
                    671:        if (!new_hw)
                    672:                return (NULL);
                    673:
                    674:        bzero(new_hw, sizeof(sdlahw_t));
                    675:
                    676:        new_hw->cpu_no  = cpu_no;
                    677:        new_hw->irq     = irq;
                    678:        new_hw->hwcard  = card;
                    679: #if 0
                    680:        new_hw->dev     = dev;
                    681: #endif
                    682:        new_hw->magic   = SDLAHW_MAGIC;
                    683:        card->used++;
                    684:
                    685:        LIST_FOREACH(last_hw, &sdlahw_head, next) {
                    686:                if (!LIST_NEXT(last_hw, next))
                    687:                        break;
                    688:        }
                    689:        if (last_hw)
                    690:                LIST_INSERT_AFTER(last_hw, new_hw, next);
                    691:        else
                    692:                LIST_INSERT_HEAD(&sdlahw_head, new_hw, next);
                    693:
                    694:        return (new_hw);
                    695: }
                    696:
                    697: #if 0
                    698: static int
                    699: sdla_hw_unregister(sdlahw_card_t* hwcard, int cpu_no)
                    700: {
                    701:        sdlahw_t*       tmp_hw;
                    702:        int             i;
                    703:
                    704:        LIST_FOREACH(tmp_hw, &sdlahw_head, next) {
                    705:                if (tmp_hw->hwcard != hwcard)
                    706:                        continue;
                    707:
                    708:                if (tmp_hw->cpu_no == cpu_no)
                    709:                        break;
                    710:        }
                    711:
                    712:        if (tmp_hw == NULL) {
                    713:                log(LOG_INFO,
                    714:                "Error: Failed to find device (slot=%d,bus=%d,cpu=%c)\n",
                    715:                hwcard->slot_no, hwcard->bus_no, SDLA_GET_CPU(cpu_no));
                    716:                return (EFAULT);
                    717:        }
                    718:        if (tmp_hw->used) {
                    719:                log(LOG_INFO,
                    720:                "Error: Device is still in used (slot=%d,bus=%d,cpu=%c,%d)\n",
                    721:                                hwcard->slot_no,
                    722:                                hwcard->bus_no,
                    723:                                SDLA_GET_CPU(cpu_no),
                    724:                                hwcard->used);
                    725:                return (EBUSY);
                    726:        }
                    727:
                    728:        tmp_hw->hwprobe = NULL;
                    729:        tmp_hw->hwcard = NULL;
                    730:        hwcard->used--;                 /* Decrement card usage */
                    731:        LIST_REMOVE(tmp_hw, next);
                    732:        free(tmp_hw, M_DEVBUF);
                    733:
                    734:        return (0);
                    735: }
                    736: #endif
                    737:
                    738: static sdlahw_t*
                    739: sdla_hw_search(u_int16_t atype, int slot_no, int bus_no, int cpu_no)
                    740: {
                    741:        sdlahw_t*       tmp_hw;
                    742:
                    743:
                    744:        LIST_FOREACH(tmp_hw, &sdlahw_head, next) {
                    745:                if (tmp_hw->hwcard == NULL) {
                    746:                        log(LOG_INFO,
                    747:                        "Critical Error: sdla_cpu_search: line %d\n",
                    748:                                        __LINE__);
                    749:                        // XXX REMOVE in LIST_FOREACH
                    750:                        LIST_REMOVE(tmp_hw, next);
                    751:                        continue;
                    752:                }
                    753:                if (tmp_hw->hwcard->atype != atype) {
                    754:                        // XXX why ???
                    755:                        LIST_REMOVE(tmp_hw, next);
                    756:                        continue;
                    757:                }
                    758:                if (tmp_hw->hwcard->slot_no == slot_no &&
                    759:                    tmp_hw->hwcard->bus_no == bus_no &&
                    760:                    tmp_hw->cpu_no == cpu_no)
                    761:                        return (tmp_hw);
                    762:        }
                    763:
                    764:        return (NULL);
                    765: }
                    766:
                    767:
                    768: /*
                    769:  * Set up adapter.
                    770:  * o detect adapter type
                    771:  * o set up adapter shared memory
                    772:  * Return:     0       ok.
                    773:  *             < 0     error
                    774:  */
                    775:
                    776: int
                    777: sdla_setup(void *phw)
                    778: {
                    779:        sdlahw_card_t*  hwcard = NULL;
                    780:        sdlahw_t*       hw = (sdlahw_t*)phw;
                    781:        int             err=0;
                    782:
                    783:        WAN_ASSERT(hw == NULL);
                    784:        SDLA_MAGIC(hw);
                    785:        WAN_ASSERT(hw->hwcard == NULL);
                    786:        hwcard = hw->hwcard;
                    787:        switch (hwcard->type) {
                    788:        case SDLA_AFT:
                    789:                break;
                    790:
                    791:        default:
                    792:                log(LOG_INFO, "%s: Invalid card type %x\n",
                    793:                                hw->devname, hw->hwcard->type);
                    794:                return (EINVAL);
                    795:        }
                    796:
                    797:        hw->dpmsize = SDLA_WINDOWSIZE;
                    798:
                    799:        err = sdla_detect(hw);
                    800:        return (err);
                    801: }
                    802:
                    803:
                    804: /*
                    805:  * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
                    806:  */
                    807: int
                    808: sdla_down(void *phw)
                    809: {
                    810:        sdlahw_card_t*  card = NULL;
                    811:        sdlahw_t*       hw = (sdlahw_t*)phw;
                    812:
                    813:        WAN_ASSERT(hw == NULL);
                    814:        SDLA_MAGIC(hw);
                    815:        WAN_ASSERT(hw->hwcard == NULL);
                    816:        card = hw->hwcard;
                    817:        switch (card->type) {
                    818:        case SDLA_AFT:
                    819:                /* free up the allocated virtual memory */
                    820:                if (hw->status & SDLA_MEM_MAPPED) {
                    821:                        bus_space_unmap(hw->hwcard->memt,
                    822:                                        hw->dpmbase,
                    823:                                        XILINX_PCI_MEM_SIZE);
                    824:                        hw->status &= ~SDLA_MEM_MAPPED;
                    825:                }
                    826:                break;
                    827:
                    828:        default:
                    829:                return (EINVAL);
                    830:        }
                    831:        return (0);
                    832: }
                    833:
                    834: /*
                    835:  * Read the hardware interrupt status.
                    836:  */
                    837: int
                    838: sdla_read_int_stat(void *phw, u_int32_t *int_status)
                    839: {
                    840:        sdlahw_card_t*  card = NULL;
                    841:        sdlahw_t*       hw = (sdlahw_t*)phw;
                    842:
                    843:        WAN_ASSERT(hw == NULL);
                    844:        SDLA_MAGIC(hw);
                    845:        WAN_ASSERT(hw->hwcard == NULL);
                    846:        card = hw->hwcard;
                    847:        switch (card->type) {
                    848:        case SDLA_AFT:
                    849:                sdla_pci_read_config_dword(hw, PCI_INT_STATUS, int_status);
                    850:        }
                    851:        return (0);
                    852: }
                    853:
                    854:
                    855: /*
                    856:  * Generate an interrupt to adapter's CPU.
                    857:  */
                    858: int
                    859: sdla_cmd(void *phw, unsigned long offset, wan_mbox_t *mbox)
                    860: {
                    861:        sdlahw_t        *hw = (sdlahw_t*)phw;
                    862:        int              len = sizeof(wan_cmd_t);
                    863:        int              err = 0;
                    864:        u_int8_t         value;
                    865:
                    866:        SDLA_MAGIC(hw);
                    867:        len += mbox->wan_data_len;
                    868:
                    869:        sdla_peek(hw, offset, (void*)&value, 1);
                    870:        if (value != 0x00) {
                    871:                log(LOG_INFO, "%s: opp flag set on entry to sdla_exec!\n",
                    872:                                hw->devname);
                    873:                return (0);
                    874:        }
                    875:        mbox->wan_opp_flag = 0x00;
                    876:        sdla_poke(hw, offset, (void*)mbox, len);
                    877:
                    878:        err = sdla_exec(hw, offset);
                    879:        if (!err) {
                    880:                log(LOG_INFO, "%s: Command 0x%02X failed!\n",
                    881:                                        hw->devname, mbox->wan_command);
                    882:                return (WAN_CMD_TIMEOUT);
                    883:        }
                    884:        sdla_peek(hw, offset, (void*)mbox, sizeof(wan_cmd_t));
                    885:        if (mbox->wan_data_len) {
                    886:                sdla_peek(hw, offset+offsetof(wan_mbox_t, wan_data),
                    887:                    mbox->wan_data, mbox->wan_data_len);
                    888:        }
                    889:
                    890:        return (mbox->wan_return_code);
                    891: }
                    892:
                    893: /*
                    894:  * Execute Adapter Command.
                    895:  * o Set exec flag.
                    896:  * o Busy-wait until flag is reset.
                    897:  * o Return number of loops made, or 0 if command timed out.
                    898:  */
                    899: static int
                    900: sdla_exec(sdlahw_t *hw, unsigned long offset)
                    901: {
                    902:        volatile unsigned long  tstop;
                    903:        volatile unsigned long  nloops;
                    904:        u_int8_t                value;
                    905:
                    906:        value = 0x01;
                    907:        sdla_poke(hw, offset, (void*)&value, 1);
                    908:        tstop = ticks + EXEC_TIMEOUT;
                    909:
                    910:        sdla_peek(hw, offset, (void*)&value, 1);
                    911:        for (nloops = 1; value == 0x01; ++ nloops) {
                    912:                DELAY(EXEC_DELAY);
                    913:                if (ticks > tstop || nloops > MAX_NLOOPS) {
                    914:                        log(LOG_INFO, "%s: Timeout %lu ticks (max=%lu) "
                    915:                            "loops %lu (max=%u)\n", hw->devname,
                    916:                            (ticks-tstop+EXEC_TIMEOUT),
                    917:                            (unsigned long)EXEC_TIMEOUT, nloops, MAX_NLOOPS);
                    918:                        return (0);             /* time is up! */
                    919:                }
                    920:                sdla_peek(hw, offset, (void*)&value, 1);
                    921:        }
                    922:
                    923:        return (nloops);
                    924: }
                    925:
                    926:
                    927: /*
                    928:  * Read absolute adapter memory.
                    929:  * Transfer data from adapter's memory to data buffer.
                    930:  *
                    931:  * Note:
                    932:  * Care should be taken when crossing dual-port memory window boundary.
                    933:  * This function is not atomic, so caller must disable interrupt if
                    934:  * interrupt routines are accessing adapter shared memory.
                    935:  */
                    936: int
                    937: sdla_peek(void *phw, unsigned long addr, void *buf, unsigned len)
                    938: {
                    939:        sdlahw_card_t*  card = NULL;
                    940:        sdlahw_t*       hw = (sdlahw_t*)phw;
                    941:        int err = 0;
                    942:
                    943:        WAN_ASSERT(hw == NULL);
                    944:        SDLA_MAGIC(hw);
                    945:        WAN_ASSERT(hw->hwcard == NULL);
                    946:        card = hw->hwcard;
                    947:        if (addr + len > hw->memory)    /* verify arguments */
                    948:                return (EINVAL);
                    949:
                    950:        switch (card->type) {
                    951:        case SDLA_AFT:
                    952:                sdla_peek_by_4(hw, addr, buf, len);
                    953:                break;
                    954:
                    955:        default:
                    956:                log(LOG_INFO, "%s: Invalid card type 0x%X\n",
                    957:                        __FUNCTION__,card->type);
                    958:                err = (EINVAL);
                    959:                break;
                    960:        }
                    961:        return (err);
                    962: }
                    963:
                    964:
                    965: /*
                    966:  * Read data from adapter's memory to a data buffer in 4-byte chunks.
                    967:  * Note that we ensure that the SDLA memory address is on a 4-byte boundary
                    968:  * before we begin moving the data in 4-byte chunks.
                    969: */
                    970: static void
                    971: sdla_peek_by_4(sdlahw_t *hw, unsigned long offset, void *buf, unsigned int len)
                    972: {
                    973:        /* byte copy data until we get to a 4-byte boundary */
                    974:        while (len && (offset & 0x03)) {
                    975:                sdla_bus_read_1(hw, offset++, (u_int8_t*)buf);
                    976:                ((u_int8_t *)buf)++;
                    977:                len--;
                    978:        }
                    979:
                    980:        /* copy data in 4-byte chunks */
                    981:        while (len >= 4) {
                    982:                sdla_bus_read_4(hw, offset, (u_int32_t*)buf);
                    983:                (u_int8_t*)buf += 4;
                    984:                offset += 4;
                    985:                len -= 4;
                    986:        }
                    987:
                    988:        /* byte copy any remaining data */
                    989:        while (len) {
                    990:                sdla_bus_read_1(hw, offset++, (u_int8_t*)buf);
                    991:                ((u_int8_t *)buf)++;
                    992:                len--;
                    993:        }
                    994: }
                    995:
                    996: /*
                    997:  * Write Absolute Adapter Memory.
                    998:  * Transfer data from data buffer to adapter's memory.
                    999:  *
                   1000:  * Note:
                   1001:  * Care should be taken when crossing dual-port memory window boundary.
                   1002:  * This function is not atomic, so caller must disable interrupt if
                   1003:  * interrupt routines are accessing adapter shared memory.
                   1004:  */
                   1005: int
                   1006: sdla_poke(void *phw, unsigned long addr, void *buf, unsigned len)
                   1007: {
                   1008:        sdlahw_card_t*  card = NULL;
                   1009:        sdlahw_t*       hw = (sdlahw_t*)phw;
                   1010:        int err = 0;
                   1011:
                   1012:        WAN_ASSERT(hw == NULL);
                   1013:        SDLA_MAGIC(hw);
                   1014:        WAN_ASSERT(hw->hwcard == NULL);
                   1015:        card = hw->hwcard;
                   1016:        if (addr + len > hw->memory) {  /* verify arguments */
                   1017:                return (EINVAL);
                   1018:        }
                   1019:
                   1020:        switch (card->type) {
                   1021:        case SDLA_AFT:
                   1022:                sdla_poke_by_4(hw, addr, buf, len);
                   1023:                break;
                   1024:
                   1025:        default:
                   1026:                log(LOG_INFO, "%s: Invalid card type 0x%X\n",
                   1027:                        __FUNCTION__,card->type);
                   1028:                err = (EINVAL);
                   1029:                break;
                   1030:        }
                   1031:        return (err);
                   1032: }
                   1033:
                   1034:
                   1035: /*
                   1036:  * Write from a data buffer to adapter's memory in 4-byte chunks.
                   1037:  * Note that we ensure that the SDLA memory address is on a 4-byte boundary
                   1038:  * before we begin moving the data in 4-byte chunks.
                   1039: */
                   1040: static void
                   1041: sdla_poke_by_4(sdlahw_t *hw, unsigned long offset, void *buf, unsigned int len)
                   1042: {
                   1043:        /* byte copy data until we get to a 4-byte boundary */
                   1044:        while (len && (offset & 0x03)) {
                   1045:                sdla_bus_write_1(hw, offset++, *(char *)buf);
                   1046:                ((char *)buf) ++;
                   1047:                len --;
                   1048:        }
                   1049:
                   1050:        /* copy data in 4-byte chunks */
                   1051:        while (len >= 4) {
                   1052:                sdla_bus_write_4(hw, offset, *(unsigned long *)buf);
                   1053:                offset += 4;
                   1054:                (char*)buf += 4;
                   1055:                len -= 4;
                   1056:        }
                   1057:
                   1058:        /* byte copy any remaining data */
                   1059:        while (len) {
                   1060:                sdla_bus_write_1(hw, offset++, *(char *)buf);
                   1061:                ((char *)buf) ++;
                   1062:                len --;
                   1063:        }
                   1064: }
                   1065:
                   1066: int
                   1067: sdla_poke_byte(void *phw, unsigned long offset, u_int8_t value)
                   1068: {
                   1069:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1070:
                   1071:        SDLA_MAGIC(hw);
                   1072:        /* Sangoma ISA card sdla_bus_write_1(hw, offset, value); */
                   1073:        sdla_poke(hw, offset, (void*)&value, 1);
                   1074:        return (0);
                   1075: }
                   1076:
                   1077: int
                   1078: sdla_set_bit(void *phw, unsigned long offset, u_int8_t value)
                   1079: {
                   1080:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1081:        u_int8_t         tmp;
                   1082:
                   1083:        SDLA_MAGIC(hw);
                   1084:        /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &tmp); */
                   1085:        sdla_peek(hw, offset, (void*)&tmp, 1);
                   1086:        tmp |= value;
                   1087:        /* Sangoma ISA card -> sdla_bus_write_1(hw, offset, tmp); */
                   1088:        sdla_poke(hw, offset, (void*)&tmp, 1);
                   1089:        return (0);
                   1090: }
                   1091:
                   1092: int
                   1093: sdla_clear_bit(void *phw, unsigned long offset, u_int8_t value)
                   1094: {
                   1095:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1096:        u_int8_t         tmp;
                   1097:
                   1098:        SDLA_MAGIC(hw);
                   1099:        /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &tmp); */
                   1100:        sdla_peek(hw, offset, (void*)&tmp, 1);
                   1101:        tmp &= ~value;
                   1102:        /* Sangoma ISA card -> sdla_bus_write_1(hw, offset, tmp); */
                   1103:        sdla_poke(hw, offset, (void*)&tmp, 1);
                   1104:        return (0);
                   1105: }
                   1106:
                   1107: /*
                   1108:  * Find the AFT HDLC PCI adapter in the PCI bus.
                   1109:  * Return the number of AFT adapters found (0 if no adapter found).
                   1110:  */
                   1111: static int
                   1112: sdla_detect_aft(sdlahw_t *hw)
                   1113: {
                   1114:        sdlahw_card_t   *card;
                   1115:        u_int16_t        ut_u16;
                   1116:
                   1117:        WAN_ASSERT(hw == NULL);
                   1118:        WAN_ASSERT(hw->hwcard == NULL);
                   1119:        card = hw->hwcard;
                   1120:        sdla_pci_read_config_dword(hw,
                   1121:            (hw->cpu_no == SDLA_CPU_A) ? PCI_IO_BASE_DWORD :
                   1122:            PCI_MEM_BASE0_DWORD, (u_int32_t*)&hw->mem_base_addr);
                   1123:        if (!hw->mem_base_addr) {
                   1124:                if (hw->cpu_no == SDLA_CPU_B) {
                   1125:                        printf("%s: No PCI memory allocated for CPU #B\n",
                   1126:                                        hw->devname);
                   1127:                } else {
                   1128:                        printf("%s: No PCI memory allocated to card\n",
                   1129:                                        hw->devname);
                   1130:                }
                   1131:                return (EINVAL);
                   1132:        }
                   1133: #ifdef DEBUG
                   1134:        log(LOG_INFO,  "%s: AFT PCI memory at 0x%lX\n",
                   1135:                                hw->devname, (unsigned long)hw->mem_base_addr);
                   1136: #endif /* DEBUG */
                   1137:        sdla_pci_read_config_byte(hw, PCI_INTLINE, (u_int8_t*)&hw->irq);
                   1138:        if (hw->irq == PCI_IRQ_NOT_ALLOCATED) {
                   1139:                printf("%s: IRQ not allocated to AFT adapter\n", hw->devname);
                   1140:                return (EINVAL);
                   1141:        }
                   1142:
                   1143: #ifdef DEBUG
                   1144:        log(LOG_INFO, "%s: IRQ %d allocated to the AFT PCI card\n",
                   1145:            hw->devname, hw->irq);
                   1146: #endif /* DEBUG */
                   1147:
                   1148:        hw->memory=XILINX_PCI_MEM_SIZE;
                   1149:
                   1150:        /* Map the physical PCI memory to virtual memory */
                   1151:        bus_space_map(hw->hwcard->memt, hw->mem_base_addr, XILINX_PCI_MEM_SIZE,
                   1152:            0, &hw->dpmbase);
                   1153:        if (!hw->dpmbase) {
                   1154:                printf("%s: couldn't map memory\n", hw->devname);
                   1155:                return (EINVAL);
                   1156:        }
                   1157:        hw->status |= SDLA_MEM_MAPPED;
                   1158:
                   1159:
                   1160:        /* Enable master operation on PCI and enable bar0 memory */
                   1161:        sdla_pci_read_config_word(hw, XILINX_PCI_CMD_REG, &ut_u16);
                   1162:        ut_u16 |=0x06;
                   1163:        sdla_pci_write_config_word(hw, XILINX_PCI_CMD_REG, ut_u16);
                   1164:
                   1165:        /* Set PCI Latency of 0xFF*/
                   1166:        sdla_pci_write_config_dword(hw, XILINX_PCI_LATENCY_REG,
                   1167:            XILINX_PCI_LATENCY);
                   1168:
                   1169:        return (0);
                   1170: }
                   1171:
                   1172:
                   1173: /*
                   1174:  * Detect adapter type.
                   1175:  */
                   1176: static int
                   1177: sdla_detect(sdlahw_t *hw)
                   1178: {
                   1179:        sdlahw_card_t   *card = NULL;
                   1180:        int              err = 0;
                   1181:
                   1182:        WAN_ASSERT(hw == NULL);
                   1183:        WAN_ASSERT(hw->hwcard == NULL);
                   1184:        card = hw->hwcard;
                   1185:        switch (card->type) {
                   1186:        case SDLA_AFT:
                   1187:                err = sdla_detect_aft(hw);
                   1188:                break;
                   1189:        }
                   1190:        if (err)
                   1191:                sdla_down(hw);
                   1192:
                   1193:        return (err);
                   1194: }
                   1195:
                   1196: int
                   1197: sdla_is_te1(void *phw)
                   1198: {
                   1199:        sdlahw_card_t   *hwcard = NULL;
                   1200:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1201:
                   1202:        WAN_ASSERT(hw == NULL);
                   1203:        SDLA_MAGIC(hw);
                   1204:        WAN_ASSERT(hw->hwcard == NULL);
                   1205:        hwcard = hw->hwcard;
                   1206:        switch (hwcard->atype) {
                   1207:        case S5144_ADPTR_1_CPU_T1E1:
                   1208:        case S5147_ADPTR_2_CPU_T1E1:
                   1209:        case S5148_ADPTR_1_CPU_T1E1:
                   1210:        case A101_ADPTR_1TE1:
                   1211:        case A101_ADPTR_2TE1:
                   1212:                return (1);
                   1213:        }
                   1214:        return (0);
                   1215: }
                   1216:
                   1217: int
                   1218: sdla_check_mismatch(void *phw, unsigned char media)
                   1219: {
                   1220:        sdlahw_card_t   *hwcard = NULL;
                   1221:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1222:
                   1223:        WAN_ASSERT(hw == NULL);
                   1224:        SDLA_MAGIC(hw);
                   1225:        WAN_ASSERT(hw->hwcard == NULL);
                   1226:        hwcard = hw->hwcard;
                   1227:        if (media == WAN_MEDIA_T1 ||
                   1228:            media == WAN_MEDIA_E1) {
                   1229:                if (hwcard->atype != S5144_ADPTR_1_CPU_T1E1 &&
                   1230:                    hwcard->atype != S5147_ADPTR_2_CPU_T1E1 &&
                   1231:                    hwcard->atype != S5148_ADPTR_1_CPU_T1E1) {
                   1232:                        log(LOG_INFO, "%s: Error: Card type mismatch: "
                   1233:                            "User=T1/E1 Actual=%s\n", hw->devname,
                   1234:                            SDLA_ADPTR_DECODE(hwcard->atype));
                   1235:                        return (EIO);
                   1236:                }
                   1237:                hwcard->atype = S5144_ADPTR_1_CPU_T1E1;
                   1238:
                   1239:        } else if (media == WAN_MEDIA_56K) {
                   1240:                if (hwcard->atype != S5145_ADPTR_1_CPU_56K) {
                   1241:                        log(LOG_INFO, "%s: Error: Card type mismatch: "
                   1242:                            "User=56K Actual=%s\n", hw->devname,
                   1243:                            SDLA_ADPTR_DECODE(hwcard->atype));
                   1244:                        return (EIO);
                   1245:                }
                   1246:        } else {
                   1247:                if (hwcard->atype == S5145_ADPTR_1_CPU_56K ||
                   1248:                    hwcard->atype == S5144_ADPTR_1_CPU_T1E1 ||
                   1249:                    hwcard->atype == S5147_ADPTR_2_CPU_T1E1 ||
                   1250:                    hwcard->atype == S5148_ADPTR_1_CPU_T1E1) {
                   1251:                        log(LOG_INFO, "%s: Error: Card type mismatch: "
                   1252:                            "User=S514(1/2/3) Actual=%s\n", hw->devname,
                   1253:                            SDLA_ADPTR_DECODE(hwcard->atype));
                   1254:                        return (EIO);
                   1255:                }
                   1256:        }
                   1257:
                   1258:        return (0);
                   1259: }
                   1260:
                   1261: int
                   1262: sdla_getcfg(void *phw, int type, void *value)
                   1263: {
                   1264:        sdlahw_t*       hw = (sdlahw_t*)phw;
                   1265:        sdlahw_card_t *hwcard;
                   1266:
                   1267:        WAN_ASSERT(hw == NULL);
                   1268:        SDLA_MAGIC(hw);
                   1269:        WAN_ASSERT(hw->hwcard == NULL);
                   1270:        hwcard = hw->hwcard;
                   1271:        switch (type) {
                   1272:        case SDLA_CARDTYPE:
                   1273:                *(u_int16_t*)value = hwcard->type;
                   1274:                break;
                   1275:        case SDLA_MEMBASE:
                   1276:                *(bus_space_handle_t*)value = hw->dpmbase;
                   1277:                break;
                   1278:        case SDLA_MEMEND:
                   1279:                *(u_int32_t*)value = ((unsigned long)hw->dpmbase +
                   1280:                    hw->dpmsize - 1);
                   1281:                break;
                   1282:        case SDLA_MEMSIZE:
                   1283:                *(u_int16_t*)value = hw->dpmsize;
                   1284:                break;
                   1285:        case SDLA_MEMORY:
                   1286:                *(u_int32_t*)value = hw->memory;
                   1287:                break;
                   1288:        case SDLA_IRQ:
                   1289:                *(u_int16_t*)value = hw->irq;
                   1290:                break;
                   1291:        case SDLA_ADAPTERTYPE:
                   1292:                *(u_int16_t*)value = hwcard->atype;
                   1293:                break;
                   1294:        case SDLA_CPU:
                   1295:                *(u_int16_t*)value = hw->cpu_no;
                   1296:                break;
                   1297:        case SDLA_SLOT:
                   1298:                *(u_int16_t*)value = hwcard->slot_no;
                   1299:                break;
                   1300:        case SDLA_BUS:
                   1301:                *(u_int16_t*)value = hwcard->bus_no;
                   1302:                break;
                   1303:        case SDLA_DMATAG:
                   1304:                *(bus_dma_tag_t*)value = hwcard->pa.pa_dmat;
                   1305:                break;
                   1306:        case SDLA_PCIEXTRAVER:
                   1307:                *(u_int8_t*)value = hwcard->pci_extra_ver;
                   1308:                break;
                   1309:        case SDLA_BASEADDR:
                   1310:                *(u_int32_t*)value = hw->mem_base_addr;
                   1311:                break;
                   1312:        }
                   1313:        return (0);
                   1314: }
                   1315:
                   1316:
                   1317: int
                   1318: sdla_get_hwcard(void *phw, void **phwcard)
                   1319: {
                   1320:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1321:
                   1322:        WAN_ASSERT(hw == NULL);
                   1323:        SDLA_MAGIC(hw);
                   1324:
                   1325:        *phwcard = hw->hwcard;
                   1326:        return (0);
                   1327: }
                   1328:
                   1329:
                   1330: int
                   1331: sdla_get_hwprobe(void *phw, void **str)
                   1332: {
                   1333:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1334:
                   1335:        WAN_ASSERT(hw == NULL);
                   1336:        SDLA_MAGIC(hw);
                   1337:
                   1338:        if (hw->hwprobe)
                   1339:                *str = hw->hwprobe->hw_info;
                   1340:
                   1341:        return (0);
                   1342: }
                   1343:
                   1344: int
                   1345: sdla_bus_write_1(void *phw, unsigned int offset, u_int8_t value)
                   1346: {
                   1347:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1348:
                   1349:        WAN_ASSERT(hw == NULL);
                   1350:        SDLA_MAGIC(hw);
                   1351:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1352:                return (0);
                   1353:        bus_space_write_1(hw->hwcard->memt, hw->dpmbase, offset, value);
                   1354:        return (0);
                   1355: }
                   1356:
                   1357: int
                   1358: sdla_bus_write_2(void *phw, unsigned int offset, u_int16_t value)
                   1359: {
                   1360:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1361:
                   1362:        WAN_ASSERT(hw == NULL);
                   1363:        SDLA_MAGIC(hw);
                   1364:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1365:                return (0);
                   1366:        bus_space_write_2(hw->hwcard->memt, hw->dpmbase, offset, value);
                   1367:        return (0);
                   1368: }
                   1369:
                   1370: int
                   1371: sdla_bus_write_4(void *phw, unsigned int offset, u_int32_t value)
                   1372: {
                   1373:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1374:
                   1375:        WAN_ASSERT(hw == NULL);
                   1376:        SDLA_MAGIC(hw);
                   1377:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1378:                return (0);
                   1379:        bus_space_write_4(hw->hwcard->memt, hw->dpmbase, offset, value);
                   1380:        return (0);
                   1381: }
                   1382:
                   1383: int
                   1384: sdla_bus_read_1(void *phw, unsigned int offset, u_int8_t *value)
                   1385: {
                   1386:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1387:
                   1388:        WAN_ASSERT2(hw == NULL, 0);
                   1389:        SDLA_MAGIC(hw);
                   1390:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1391:                return (0);
                   1392:        *value = bus_space_read_1(hw->hwcard->memt, hw->dpmbase, offset);
                   1393:        return (0);
                   1394: }
                   1395:
                   1396: int
                   1397: sdla_bus_read_2(void *phw, unsigned int offset, u_int16_t *value)
                   1398: {
                   1399:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1400:
                   1401:        WAN_ASSERT2(hw == NULL, 0);
                   1402:        SDLA_MAGIC(hw);
                   1403:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1404:                return (0);
                   1405:        *value = bus_space_read_2(hw->hwcard->memt, hw->dpmbase, offset);
                   1406:        return (0);
                   1407: }
                   1408:
                   1409: int
                   1410: sdla_bus_read_4(void *phw, unsigned int offset, u_int32_t *value)
                   1411: {
                   1412:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1413:
                   1414:        WAN_ASSERT2(hw == NULL, 0);
                   1415:        WAN_ASSERT2(hw->dpmbase == 0, 0);
                   1416:        SDLA_MAGIC(hw);
                   1417:        if (!(hw->status & SDLA_MEM_MAPPED))
                   1418:                return (0);
                   1419:        *value = bus_space_read_4(hw->hwcard->memt, hw->dpmbase, offset);
                   1420:        return (0);
                   1421: }
                   1422:
                   1423: static int
                   1424: sdla_pci_read_config_dword(void *phw, int reg, u_int32_t *value)
                   1425: {
                   1426:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1427:        sdlahw_card_t   *hwcard;
                   1428:
                   1429:        WAN_ASSERT(hw == NULL);
                   1430:        SDLA_MAGIC(hw);
                   1431:        WAN_ASSERT(hw->hwcard == NULL);
                   1432:        hwcard = hw->hwcard;
                   1433:        *value = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
                   1434:        return (0);
                   1435: }
                   1436:
                   1437: static int
                   1438: sdla_pci_read_config_word(void *phw, int reg, u_int16_t *value)
                   1439: {
                   1440:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1441:        sdlahw_card_t   *hwcard;
                   1442:        u_int32_t        tmp = 0x00;
                   1443:
                   1444:        WAN_ASSERT(hw == NULL);
                   1445:        SDLA_MAGIC(hw);
                   1446:        WAN_ASSERT(hw->hwcard == NULL);
                   1447:        hwcard = hw->hwcard;
                   1448:        tmp = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
                   1449:        *value = (u_int16_t)((tmp >> 16) & 0xFFFF);
                   1450:        return (0);
                   1451: }
                   1452:
                   1453: static int
                   1454: sdla_pci_read_config_byte(void *phw, int reg, u_int8_t *value)
                   1455: {
                   1456:        sdlahw_t        *hw = (sdlahw_t*)phw;
                   1457:        sdlahw_card_t   *hwcard;
                   1458:        u_int32_t        tmp = 0x00;
                   1459:
                   1460:        WAN_ASSERT(hw == NULL);
                   1461:        SDLA_MAGIC(hw);
                   1462:        WAN_ASSERT(hw->hwcard == NULL);
                   1463:        hwcard = hw->hwcard;
                   1464:        tmp = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
                   1465:        *value = (u_int8_t)(tmp & 0xFF);
                   1466:        return (0);
                   1467: }
                   1468:
                   1469: static int
                   1470: sdla_pci_write_config_dword(void *phw, int reg, u_int32_t value)
                   1471: {
                   1472:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1473:        sdlahw_card_t *card;
                   1474:
                   1475:        WAN_ASSERT(hw == NULL);
                   1476:        SDLA_MAGIC(hw);
                   1477:        WAN_ASSERT(hw->hwcard == NULL);
                   1478:        card = hw->hwcard;
                   1479:        pci_conf_write(card->pa.pa_pc, card->pa.pa_tag, reg, value);
                   1480:        return (0);
                   1481: }
                   1482:
                   1483: static int
                   1484: sdla_pci_write_config_word(void *phw, int reg, u_int16_t value)
                   1485: {
                   1486:        sdlahw_t *hw = (sdlahw_t*)phw;
                   1487:        sdlahw_card_t *card;
                   1488:
                   1489:        WAN_ASSERT(hw == NULL);
                   1490:        SDLA_MAGIC(hw);
                   1491:        WAN_ASSERT(hw->hwcard == NULL);
                   1492:        card = hw->hwcard;
                   1493:        pci_conf_write(card->pa.pa_pc, card->pa.pa_tag, reg, value);
                   1494:        return (0);
                   1495: }

CVSweb