root/dev/pci/if_sandrv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sdla_hw_probe_t
  2. sdlahw_card_t
  3. sdlahw_t
  4. san_match
  5. san_attach
  6. sdladrv_init
  7. sdladrv_exit
  8. sdla_save_hw_probe
  9. sdla_aft_hw_select
  10. sdla_pci_probe
  11. sdla_intr_establish
  12. sdla_intr_disestablish
  13. sdla_get_hw_devices
  14. sdla_get_hw_adptr_cnt
  15. sdla_card_register
  16. sdla_card_unregister
  17. sdla_card_search
  18. sdla_hw_register
  19. sdla_hw_unregister
  20. sdla_hw_search
  21. sdla_setup
  22. sdla_down
  23. sdla_read_int_stat
  24. sdla_cmd
  25. sdla_exec
  26. sdla_peek
  27. sdla_peek_by_4
  28. sdla_poke
  29. sdla_poke_by_4
  30. sdla_poke_byte
  31. sdla_set_bit
  32. sdla_clear_bit
  33. sdla_detect_aft
  34. sdla_detect
  35. sdla_is_te1
  36. sdla_check_mismatch
  37. sdla_getcfg
  38. sdla_get_hwcard
  39. sdla_get_hwprobe
  40. sdla_bus_write_1
  41. sdla_bus_write_2
  42. sdla_bus_write_4
  43. sdla_bus_read_1
  44. sdla_bus_read_2
  45. sdla_bus_read_4
  46. sdla_pci_read_config_dword
  47. sdla_pci_read_config_word
  48. sdla_pci_read_config_byte
  49. sdla_pci_write_config_dword
  50. sdla_pci_write_config_word

    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 }

/* [<][>][^][v][top][bottom][index][help] */