The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bsif.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NecBSD: bsif.c,v 1.6 1997/10/31 17:43:40 honda Exp $   */
    2 /*
    3  * Copyright (c) HONDA Naofumi, KATO Takenori, 1996.  All rights reserved.
    4  * 
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer as
   11  *    the first lines of this file unmodified.
   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  * The name of the author may not be used to endorse or promote products
   16  * derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 #if     0
   31 /* WARNING: Any bug report must contain BS_REL_VERSION */
   32 #define BS_REL_VERSION  "NetBSD1.2/030" /* major jump */
   33 #endif
   34 
   35 #ifdef __NetBSD__
   36 #include <i386/Cbus/dev/bs/bsif.h>
   37 #endif  /* __NetBSD__ */
   38 #ifdef __FreeBSD__
   39 #include "bs.h"
   40 #include <i386/isa/bs/bsif.h>
   41 #endif  /* __FreeBSD__ */
   42 
   43 /**************************************************
   44  * DEVICE DECLARE
   45  **************************************************/
   46 #ifdef __NetBSD__
   47 static void bs_scsi_minphys __P((struct buf *));
   48 
   49 struct cfdriver bs_cd = {
   50         NULL, "bs", DV_DULL
   51 };
   52 
   53 struct scsi_device bs_dev = {
   54         NULL,   /* Use default error handler */
   55         NULL,   /* have a queue, served by this */
   56         NULL,   /* have no async handler */
   57         NULL,   /* Use default 'done' routine */
   58 };
   59 
   60 struct scsi_adapter pc98texa55bs = {
   61         bs_scsi_cmd,
   62         bs_scsi_minphys,
   63         bs_target_open,
   64         0,
   65 };
   66 #endif  /* __NetBSD__ */
   67 
   68 #ifdef __FreeBSD__
   69 static int bsprobe __P((struct isa_device *));
   70 static int bsattach __P((struct isa_device *));
   71 static int bsprint __P((void *, const char *));
   72 static void bs_scsi_minphys __P((struct buf *));
   73 static int bs_dmarangecheck __P((caddr_t, unsigned));
   74 
   75 struct isa_driver bsdriver = {
   76         bsprobe,
   77         bsattach,
   78         "bs"
   79 };
   80 
   81 struct scsi_device bs_dev = {
   82         NULL,   /* Use default error handler */
   83         NULL,   /* have a queue, served by this */
   84         NULL,   /* have no async handler */
   85         NULL,   /* Use default 'done' routine */
   86         "bs",
   87         0, {0, 0}
   88 };
   89 
   90 u_int32_t
   91 bs_adapter_info(unit)
   92         int unit;
   93 {
   94         return (1);
   95 }
   96 
   97 struct scsi_adapter pc98texa55bs = {
   98         bs_scsi_cmd,
   99         bs_scsi_minphys,
  100         bs_target_open,
  101         0,
  102         bs_adapter_info,
  103         "bs", {0, 0}
  104 };
  105 
  106 static u_short pc98_irq_ball[16] = {
  107         IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
  108         IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15
  109 };
  110 
  111 static struct bs_softc *bscdata[NBS];
  112 #endif  /* __FreeBSD__ */
  113 
  114 /*****************************************************************
  115  * OS <=> BS INTERFACE
  116  *****************************************************************/
  117 #ifdef __FreeBSD__
  118 static int
  119 bsprobe(dev)
  120         struct isa_device *dev;
  121 {
  122         struct bs_softc *bsc;
  123         int unit = dev->id_unit;
  124         u_int irq, drq;
  125         int i, rv = 0;
  126 
  127         if (unit >= NBS) {
  128                 printf("bs%d: unit number too high\n", unit);
  129                 return rv;
  130         }
  131         /*
  132          * Allocate a storage for us
  133          */
  134         if (bscdata[unit]) {
  135                 printf("bs%d: memory already allocated\n", unit);
  136                 return rv;
  137         }
  138         if (!(bsc = malloc(sizeof(struct bs_softc), M_TEMP, M_NOWAIT))) {
  139                 printf("bs%d cannot malloc!\n", unit);
  140                 return rv;
  141         }
  142         bzero(bsc, sizeof(struct bs_softc));
  143         bscdata[unit] = bsc;
  144         bsc->unit = unit;
  145 
  146         bsc->sc_cfgflags = DVCFG_MINOR(dev->id_flags);
  147         bsc->sc_hw = DVCFG_HW(&bshw_hwsel, DVCFG_MAJOR(dev->id_flags));
  148         if (bsc->sc_hw == NULL)
  149                 return rv;
  150 
  151         if ((bsc->sc_hw->hw_flags & BSHW_SMFIFO) &&
  152                         (dev->id_maddr != (caddr_t)MADDRUNK))
  153                 bsc->sm_offset = (u_long) dev->id_maddr;
  154         else
  155                 bsc->sm_offset = (u_long) 0;
  156 
  157         sprintf(bsc->sc_dvname, "bs%d", unit);
  158 
  159         if (dev->id_iobase == 0)
  160         {
  161                 printf("%s: iobase not specified. Assume default port(0x%x)\n",
  162                         bsc->sc_dvname, BSHW_DEFAULT_PORT);
  163                 dev->id_iobase = BSHW_DEFAULT_PORT;
  164         }
  165 
  166         bsc->sc_iobase = dev->id_iobase;
  167         irq = IRQUNK;
  168         drq = DRQUNK;
  169         if (bshw_board_probe(bsc, &drq, &irq))
  170                 goto bad;
  171 
  172         dev->id_irq = pc98_irq_ball[irq];
  173         dev->id_drq = (short)drq;
  174 
  175         /* initialize host queue and target info */
  176         bs_hostque_init(bsc);
  177         for (i = 0; i < NTARGETS; i++)
  178                 if (i != bsc->sc_hostid)
  179                         bs_init_target_info(bsc, i);
  180 
  181         /* initialize ccb queue */
  182         bs_init_ccbque(BS_MAX_CCB);
  183 
  184         /* scsi bus reset and restart */
  185         bsc->sc_hstate = BSC_BOOTUP;
  186         bsc->sc_retry = RETRIES;
  187         bsc->sc_wc = delaycount * 250;  /* about 1 sec */
  188         bs_reset_nexus(bsc);
  189 
  190         return BSHW_IOSZ;
  191 bad:
  192         return rv;
  193 }
  194 #endif  /* __FreeBSD__ */
  195 
  196 #ifdef __FreeBSD__
  197 static int
  198 #else   /* __NetBSD__ */
  199 int
  200 #endif  /* __NetBSD__ */
  201 bsprint(aux, name)
  202         void *aux;
  203         const char *name;
  204 {
  205 
  206         if (name != NULL)
  207                 printf("%s: scsibus ", name);
  208         return UNCONF;
  209 }
  210 
  211 #ifdef __FreeBSD__
  212 static int
  213 bsattach(dev)
  214         struct isa_device *dev;
  215 {
  216         int unit = dev->id_unit;
  217         struct bs_softc *bsc = bscdata[unit];
  218         struct scsibus_data *scbus;
  219 
  220         bsc->sc_link.adapter_unit = unit;
  221         bsc->sc_link.adapter_targ = bsc->sc_hostid;
  222         bsc->sc_link.flags = SDEV_BOUNCE;
  223         bsc->sc_link.opennings = XSMAX;
  224         bsc->sc_link.adapter_softc = bsc;
  225         bsc->sc_link.adapter = &pc98texa55bs;
  226         bsc->sc_link.device = &bs_dev;
  227 
  228         /*
  229          * Prepare the scsibus_data area for the upperlevel
  230          * scsi code.
  231          */
  232         scbus = scsi_alloc_bus();
  233         if (!scbus)
  234                 return 0;
  235         scbus->adapter_link = &bsc->sc_link;
  236         /*
  237          * ask the adapter what subunits are present
  238          */
  239         scsi_attachdevs(scbus);
  240         bs_start_timeout(bsc);
  241         return 1;
  242 }
  243 #endif  /* __FreeBSD__ */
  244 
  245 #ifdef __NetBSD__
  246 int
  247 bsintr(arg)
  248         void *arg;
  249 {
  250 
  251         return bs_sequencer((struct bs_softc *)arg);
  252 }
  253 #endif  /* __NetBSD__ */
  254 
  255 #ifdef __FreeBSD__
  256 void
  257 bsintr(unit)
  258         int unit;
  259 {
  260         (void)bs_sequencer(bscdata[unit]);
  261 }
  262 #endif  /* __FreeBSD__ */
  263 
  264 /*****************************************************************
  265  * JULIAN SCSI <=> BS INTERFACE
  266  *****************************************************************/
  267 static void
  268 bs_scsi_minphys(bp)
  269         struct buf *bp;
  270 {
  271 
  272         if (bp->b_bcount > BSDMABUFSIZ)
  273                 bp->b_bcount = BSDMABUFSIZ;
  274         minphys(bp);
  275 }
  276 
  277 XSBS_INT32T
  278 bs_target_open(sc, cf)
  279         struct scsi_link *sc;
  280         struct cfdata *cf;
  281 {
  282         u_int target = sc->target;
  283         struct bs_softc *bsc = (struct bs_softc *) (sc->adapter_softc);
  284         struct targ_info *ti = bsc->sc_ti[target];
  285         u_int flags;
  286 
  287         if ((bsc->sc_openf & (1 << target)) == 0)
  288                 return ENODEV;
  289 
  290         if ((flags = cf->cf_flags) == 0)
  291                 flags = BS_SCSI_DEFCFG;
  292 
  293         bs_setup_ctrl(ti, (u_int)sc->quirks, flags);
  294         return 0;
  295 }
  296 
  297 /*****************************************************************
  298  * BS MEMORY ALLOCATION INTERFACE
  299  *****************************************************************/
  300 #ifdef __NetBSD__
  301 void
  302 bs_alloc_buf(ti)
  303         struct targ_info *ti;
  304 {
  305         struct bs_softc *bsc = ti->ti_bsc;
  306         caddr_t addr, physaddr;
  307         bus_dma_segment_t seg;
  308         int rseg, error;
  309         u_int pages;
  310         extern int cold;
  311 
  312         /* XXX:
  313          * strategy change!
  314          * A) total memory >= 16M at boot: MAXBSIZE * 7 = 112k.
  315          * B) others:  4K * 7 = 28 K.
  316          */
  317         if (get_sysinfo(SYSINFO_MEMLEVEL) == MEM_LEVEL1 && cold != 0)
  318                 pages = 4;
  319         else
  320                 pages = 1;
  321         ti->bounce_size = NBPG * pages;
  322 
  323         addr = NULL;
  324         error = bus_dmamem_alloc(bsc->sc_dmat, ti->bounce_size, NBPG, 0,
  325                                  &seg, 1, &rseg, BUS_DMA_NOWAIT);
  326         if (rseg == 1 && error == 0)
  327                 error = bus_dmamem_map(bsc->sc_dmat, &seg, rseg,
  328                                        ti->bounce_size, &addr, BUS_DMA_NOWAIT);
  329         if (rseg != 1 || error != 0)
  330         {
  331                 ti->bounce_size = NBPG;
  332                 if ((addr = malloc(NBPG, M_DEVBUF, M_NOWAIT)) == NULL)
  333                         goto bad;
  334         }
  335 
  336         physaddr = (caddr_t) vtophys(addr);
  337         if ((u_int) physaddr >= RAM_END)
  338         {
  339                 /* XXX: mem from malloc only! */
  340                 free(addr, M_DEVBUF);
  341                 goto bad;
  342         }
  343 
  344         ti->bounce_addr = (u_int8_t *) addr;
  345         ti->bounce_phys = (u_int8_t *) physaddr;
  346         return;
  347 
  348 bad:
  349         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  350         printf("WARNING: this target is dislocated\n");
  351 }
  352 #endif  /* __NetBSD__ */
  353 
  354 #ifdef __FreeBSD__
  355 static int bs_dmarangecheck(caddr_t va, unsigned length)
  356 {
  357         vm_offset_t phys, priorpage = 0, endva;
  358 
  359         endva = (vm_offset_t)round_page(va+length);
  360         for (; va < (caddr_t)endva; va += PAGE_SIZE) {
  361                 phys = trunc_page(pmap_extract(pmap_kernel(), (vm_offset_t)va));
  362                 if (phys == 0)
  363                         panic("bs_dmarangecheck: no physical page present");
  364                 if (phys >= RAM_END)
  365                         return 1;
  366                 if (priorpage) {
  367                         if (priorpage + PAGE_SIZE != phys)
  368                                 return 1;
  369                 }
  370                 priorpage = phys;
  371         }
  372         return 0;
  373 }
  374 
  375 void
  376 bs_alloc_buf(ti)
  377         struct targ_info *ti;
  378 {
  379         caddr_t addr, physaddr;
  380 
  381 #if BS_BOUNCE_SIZE != 0
  382         ti->bounce_size = BS_BOUNCE_SIZE;
  383 #else
  384         ti->bounce_size = BSHW_NBPG;
  385 #endif
  386         /* Try malloc() first.  It works better if it works. */
  387         addr = malloc(ti->bounce_size, M_DEVBUF, M_NOWAIT);
  388         if (addr != NULL) {
  389                 if (bs_dmarangecheck(addr, ti->bounce_size) == 0) {
  390                         physaddr = (caddr_t) vtophys(addr);
  391                         ti->bounce_addr = (u_int8_t *) addr;
  392                         ti->bounce_phys = (u_int8_t *) physaddr;
  393                         return;
  394                 }
  395                 free(buf, M_DEVBUF);
  396         }
  397         addr = contigmalloc(ti->bounce_size, M_DEVBUF, M_NOWAIT,
  398                                                 0ul, RAM_END, 1ul, 0x10000ul);
  399         if (addr == NULL)
  400                 goto bad;
  401 
  402         physaddr = (caddr_t) vtophys(addr);
  403         if ((u_int) physaddr >= RAM_END)
  404         {
  405                 /* XXX:
  406                  * must free memory !
  407                  */
  408                 goto bad;
  409         }
  410 
  411         ti->bounce_addr = (u_int8_t *) addr;
  412         ti->bounce_phys = (u_int8_t *) physaddr;
  413         return;
  414 
  415 bad:
  416         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  417         printf("WARNING: this target is dislocated\n");
  418 }
  419 #endif  /* __FreeBSD__ */

Cache object: 1bdeaa98597f3990743d18cf21e487f8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.