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 bsprint __P((void *, const char *));
   87 static void bs_scsi_minphys __P((struct buf *));
   88 static int bs_dmarangecheck __P((caddr_t, unsigned));
   89 
   90 struct isa_driver bsdriver = {
   91         bsprobe,
   92         bsattach,
   93         "bs"
   94 };
   95 #if 0
   96 struct scsi_device bs_dev = {
   97         NULL,   /* Use default error handler */
   98         NULL,   /* have a queue, served by this */
   99         NULL,   /* have no async handler */
  100         NULL,   /* Use default 'done' routine */
  101         "bs",
  102         0, {0, 0}
  103 };
  104 #endif
  105 u_int32_t
  106 bs_adapter_info(unit)
  107         int unit;
  108 {
  109         return (1);
  110 }
  111 #if 0
  112 static struct scsi_adapter pc98texa55bs = {
  113         bs_scsi_cmd,
  114         bs_scsi_minphys,
  115         bs_target_open,
  116         0,
  117         bs_adapter_info,
  118         "bs", {0, 0}
  119 };
  120 #endif
  121 static u_short pc98_irq_ball[16] = {
  122         IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
  123         IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15
  124 };
  125 
  126 static struct bs_softc *bscdata[NBS];
  127 #endif  /* __FreeBSD__ */
  128 
  129 /*****************************************************************
  130  * OS <=> BS INTERFACE
  131  *****************************************************************/
  132 #ifdef __FreeBSD__
  133 static int
  134 bsprobe(dev)
  135         struct isa_device *dev;
  136 {
  137         struct bs_softc *bsc;
  138         int unit = dev->id_unit;
  139         u_int irq, drq;
  140         int i, rv = 0;
  141 
  142         if (unit >= NBS) {
  143                 printf("bs%d: unit number too high\n", unit);
  144                 return rv;
  145         }
  146         /*
  147          * Allocate a storage for us
  148          */
  149         if (bscdata[unit]) {
  150                 printf("bs%d: memory already allocated\n", unit);
  151                 return rv;
  152         }
  153         if (!(bsc = malloc(sizeof(struct bs_softc), M_TEMP, M_NOWAIT))) {
  154                 printf("bs%d cannot malloc!\n", unit);
  155                 return rv;
  156         }
  157         bzero(bsc, sizeof(struct bs_softc));
  158         callout_handle_init(&bsc->timeout_ch);
  159         bscdata[unit] = bsc;
  160         bsc->unit = unit;
  161 
  162         bsc->sc_cfgflags = DVCFG_MINOR(dev->id_flags);
  163         bsc->sc_hw = DVCFG_HW(&bshw_hwsel, DVCFG_MAJOR(dev->id_flags));
  164         if (bsc->sc_hw == NULL)
  165                 return rv;
  166 
  167         if ((bsc->sc_hw->hw_flags & BSHW_SMFIFO) &&
  168                         (dev->id_maddr != (caddr_t)MADDRUNK))
  169                 bsc->sm_offset = (u_long) dev->id_maddr;
  170         else
  171                 bsc->sm_offset = (u_long) 0;
  172 
  173         snprintf(bsc->sc_dvname, sizeof(bsc->sc_dvname), "bs%d", unit);
  174 
  175         if (dev->id_iobase == 0)
  176         {
  177                 printf("%s: iobase not specified. Assume default port(0x%x)\n",
  178                         bsc->sc_dvname, BSHW_DEFAULT_PORT);
  179                 dev->id_iobase = BSHW_DEFAULT_PORT;
  180         }
  181 
  182         bsc->sc_iobase = dev->id_iobase;
  183         irq = IRQUNK;
  184         drq = DRQUNK;
  185         if (bshw_board_probe(bsc, &drq, &irq))
  186                 goto bad;
  187 
  188         dev->id_irq = pc98_irq_ball[irq];
  189         dev->id_drq = (short)drq;
  190 
  191         /* initialize host queue and target info */
  192         bs_hostque_init(bsc);
  193         for (i = 0; i < NTARGETS; i++)
  194                 if (i != bsc->sc_hostid)
  195                         bs_init_target_info(bsc, i);
  196 
  197         /* initialize ccb queue */
  198         bs_init_ccbque(BS_MAX_CCB);
  199 
  200         /* scsi bus reset and restart */
  201         bsc->sc_hstate = BSC_BOOTUP;
  202         bsc->sc_retry = RETRIES;
  203         bsc->sc_wc = delaycount * 250;  /* about 1 sec */
  204         bs_reset_nexus(bsc);
  205 
  206         return BSHW_IOSZ;
  207 bad:
  208         return rv;
  209 }
  210 #endif  /* __FreeBSD__ */
  211 
  212 #ifdef __FreeBSD__
  213 static int
  214 #else   /* __NetBSD__ */
  215 int
  216 #endif  /* __NetBSD__ */
  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 
  227 #ifdef __FreeBSD__
  228 static void
  229 bs_poll(struct cam_sim *sim)
  230 {
  231         bs_sequencer(cam_sim_softc(sim));
  232 }
  233 
  234 static int
  235 bsattach(dev)
  236         struct isa_device *dev;
  237 {
  238         int unit = dev->id_unit;
  239         struct bs_softc *bsc = bscdata[unit];
  240         struct scsibus_data *scbus;
  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 static void
  300 bs_scsi_minphys(bp)
  301         struct buf *bp;
  302 {
  303 
  304         if (bp->b_bcount > BSDMABUFSIZ)
  305                 bp->b_bcount = BSDMABUFSIZ;
  306         minphys(bp);
  307 }
  308 #if 0
  309 XSBS_INT32T
  310 bs_target_open(sc, cf)
  311         struct scsi_link *sc;
  312         struct cfdata *cf;
  313 {
  314         u_int target = sc->target;
  315         struct bs_softc *bsc = (struct bs_softc *) (sc->adapter_softc);
  316         struct targ_info *ti = bsc->sc_ti[target];
  317         u_int flags;
  318 
  319         if ((bsc->sc_openf & (1 << target)) == 0)
  320                 return ENODEV;
  321 
  322         if ((flags = cf->cf_flags) == 0)
  323                 flags = BS_SCSI_DEFCFG;
  324 
  325         bs_setup_ctrl(ti, (u_int)sc->quirks, flags);
  326         return 0;
  327 }
  328 #endif
  329 /*****************************************************************
  330  * BS MEMORY ALLOCATION INTERFACE
  331  *****************************************************************/
  332 #ifdef __NetBSD__
  333 void
  334 bs_alloc_buf(ti)
  335         struct targ_info *ti;
  336 {
  337         struct bs_softc *bsc = ti->ti_bsc;
  338         caddr_t addr, physaddr;
  339         bus_dma_segment_t seg;
  340         int rseg, error;
  341         u_int pages;
  342         extern int cold;
  343 
  344         /* XXX:
  345          * strategy change!
  346          * A) total memory >= 16M at boot: MAXBSIZE * 7 = 112k.
  347          * B) others:  4K * 7 = 28 K.
  348          */
  349         if (get_sysinfo(SYSINFO_MEMLEVEL) == MEM_LEVEL1 && cold != 0)
  350                 pages = 4;
  351         else
  352                 pages = 1;
  353         ti->bounce_size = NBPG * pages;
  354 
  355         addr = NULL;
  356         error = bus_dmamem_alloc(bsc->sc_dmat, ti->bounce_size, NBPG, 0,
  357                                  &seg, 1, &rseg, BUS_DMA_NOWAIT);
  358         if (rseg == 1 && error == 0)
  359                 error = bus_dmamem_map(bsc->sc_dmat, &seg, rseg,
  360                                        ti->bounce_size, &addr, BUS_DMA_NOWAIT);
  361         if (rseg != 1 || error != 0)
  362         {
  363                 ti->bounce_size = NBPG;
  364                 if ((addr = malloc(NBPG, M_DEVBUF, M_NOWAIT)) == NULL)
  365                         goto bad;
  366         }
  367 
  368         physaddr = (caddr_t) vtophys(addr);
  369         if ((u_int) physaddr >= RAM_END)
  370         {
  371                 /* XXX: mem from malloc only! */
  372                 free(addr, M_DEVBUF);
  373                 goto bad;
  374         }
  375 
  376         ti->bounce_addr = (u_int8_t *) addr;
  377         ti->bounce_phys = (u_int8_t *) physaddr;
  378         return;
  379 
  380 bad:
  381         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  382         printf("WARNING: this target is dislocated\n");
  383 }
  384 #endif  /* __NetBSD__ */
  385 
  386 #ifdef __FreeBSD__
  387 static int bs_dmarangecheck(caddr_t va, unsigned length)
  388 {
  389         vm_offset_t phys, priorpage = 0, endva;
  390 
  391         endva = (vm_offset_t)round_page((unsigned long)(va+length));
  392         for (; va < (caddr_t)endva; va += PAGE_SIZE) {
  393                 phys = trunc_page(pmap_extract(pmap_kernel(), (vm_offset_t)va));
  394                 if (phys == 0)
  395                         panic("bs_dmarangecheck: no physical page present");
  396                 if (phys >= RAM_END)
  397                         return 1;
  398                 if (priorpage) {
  399                         if (priorpage + PAGE_SIZE != phys)
  400                                 return 1;
  401                 }
  402                 priorpage = phys;
  403         }
  404         return 0;
  405 }
  406 
  407 void
  408 bs_alloc_buf(ti)
  409         struct targ_info *ti;
  410 {
  411         caddr_t addr, physaddr;
  412 
  413 #if BS_BOUNCE_SIZE != 0
  414         ti->bounce_size = BS_BOUNCE_SIZE;
  415 #else
  416         ti->bounce_size = BSHW_NBPG;
  417 #endif
  418         /* Try malloc() first.  It works better if it works. */
  419         addr = malloc(ti->bounce_size, M_DEVBUF, M_NOWAIT);
  420         if (addr != NULL) {
  421                 if (bs_dmarangecheck(addr, ti->bounce_size) == 0) {
  422                         physaddr = (caddr_t) vtophys(addr);
  423                         ti->bounce_addr = (u_int8_t *) addr;
  424                         ti->bounce_phys = (u_int8_t *) physaddr;
  425                         return;
  426                 }
  427                 free(addr, M_DEVBUF);
  428         }
  429         addr = contigmalloc(ti->bounce_size, M_DEVBUF, M_NOWAIT,
  430                                                 0ul, RAM_END, 1ul, 0x10000ul);
  431         if (addr == NULL)
  432                 goto bad;
  433 
  434         physaddr = (caddr_t) vtophys(addr);
  435         if ((u_int) physaddr >= RAM_END)
  436         {
  437                 /* XXX:
  438                  * must free memory !
  439                  */
  440                 goto bad;
  441         }
  442 
  443         ti->bounce_addr = (u_int8_t *) addr;
  444         ti->bounce_phys = (u_int8_t *) physaddr;
  445         return;
  446 
  447 bad:
  448         bs_printf(ti, "bs_alloc_buf", "no phys bounce buffer");
  449         printf("WARNING: this target is dislocated\n");
  450 }
  451 #endif  /* __FreeBSD__ */

Cache object: 19794b8f50af34476c332b9d1167d8d3


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