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

Cache object: c396dde141edc3c9e5ada5fff25cedee


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