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/dev/ata/ata_raid.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 /*      $NetBSD: ata_raid.c,v 1.8 2004/01/25 18:06:48 hannken Exp $     */
    2 
    3 /*
    4  * Copyright (c) 2003 Wasabi Systems, Inc.
    5  * All rights reserved.
    6  *
    7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed for the NetBSD Project by
   20  *      Wasabi Systems, Inc.
   21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
   22  *    or promote products derived from this software without specific prior
   23  *    written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
   29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  */
   37 
   38 /*
   39  * Support for autoconfiguration of RAID sets on ATA RAID controllers.
   40  */
   41 
   42 #include <sys/cdefs.h>
   43 __KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v 1.8 2004/01/25 18:06:48 hannken Exp $");
   44 
   45 #include <sys/param.h>
   46 #include <sys/buf.h>
   47 #include <sys/conf.h>
   48 #include <sys/device.h>
   49 #include <sys/disk.h>
   50 #include <sys/disklabel.h>
   51 #include <sys/fcntl.h>
   52 #include <sys/malloc.h>
   53 #include <sys/vnode.h>
   54 
   55 #include <miscfs/specfs/specdev.h>
   56 
   57 #include <dev/ata/atareg.h>
   58 #include <dev/ata/atavar.h>
   59 #include <dev/ata/wdvar.h>
   60 
   61 #include <dev/ata/ata_raidreg.h>
   62 #include <dev/ata/ata_raidvar.h>
   63 
   64 #include "locators.h"
   65 
   66 #ifdef ATA_RAID_DEBUG
   67 #define DPRINTF(x)      printf x
   68 #else
   69 #define DPRINTF(x)      /* nothing */
   70 #endif
   71 
   72 void            ataraidattach(int);
   73 
   74 static int      ataraid_match(struct device *, struct cfdata *, void *);
   75 static void     ataraid_attach(struct device *, struct device *, void *);
   76 static int      ataraid_print(void *, const char *);
   77 
   78 static int      ataraid_submatch(struct device *, struct cfdata *, void *);
   79 
   80 static int      ata_raid_finalize(struct device *);
   81 
   82 ataraid_array_info_list_t ataraid_array_info_list =
   83     TAILQ_HEAD_INITIALIZER(ataraid_array_info_list);
   84 u_int ataraid_array_info_count;
   85 
   86 CFATTACH_DECL(ataraid, sizeof(struct device),
   87     ataraid_match, ataraid_attach, NULL, NULL);
   88 
   89 /*
   90  * ataraidattach:
   91  *
   92  *      Pseudo-device attach routine.
   93  */
   94 void
   95 ataraidattach(int count)
   96 {
   97 
   98         /*
   99          * Register a finalizer which will be used to actually configure
  100          * the logical disks configured by ataraid.
  101          */
  102         if (config_finalize_register(NULL, ata_raid_finalize) != 0)
  103                 printf("WARNING: unable to register ATA RAID finalizer\n");
  104 }
  105 
  106 /*
  107  * ata_raid_type_name:
  108  *
  109  *      Return the type of ATA RAID.
  110  */
  111 const char *
  112 ata_raid_type_name(u_int type)
  113 {
  114         static const char *ata_raid_type_names[] = {
  115                 "Promise",
  116         };
  117 
  118         if (type <= ATA_RAID_TYPE_MAX)
  119                 return (ata_raid_type_names[type]);
  120 
  121         return (NULL);
  122 }
  123 
  124 /*
  125  * ata_raid_finalize:
  126  *
  127  *      Autoconfiguration finalizer for ATA RAID.
  128  */
  129 static int
  130 ata_raid_finalize(struct device *self)
  131 {
  132         extern struct cfdriver ataraid_cd;
  133         static int done_once;
  134         int error;
  135 
  136         /*
  137          * Since we only handle real hardware, we only need to be
  138          * called once.
  139          */
  140         if (done_once)
  141                 return (0);
  142         done_once = 1;
  143 
  144         if (TAILQ_EMPTY(&ataraid_array_info_list))
  145                 goto out;
  146 
  147         error = config_cfattach_attach(ataraid_cd.cd_name, &ataraid_ca);
  148         if (error) {
  149                 printf("%s: unable to register cfattach, error = %d\n",
  150                     ataraid_cd.cd_name, error);
  151                 (void) config_cfdriver_detach(&ataraid_cd);
  152                 goto out;
  153         }
  154 
  155         if (config_attach_pseudo(ataraid_cd.cd_name, -1) == NULL)
  156                 printf("%s: unable to attach an instance\n",
  157                     ataraid_cd.cd_name);
  158 
  159  out:
  160         return (1);
  161 }
  162 
  163 /*
  164  * ataraid_match:
  165  *
  166  *      Autoconfiguration glue: match routine.
  167  */
  168 static int
  169 ataraid_match(struct device *parent, struct cfdata *cf, void *aux)
  170 {
  171 
  172         /* pseudo-device; always present */
  173         return (1);
  174 }
  175 
  176 /*
  177  * ataraid_attach:
  178  *
  179  *      Autoconfiguration glue: attach routine.  We attach the children.
  180  */
  181 static void
  182 ataraid_attach(struct device *parent, struct device *self, void *aux)
  183 {
  184         struct ataraid_array_info *aai;
  185 
  186         /*
  187          * We're a pseudo-device, so we get to announce our own
  188          * presence.
  189          */
  190         aprint_normal("%s: found %u RAID volume%s\n",
  191             self->dv_xname, ataraid_array_info_count,
  192             ataraid_array_info_count == 1 ? "" : "s");
  193 
  194         TAILQ_FOREACH(aai, &ataraid_array_info_list, aai_list) {
  195                 config_found_sm(self, aai, ataraid_print, ataraid_submatch);
  196         }
  197 }
  198 
  199 /*
  200  * ataraid_print:
  201  *
  202  *      Autoconfiguration glue: print routine.
  203  */
  204 static int
  205 ataraid_print(void *aux, const char *pnp)
  206 {
  207         struct ataraid_array_info *aai = aux;
  208 
  209         if (pnp != NULL)
  210                 aprint_normal("block device at %s", pnp);
  211         aprint_normal(" vendtype %d unit %d", aai->aai_type, aai->aai_arrayno);
  212         return (UNCONF);
  213 }
  214 
  215 /*
  216  * ataraid_submatch:
  217  *
  218  *      Submatch routine for ATA RAID logical disks.
  219  */
  220 static int
  221 ataraid_submatch(struct device *parent, struct cfdata *cf, void *aux)
  222 {
  223         struct ataraid_array_info *aai = aux;
  224 
  225         if (cf->cf_loc[ATARAIDCF_VENDTYPE] != ATARAIDCF_VENDTYPE_DEFAULT &&
  226             cf->cf_loc[ATARAIDCF_VENDTYPE] != aai->aai_type)
  227                 return (0);
  228 
  229         if (cf->cf_loc[ATARAIDCF_UNIT] != ATARAIDCF_UNIT_DEFAULT &&
  230             cf->cf_loc[ATARAIDCF_UNIT] != aai->aai_arrayno)
  231                 return (0);
  232 
  233         return (config_match(parent, cf, aux));
  234 }
  235 
  236 /*
  237  * ata_raid_check_component:
  238  *
  239  *      Check the component for a RAID configuration structure.
  240  *      Called via autoconfiguration callback.
  241  */
  242 void
  243 ata_raid_check_component(struct device *self)
  244 {
  245         struct wd_softc *sc = (void *) self;
  246 
  247         if (ata_raid_read_config_promise(sc) == 0)
  248                 return;
  249 }
  250 
  251 struct ataraid_array_info *
  252 ata_raid_get_array_info(u_int type, u_int arrayno)
  253 {
  254         struct ataraid_array_info *aai, *laai;
  255 
  256         TAILQ_FOREACH(aai, &ataraid_array_info_list, aai_list) {
  257                 if (aai->aai_type == type &&
  258                     aai->aai_arrayno == arrayno)
  259                         goto out;
  260         }
  261 
  262         /* Need to allocate a new one. */
  263         aai = malloc(sizeof(*aai), M_DEVBUF, M_WAITOK | M_ZERO);
  264         aai->aai_type = type;
  265         aai->aai_arrayno = arrayno;
  266 
  267         ataraid_array_info_count++;
  268 
  269         if (TAILQ_EMPTY(&ataraid_array_info_list)) {
  270                 TAILQ_INSERT_TAIL(&ataraid_array_info_list, aai, aai_list);
  271                 goto out;
  272         }
  273 
  274         /* Sort it into the list: type first, then array number. */
  275         TAILQ_FOREACH(laai, &ataraid_array_info_list, aai_list) {
  276                 if (aai->aai_type < laai->aai_type) {
  277                         TAILQ_INSERT_BEFORE(laai, aai, aai_list);
  278                         goto out;
  279                 }
  280                 if (aai->aai_type == laai->aai_type &&
  281                     aai->aai_arrayno < laai->aai_arrayno) {
  282                         TAILQ_INSERT_BEFORE(laai, aai, aai_list);
  283                         goto out;
  284                 }
  285         }
  286         TAILQ_INSERT_TAIL(&ataraid_array_info_list, aai, aai_list);
  287 
  288  out:
  289         return (aai);
  290 }
  291 
  292 int
  293 ata_raid_config_block_rw(struct vnode *vp, daddr_t blkno, void *buf,
  294     size_t size, int bflags)
  295 {
  296         struct buf *bp;
  297         int error, s;
  298 
  299         s = splbio();
  300         bp = pool_get(&bufpool, PR_WAITOK);
  301         splx(s);
  302         BUF_INIT(bp);
  303 
  304         bp->b_vp = vp;
  305         bp->b_blkno = blkno;
  306         bp->b_bcount = bp->b_resid = size;
  307         bp->b_flags = bflags;
  308         bp->b_proc = curproc;
  309         bp->b_data = buf;
  310 
  311         VOP_STRATEGY(vp, bp);
  312         error = biowait(bp);
  313 
  314         s = splbio();
  315         pool_put(&bufpool, bp);
  316         splx(s);
  317         return (error);
  318 }

Cache object: 81f75255f10bb7978cdc9b340a67f61c


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