LCOV - code coverage report
Current view: top level - dev/cardbus - rbus.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 73 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: rbus.c,v 1.16 2010/09/22 02:28:37 jsg Exp $   */
       2             : /*      $NetBSD: rbus.c,v 1.3 1999/11/06 06:20:53 soren Exp $   */
       3             : /*
       4             :  * Copyright (c) 1999
       5             :  *     HAYAKAWA Koichi.  All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      20             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : 
      28             : #include <sys/param.h>
      29             : #include <sys/systm.h>
      30             : #include <sys/device.h>
      31             : #include <sys/malloc.h>
      32             : #include <sys/extent.h>
      33             : 
      34             : #include <machine/bus.h>
      35             : 
      36             : #include <dev/cardbus/rbus.h>
      37             : 
      38             : /* #define RBUS_DEBUG */
      39             : 
      40             : #if defined RBUS_DEBUG
      41             : #define STATIC
      42             : #define DPRINTF(a) printf a
      43             : #else
      44             : #ifdef DDB
      45             : #define STATIC
      46             : #else
      47             : #define STATIC static
      48             : #endif
      49             : #define DPRINTF(a)
      50             : #endif
      51             : 
      52             : 
      53             : int
      54           0 : rbus_space_alloc(rbus_tag_t rbt, bus_addr_t addr, bus_size_t size,
      55             :     bus_addr_t mask, bus_addr_t align, int flags, bus_addr_t *addrp,
      56             :     bus_space_handle_t *bshp)
      57             : {
      58           0 :         return (rbus_space_alloc_subregion(rbt, rbt->rb_start, rbt->rb_end,
      59             :             addr, size, mask, align, flags, addrp, bshp));
      60             : }
      61             : 
      62             : int
      63           0 : rbus_space_alloc_subregion(rbus_tag_t rbt, bus_addr_t substart,
      64             :     bus_addr_t subend, bus_addr_t addr, bus_size_t size,
      65             :     bus_addr_t mask, bus_addr_t align, int flags, bus_addr_t *addrp,
      66             :     bus_space_handle_t *bshp)
      67             : {
      68           0 :         bus_addr_t decodesize = mask + 1;
      69             :         bus_addr_t boundary, search_addr;
      70             :         int val;
      71           0 :         u_long result;
      72             :         int exflags = EX_FAST | EX_NOWAIT | EX_MALLOCOK;
      73             : 
      74             :         DPRINTF(("rbus_space_alloc: addr %lx, size %lx, mask %lx, align %lx\n",
      75             :             (u_long)addr, (u_long)size, (u_long)mask, (u_long)align));
      76             : 
      77           0 :         if (mask == 0) {
      78             :                 /* FULL Decode */
      79             :                 decodesize = 0;
      80           0 :         }
      81             : 
      82           0 :         if (rbt->rb_flags == RBUS_SPACE_SHARE ||
      83           0 :             rbt->rb_flags == RBUS_SPACE_DEDICATE) {
      84             :                 /* rbt has its own sh_extent */
      85             : 
      86             :                 /* sanity check: the subregion [substart, subend] should be
      87             :                    smaller than the region included in sh_extent */
      88           0 :                 if (substart < rbt->rb_ext->ex_start ||
      89           0 :                     subend > rbt->rb_ext->ex_end) {
      90             :                         DPRINTF(("rbus: out of range\n"));
      91           0 :                         return (1);
      92             :                 }
      93             : 
      94           0 :                 if (decodesize == align) {
      95           0 :                         if (extent_alloc_subregion(rbt->rb_ext, substart,
      96             :                             subend, size, align, 0, 0, exflags, &result))
      97           0 :                                 return (1);
      98           0 :                 } else if (decodesize == 0) {
      99             :                         /* maybe, the register is overflowed. */
     100             : 
     101           0 :                         if (extent_alloc_subregion(rbt->rb_ext, addr,
     102           0 :                             addr + size, size, 1, 0, 0, exflags, &result))
     103           0 :                                 return (1);
     104             :                 } else {
     105           0 :                         boundary = decodesize > align ? decodesize : align;
     106             : 
     107           0 :                         search_addr = (substart & ~(boundary - 1)) + addr;
     108             : 
     109           0 :                         if (search_addr < substart)
     110           0 :                                 search_addr += boundary;
     111             : 
     112             :                         val = 1;
     113           0 :                         for (; search_addr + size <= subend;
     114           0 :                             search_addr += boundary) {
     115           0 :                                 val = extent_alloc_subregion(
     116           0 :                                     rbt->rb_ext,search_addr,
     117             :                                     search_addr + size, size, align, 0, 0,
     118             :                                     exflags, &result);
     119             :                                 DPRINTF(("rbus: trying [%lx:%lx] %lx\n",
     120             :                                     (u_long)search_addr,
     121             :                                     (u_long)search_addr + size,
     122             :                                     (u_long)align));
     123           0 :                                 if (val == 0)
     124             :                                         break;
     125             :                         }
     126             : 
     127           0 :                         if (val != 0) {
     128             :                                 /* no space found */
     129             :                                 DPRINTF(("rbus: no space found\n"));
     130           0 :                                 return (1);
     131             :                         }
     132             :                 }
     133             : 
     134           0 :                 if (md_space_map(rbt, result, size, flags, bshp)) {
     135             :                         /* map failed */
     136           0 :                         extent_free(rbt->rb_ext, result, size, exflags);
     137           0 :                         return (1);
     138             :                 }
     139             : 
     140           0 :                 if (addrp != NULL)
     141           0 :                         *addrp = result;
     142           0 :                 return (0);
     143             :         } else {
     144             :                 /* error!! */
     145             :                 DPRINTF(("rbus: no rbus type\n"));
     146           0 :                 return (1);
     147             :         }
     148           0 : }
     149             : 
     150             : int
     151           0 : rbus_space_free(rbus_tag_t rbt, bus_space_handle_t bsh, bus_size_t size,
     152             :     bus_addr_t *addrp)
     153             : {
     154             :         int exflags = EX_FAST | EX_NOWAIT;
     155           0 :         bus_addr_t addr;
     156             :         int status = 1;
     157             : 
     158           0 :         if (rbt->rb_flags == RBUS_SPACE_SHARE ||
     159           0 :             rbt->rb_flags == RBUS_SPACE_DEDICATE) {
     160           0 :                 md_space_unmap(rbt, bsh, size, &addr);
     161             : 
     162           0 :                 extent_free(rbt->rb_ext, addr, size, exflags);
     163             : 
     164             :                 status = 0;
     165           0 :         } else {
     166             :                 /* error. INVALID rbustag */
     167             :                 status = 1;
     168             :         }
     169             : 
     170           0 :         if (addrp != NULL)
     171           0 :                 *addrp = addr;
     172             : 
     173           0 :         return (status);
     174           0 : }
     175             : 
     176             : /*
     177             :  * rbus_tag_t
     178             :  * rbus_new_body(bus_space_tag_t bt,
     179             :  *               struct extent *ex, bus_addr_t start, bus_size_t end,
     180             :  *               int flags)
     181             :  *
     182             :  */
     183             : rbus_tag_t
     184           0 : rbus_new_body(bus_space_tag_t bt, struct extent *ex,
     185             :     bus_addr_t start, bus_addr_t end, int flags)
     186             : {
     187             :         rbus_tag_t rb;
     188             : 
     189           0 :         if ((rb = (rbus_tag_t)malloc(sizeof(struct rbustag), M_DEVBUF,
     190           0 :             M_NOWAIT)) == NULL) {
     191           0 :                 panic("no memory for rbus instance");
     192             :         }
     193             : 
     194           0 :         rb->rb_bt = bt;
     195           0 :         rb->rb_start = start;
     196           0 :         rb->rb_end = end;
     197           0 :         rb->rb_flags = flags;
     198           0 :         rb->rb_ext = ex;
     199             : 
     200             :         DPRINTF(("rbus_new_body: [%lx, %lx] type %s name [%s]\n",
     201             :             (u_long)start, (u_long)end,
     202             :            flags == RBUS_SPACE_SHARE ? "share" :
     203             :            flags == RBUS_SPACE_DEDICATE ? "dedicated" : "invalid",
     204             :            ex != NULL ? ex->ex_name : "noname"));
     205             : 
     206           0 :         return (rb);
     207             : }
     208             : 
     209             : /*
     210             :  * rbus_tag_t rbus_new_root_delegate(bus_space_tag, bus_addr_t,
     211             :  *                                   bus_size_t)
     212             :  *
     213             :  *  This function makes a root rbus instance.
     214             :  */
     215             : rbus_tag_t
     216           0 : rbus_new_root_delegate(bus_space_tag_t bt, bus_addr_t start, bus_size_t size)
     217             : {
     218             :         rbus_tag_t rb;
     219             :         struct extent *ex;
     220             : 
     221           0 :         if ((ex = extent_create("rbus root", start, start + size, M_DEVBUF,
     222           0 :             NULL, 0, EX_NOCOALESCE|EX_NOWAIT)) == NULL)
     223           0 :                 return (NULL);
     224             : 
     225           0 :         rb = rbus_new_body(bt, ex, start, start + size,
     226             :             RBUS_SPACE_DEDICATE);
     227             : 
     228           0 :         if (rb == NULL)
     229           0 :                 extent_destroy(ex);
     230             : 
     231           0 :         return (rb);
     232           0 : }
     233             : 
     234             : /*
     235             :  * rbus_tag_t rbus_new_root_share(bus_space_tag, struct extent *,
     236             :  *                                 bus_addr_t, bus_size_t)
     237             :  *
     238             :  *  This function makes a root rbus instance.
     239             :  */
     240             : rbus_tag_t
     241           0 : rbus_new_root_share(bus_space_tag_t bt, struct extent *ex, bus_addr_t start,
     242             :     bus_size_t size)
     243             : {
     244             :         /* sanity check */
     245           0 :         if (start < ex->ex_start || start + size > ex->ex_end) {
     246             :                 /* out of range: [start, size] should be contained in
     247             :                  * parent space
     248             :                  */
     249           0 :                 return (0);
     250             :                 /* Should I invoke panic? */
     251             :         }
     252             : 
     253           0 :         return (rbus_new_body(bt, ex, start, start + size,
     254             :             RBUS_SPACE_SHARE));
     255           0 : }

Generated by: LCOV version 1.13