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  * $FreeBSD: releng/5.0/sys/i386/isa/bs/bsif.c 95710 2002-04-29 07:43:16Z peter $
   30  */
   31 
   32 #if     0
   33 /* WARNING: Any bug report must contain BS_REL_VERSION */
   34 #define BS_REL_VERSION  "NetBSD1.2/030" /* major jump */
   35 #endif
   36 
   37 #ifdef __NetBSD__
   38 #include <i386/Cbus/dev/bs/bsif.h>
   39 #endif  /* __NetBSD__ */
   40 #ifdef __FreeBSD__
   41 #include "opt_bs.h"
   42 #include "opt_pc98.h"
   43 #include "bs.h"
   44 #include <i386/isa/bs/bsif.h>
   45 #include <sys/bus.h>
   46 #endif  /* __FreeBSD__ */
   47 
   48 #include <sys/bio.h>
   49 #include <sys/buf.h>
   50 #include <cam/cam.h>
   51 #include <cam/cam_ccb.h>
   52 #include <cam/cam_sim.h>
   53 #include <cam/cam_xpt_sim.h>
   54 #include <cam/cam_debug.h>
   55 
   56 #include <cam/scsi/scsi_all.h>
   57 #include <cam/scsi/scsi_message.h>
   58 
   59 /**************************************************
   60  * DEVICE DECLARE
   61  **************************************************/
   62 #ifdef __NetBSD__
   63 static void bs_scsi_minphys(struct buf *);
   64 
   65 struct cfdriver bs_cd = {
   66         NULL, "bs", DV_DULL
   67 };
   68 
   69 struct scsi_device bs_dev = {
   70         NULL,   /* Use default error handler */
   71         NULL,   /* have a queue, served by this */
   72         NULL,   /* have no async handler */
   73         NULL,   /* Use default 'done' routine */
   74 };
   75 
   76 struct scsi_adapter pc98texa55bs = {
   77         bs_scsi_cmd,
   78         bs_scsi_minphys,
   79         bs_target_open,
   80         0,
   81 };
   82 #endif  /* __NetBSD__ */
   83 
   84 #ifdef __FreeBSD__
   85 static int bsprobe(struct isa_device *);
   86 static void bs_poll(struct cam_sim *sim);
   87 static int bsattach(struct isa_device *);
   88 static ointhand2_t bsintr;
   89 static int bs_dmarangecheck(caddr_t, unsigned);
   90 
   91 struct isa_driver bsdriver = {
   92         INTR_TYPE_CAM,
   93         bsprobe,
   94         bsattach,
   95         "bs"
   96 };
   97 COMPAT_ISA_DRIVER(bs, bsdriver);
   98 #if 0
   99 struct scsi_device bs_dev = {
  100         NULL,   /* Use default error handler */
  101         NULL,   /* have a queue, served by this */
  102         NULL,   /* have no async handler */
  103         NULL,   /* Use default 'done' routine */
  104         "bs",
  105         0, {0, 0}
  106 };
  107 #endif
  108 u_int32_t
  109 bs_adapter_info(unit)
  110         int unit;
  111 {
  112         return (1);
  113 }
  114 #if 0
  115 static struct scsi_adapter pc98texa55bs = {
  116         bs_scsi_cmd,
  117         bs_scsi_minphys,
  118         bs_target_open,
  119         0,
  120         bs_adapter_info,
  121         "bs", {0, 0}
  122 };
  123 #endif
  124 static u_short pc98_irq_ball[16] = {
  125         IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
  126         IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15
  127 };
  128 
  129 static struct bs_softc *bscdata[NBS];
  130 #endif  /* __FreeBSD__ */
  131 
  132 /*****************************************************************
  133  * OS <=> BS INTERFACE
  134  *****************************************************************/
  135 #ifdef __FreeBSD__
  136 static int
  137 bsprobe(dev)
  138         struct isa_device *dev;
  139 {
  140         struct bs_softc *bsc;
  141         int unit = dev->id_unit;
  142         u_int irq, drq;
  143         int i, rv = 0;
  144 
  145         if (unit >= NBS) {
  146                 printf("bs%d: unit number too high\n", unit);
  147                 return rv;
  148         }
  149         /*
  150          * Allocate a storage for us
  151          */
  152         if (bscdata[unit]) {
  153                 printf("bs%d: memory already allocated\n", unit);
  154                 return rv;
  155         }
  156         if (!(bsc = malloc(sizeof(struct bs_softc), M_TEMP, M_NOWAIT | M_ZERO)))
  157         {
  158                 printf("bs%d cannot malloc!\n", unit);
  159                 return rv;
  160         }
  161         callout_handle_init(&bsc->timeout_ch);
  162         bscdata[unit] = bsc;
  163         bsc->unit = unit;
  164 
  165         bsc->sc_cfgflags = DVCFG_MINOR(dev->id_flags);
  166         bsc->sc_hw = DVCFG_HW(&bshw_hwsel, DVCFG_MAJOR(dev->id_flags));
  167         if (bsc->sc_hw == NULL)
  168                 return rv;
  169 
  170         if ((bsc->sc_hw->hw_flags & BSHW_SMFIFO) &&
  171                         (dev->id_maddr != (caddr_t)MADDRUNK))
  172                 bsc->sm_offset = (u_long) dev->id_maddr;
  173         else
  174                 bsc->sm_offset = (u_long) 0;
  175 
  176         snprintf(bsc->sc_dvname, sizeof(bsc->sc_dvname), "bs%d", unit);
  177 
  178         if (dev->id_iobase == 0)
  179         {
  180                 printf("%s: iobase not specified. Assume default port(0x%x)\n",
  181                         bsc->sc_dvname, BSHW_DEFAULT_PORT);
  182                 dev->id_iobase = BSHW_DEFAULT_PORT;
  183         }
  184 
  185         bsc->sc_iobase = dev->id_iobase;
  186         irq = IRQUNK;
  187         drq = DRQUNK;
  188         if (bshw_board_probe(bsc, &drq, &irq))
  189                 goto bad;
  190 
  191         dev->id_irq = pc98_irq_ball[irq];
  192         dev->id_drq = (short)drq;
  193 
  194         /* initialize host queue and target info */
  195         bs_hostque_init(bsc);
  196         for (i = 0; i < NTARGETS; i++)
  197                 if (i != bsc->sc_hostid)
  198                         bs_init_target_info(bsc, i);
  199 
  200         /* initialize ccb queue */
  201         bs_init_ccbque(BS_MAX_CCB);
  202 
  203         /* scsi bus reset and restart */
  204         bsc->sc_hstate = BSC_BOOTUP;
  205         bsc->sc_retry = RETRIES;
  206         bsc->sc_wc = delaycount * 250;  /* about 1 sec */
  207         bs_reset_nexus(bsc);
  208 
  209         return BSHW_IOSZ;
  210 bad:
  211         return rv;
  212 }
  213 #endif  /* __FreeBSD__ */
  214 
  215 #ifdef __NetBSD__
  216 int
  217 bsprint(aux, name)
  218         void *aux;
  219         const char *name;
  220 {
  221 
  222         if (name != NULL)
  223                 printf("%s: scsibus ", name);
  224         return UNCONF;
  225 }
  226 #endif
  227 
  228 #ifdef __FreeBSD__
  229 static void
  230 bs_poll(struct cam_sim *sim)
  231 {
  232         bs_sequencer(cam_sim_softc(sim));
  233 }
  234 
  235 static int
  236 bsattach(dev)
  237         struct isa_device *dev;
  238 {
  239         int unit = dev->id_unit;
  240         struct bs_softc *bsc = bscdata[unit];
  241         struct cam_devq *devq;
  242 
  243         dev->id_ointr = bsintr;
  244 
  245         /*
  246          * CAM support  HN2  MAX_START, MAX_TAGS xxxx
  247          */
  248         devq = cam_simq_alloc(256/*MAX_START*/);
  249         if (devq == NULL)
  250                 return 0;
  251 
  252         bsc->sim = cam_sim_alloc(bs_scsi_cmd, bs_poll, "bs",
  253                                  bsc, unit, 1, 32/*MAX_TAGS*/, devq);
  254         if (bsc->sim == NULL) {
  255                 cam_simq_free(devq);
  256                 return 0;
  257         }
  258 
  259         if (xpt_bus_register(bsc->sim, 0) != CAM_SUCCESS) {
  260                 free(bsc->sim, M_DEVBUF);
  261                 return 0;
  262         }
  263         
  264         if (xpt_create_path(&bsc->path, /*periph*/NULL,
  265                             cam_sim_path(bsc->sim), CAM_TARGET_WILDCARD,
  266                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
  267                 xpt_bus_deregister(cam_sim_path(bsc->sim));
  268                 cam_sim_free(bsc->sim, /*free_simq*/TRUE);
  269                 free(bsc->sim, M_DEVBUF);
  270                 return 0;
  271         }
  272         bs_start_timeout(bsc);
  273         return 1;
  274 }
  275 #endif  /* __FreeBSD__ */
  276 
  277 #ifdef __NetBSD__
  278 int
  279 bsintr(arg)
  280         void *arg;
  281 {
  282 
  283         return bs_sequencer((struct bs_softc *)arg);
  284 }
  285 #endif  /* __NetBSD__ */
  286 
  287 #ifdef __FreeBSD__
  288 static void
  289 bsintr(unit)
  290         int unit;
  291 {
  292         (void)bs_sequencer(bscdata[unit]);
  293 }
  294 #endif  /* __FreeBSD__ */
  295 
  296 /*****************************************************************
  297  * JULIAN SCSI <=> BS INTERFACE
  298  *****************************************************************/
  299 #ifndef __FreeBSD__
  300 static void
  301 bs_scsi_minphys(bp)
  302         struct buf *bp;
  303 {
  304 
  305         if (bp->b_bcount > BSDMABUFSIZ)
  306                 bp->b_bcount = BSDMABUFSIZ;
  307         minphys(bp);
  308 }
  309 #endif
  310 #if 0
  311 XSBS_INT32T
  312 bs_target_open(sc, cf)
  313         struct scsi_link *sc;
  314         struct cfdata *cf;
  315 {
  316         u_int target = sc->target;
  317         struct bs_softc *bsc = (struct bs_softc *) (sc->adapter_softc);
  318         struct targ_info *ti = bsc->sc_ti[target];
  319         u_int flags;
  320 
  321         if ((bsc->sc_openf & (1 << target)) == 0)
  322                 return ENODEV;
  323 
  324         if ((flags = cf->cf_flags) == 0)
  325                 flags = BS_SCSI_DEFCFG;
  326 
  327         bs_setup_ctrl(ti, (u_int)sc->quirks, flags);
  328         return 0;
  329 }
  330 #endif
  331 /*****************************************************************
  332  * BS MEMORY ALLOCATION INTERFACE
  333  *****************************************************************/
  334 #ifdef __NetBSD__
  335 void
  336 bs_alloc_buf(ti)
  337         struct targ_info *ti;
  338 {
  339         struct bs_softc *bsc = ti->ti_bsc;
  340         caddr_t addr, physaddr;
  341         bus_dma_segment_t seg;
  342         int rseg, error;
  343         u_int pages;
  344         extern int cold;
  345 
  346         /* XXX:
  347          * strategy change!
  348          * A) total memory >= 16M at boot: MAXBSIZE * 7 = 112k.
  349          * B) others:  4K * 7 = 28 K.
  350          */
  351         if (get_sysinfo(SYSINFO_MEMLEVEL) == MEM_LEVEL1 && cold != 0)
  352                 pages = 4;
  353         else
  354                 pages = 1;
  355         ti->bounce_size = NBPG * pages;
  356 
  357         addr = NULL;
  358         error = bus_dmamem_alloc(bsc->sc_dmat, ti->bounce_size, NBPG, 0,
  359                                  &seg, 1, &rseg, BUS_DMA_NOWAIT);
  360         if (rseg == 1 && error == 0)
  361                 error = bus_dmamem_map(bsc->sc_dmat, &seg, rseg,
  362                                        ti->bounce_size, &addr, BUS_DMA_NOWAIT);
  363         if (rseg != 1 || error != 0)
  364         {
  365                 ti->bounce_size = NBPG;
  366                 if ((addr = malloc(NBPG, M_DEVBUF, M_NOWAIT)) == NULL)
  367                         goto bad;
  368         }
  369 
  370         physaddr = (caddr_t) vtophys(addr);
  371         if ((u_int) physaddr >= RAM_END)
  372         {
  373                 /* XXX: mem from malloc only! */
  374                 free(addr, M_DEVBUF);
  375                 goto bad;
  376         }
  377 
  378         ti->bounce_addr = (u_int8_t *) addr;
  379         ti->bounce_phys = (u_int8_t *) physaddr;
  380         return;
  381 
  382 bad:
  383         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  384         printf("WARNING: this target is dislocated\n");
  385 }
  386 #endif  /* __NetBSD__ */
  387 
  388 #ifdef __FreeBSD__
  389 static int bs_dmarangecheck(caddr_t va, unsigned length)
  390 {
  391         vm_offset_t phys, priorpage = 0, endva;
  392 
  393         endva = (vm_offset_t)round_page((unsigned long)(va+length));
  394         for (; va < (caddr_t)endva; va += PAGE_SIZE) {
  395                 phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va));
  396                 if (phys == 0)
  397                         panic("bs_dmarangecheck: no physical page present");
  398                 if (phys >= RAM_END)
  399                         return 1;
  400                 if (priorpage) {
  401                         if (priorpage + PAGE_SIZE != phys)
  402                                 return 1;
  403                 }
  404                 priorpage = phys;
  405         }
  406         return 0;
  407 }
  408 
  409 void
  410 bs_alloc_buf(ti)
  411         struct targ_info *ti;
  412 {
  413         caddr_t addr, physaddr;
  414 
  415 #if BS_BOUNCE_SIZE != 0
  416         ti->bounce_size = BS_BOUNCE_SIZE;
  417 #else
  418         ti->bounce_size = BSHW_NBPG;
  419 #endif
  420         /* Try malloc() first.  It works better if it works. */
  421         addr = malloc(ti->bounce_size, M_DEVBUF, M_NOWAIT);
  422         if (addr != NULL) {
  423                 if (bs_dmarangecheck(addr, ti->bounce_size) == 0) {
  424                         physaddr = (caddr_t) vtophys(addr);
  425                         ti->bounce_addr = (u_int8_t *) addr;
  426                         ti->bounce_phys = (u_int8_t *) physaddr;
  427                         return;
  428                 }
  429                 free(addr, M_DEVBUF);
  430         }
  431         addr = contigmalloc(ti->bounce_size, M_DEVBUF, M_NOWAIT,
  432                                                 0ul, RAM_END, 1ul, 0x10000ul);
  433         if (addr == NULL)
  434                 goto bad;
  435 
  436         physaddr = (caddr_t) vtophys(addr);
  437         if ((u_int) physaddr >= RAM_END)
  438         {
  439                 /* XXX:
  440                  * must free memory !
  441                  */
  442                 goto bad;
  443         }
  444 
  445         ti->bounce_addr = (u_int8_t *) addr;
  446         ti->bounce_phys = (u_int8_t *) physaddr;
  447         return;
  448 
  449 bad:
  450         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  451         printf("WARNING: this target is dislocated\n");
  452 }
  453 #endif  /* __FreeBSD__ */

Cache object: 11ebbda8a32dbe89657bd7a4ecc878b3


[ 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.