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/aha_isa.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 /*
    2  * Product specific probe and attach routines for:
    3  *      Adaptec 154x.
    4  *
    5  * Derived from code written by:
    6  *
    7  * Copyright (c) 1998 Justin T. Gibbs
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions, and the following disclaimer,
   15  *    without modification, immediately at the beginning of the file.
   16  * 2. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 #include "pnp.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 
   40 #include <machine/bus_pio.h>
   41 #include <machine/bus.h>
   42 
   43 #include <i386/isa/isa_device.h>
   44 #include <dev/aha/ahareg.h>
   45 
   46 #include <cam/scsi/scsi_all.h>
   47 
   48 #if NPNP > 0
   49 #include <i386/isa/pnp.h>
   50 #endif
   51 
   52 static  int aha_isa_probe(struct isa_device *dev);
   53 static  int aha_isa_attach(struct isa_device *dev);
   54 static  void aha_isa_intr(void *unit);
   55 
   56 struct isa_driver ahadriver =
   57 {
   58     aha_isa_probe,
   59     aha_isa_attach,
   60     "aha"
   61 };
   62 
   63 /*
   64  * Check if the device can be found at the port given
   65  * and if so, set it up ready for further work
   66  * as an argument, takes the isa_device structure from
   67  * autoconf.c
   68  */
   69 static int
   70 aha_isa_probe(dev)
   71         struct isa_device *dev;
   72 {
   73         /*
   74          * find unit and check we have that many defined
   75          */
   76         struct  aha_softc *aha;
   77         int     port_index;
   78         int     max_port_index;
   79 
   80         aha = NULL;
   81 
   82         /*
   83          * Bound our board search if the user has
   84          * specified an exact port.
   85          */
   86         aha_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
   87 
   88         if (port_index < 0)
   89                 return 0;
   90 
   91         /* Attempt to find an adapter */
   92         for (;port_index <= max_port_index; port_index++) {
   93                 config_data_t config_data;
   94                 u_int ioport;
   95                 int error;
   96 
   97                 ioport = aha_iop_from_bio(port_index);
   98 
   99                 /*
  100                  * Ensure this port has not already been claimed already
  101                  * by a PCI, EISA or ISA adapter.
  102                  */
  103                 if (aha_check_probed_iop(ioport) != 0)
  104                         continue;
  105                 dev->id_iobase = ioport;
  106                 if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
  107                         continue;
  108 
  109                 /* Allocate a softc for use during probing */
  110                 aha = aha_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
  111 
  112                 if (aha == NULL)
  113                         break;
  114 
  115                 /* We're going to attempt to probe it now, so mark it probed */
  116                 aha_mark_probed_bio(port_index);
  117 
  118                 /* See if there is really a card present */
  119                 if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
  120                         aha_free(aha);
  121                         continue;
  122                 }
  123 
  124                 /*
  125                  * Determine our IRQ, and DMA settings and
  126                  * export them to the configuration system.
  127                  */
  128                 error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
  129                                (u_int8_t*)&config_data, sizeof(config_data),
  130                                DEFAULT_CMD_TIMEOUT);
  131                 if (error != 0) {
  132                         printf("aha_isa_probe: Could not determine IRQ or DMA "
  133                                "settings for adapter at 0x%x.  Failing probe\n",
  134                                ioport);
  135                         aha_free(aha);
  136                         continue;
  137                 }
  138 
  139                 switch (config_data.dma_chan) {
  140                 case DMA_CHAN_5:
  141                         dev->id_drq = 5;
  142                         break;
  143                 case DMA_CHAN_6:
  144                         dev->id_drq = 6;
  145                         break;
  146                 case DMA_CHAN_7:
  147                         dev->id_drq = 7;
  148                         break;
  149                 default:
  150                         printf("aha_isa_probe: Invalid DMA setting "
  151                                 "detected for adapter at 0x%x.  "
  152                                 "Failing probe\n", ioport);
  153                         return (0);
  154                 }
  155                 dev->id_irq = (config_data.irq << 9);
  156                 dev->id_intr = aha_isa_intr;
  157                 aha_unit++;
  158                 return (AHA_NREGS);
  159         }
  160 
  161         return (0);
  162 }
  163 
  164 /*
  165  * Attach all the sub-devices we can find
  166  */
  167 static int
  168 aha_isa_attach(dev)
  169         struct isa_device *dev;
  170 {
  171         struct  aha_softc *aha;
  172         bus_dma_filter_t *filter;
  173         void             *filter_arg;
  174         bus_addr_t       lowaddr;
  175 
  176         aha = aha_softcs[dev->id_unit];
  177         if (dev->id_drq != -1)
  178                 isa_dmacascade(dev->id_drq);
  179 
  180         /* Allocate our parent dmatag */
  181         filter = NULL;
  182         filter_arg = NULL;
  183         lowaddr = BUS_SPACE_MAXADDR_24BIT;
  184 
  185         if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
  186                                lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
  187                                filter, filter_arg,
  188                                /*maxsize*/BUS_SPACE_MAXSIZE_24BIT,
  189                                /*nsegments*/BUS_SPACE_UNRESTRICTED,
  190                                /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
  191                                /*flags*/0, &aha->parent_dmat) != 0) {
  192                 aha_free(aha);
  193                 return (-1);
  194         }                              
  195 
  196         if (aha_init(aha)) {
  197                 printf("aha init failed\n");
  198                 aha_free(aha);
  199                 return (-1);
  200         }
  201 
  202         return (aha_attach(aha));
  203 }
  204 
  205 /*
  206  * Handle an ISA interrupt.
  207  * XXX should go away as soon as ISA interrupt handlers
  208  * take a (void *) arg.
  209  */
  210 static void
  211 aha_isa_intr(void *unit)
  212 {
  213         struct aha_softc* arg = aha_softcs[(int)unit];
  214         aha_intr((void *)arg);
  215 }
  216 
  217 /*
  218  * support PnP cards if we are using 'em
  219  */
  220 
  221 #if NPNP > 0
  222 
  223 static char *ahapnp_probe(u_long csn, u_long vend_id);
  224 static void ahapnp_attach(u_long csn, u_long vend_id, char *name,
  225         struct isa_device *dev);
  226 static u_long nahapnp = NAHA;
  227 
  228 static struct pnp_device ahapnp = {
  229         "ahapnp",
  230         ahapnp_probe,
  231         ahapnp_attach,
  232         &nahapnp,
  233         &bio_imask
  234 };
  235 DATA_SET (pnpdevice_set, ahapnp);
  236 
  237 static char *
  238 ahapnp_probe(u_long csn, u_long vend_id)
  239 {
  240         struct pnp_cinfo d;
  241         char *s = NULL;
  242 
  243         if (vend_id != AHA1542_PNP && vend_id != AHA1542_PNPCOMPAT)
  244                 return (NULL);
  245 
  246         read_pnp_parms(&d, 0);
  247         if (d.enable == 0 || d.flags & 1) {
  248                 printf("CSN %lu is disabled.\n", csn);
  249                 return (NULL);
  250         }
  251         s = "Adaptec 1542CP";
  252 
  253         return (s);
  254 }
  255 
  256 static void
  257 ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
  258 {
  259         struct pnp_cinfo d;
  260         struct isa_device *dvp;
  261 
  262         if (dev->id_unit >= NAHATOT)
  263                 return;
  264 
  265         if (read_pnp_parms(&d, 0) == 0) {
  266                 printf("failed to read pnp parms\n");
  267                 return;
  268         }
  269 
  270         write_pnp_parms(&d, 0);
  271 
  272         enable_pnp_card();
  273 
  274         dev->id_iobase = d.port[0];
  275         dev->id_irq = (1 << d.irq[0]);
  276         dev->id_intr = aha_intr;
  277         dev->id_drq = d.drq[0];
  278 
  279         if (dev->id_driver == NULL) {
  280                 dev->id_driver = &ahadriver;
  281                 dvp = find_isadev(isa_devtab_tty, &ahadriver, 0);
  282                 if (dvp != NULL)
  283                         dev->id_id = dvp->id_id;
  284         }
  285 
  286         if ((dev->id_alive = aha_isa_probe(dev)) != 0)
  287                 aha_isa_attach(dev);
  288         else
  289                 printf("aha%d: probe failed\n", dev->id_unit);
  290 }
  291 #endif

Cache object: c92a209a7e131a21dd147119af6fd08d


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