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/kern/subr_diskmbr.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  * Copyright (c) 1994 Bruce D. Evans.
    3  * All rights reserved.
    4  *
    5  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by the University of
   19  *      California, Berkeley and its contributors.
   20  * 4. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      from: @(#)ufs_disksubr.c        7.16 (Berkeley) 5/4/91
   37  *      from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
   38  * $FreeBSD: releng/5.0/sys/kern/subr_diskmbr.c 104272 2002-10-01 07:24:55Z phk $
   39  */
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/bio.h>
   44 #include <sys/buf.h>
   45 #include <sys/conf.h>
   46 #ifdef PC98
   47 #define PC98_ATCOMPAT
   48 #define dsinit                  atcompat_dsinit
   49 #endif
   50 #include <sys/disk.h>
   51 #include <sys/disklabel.h>
   52 #include <sys/diskmbr.h>
   53 #define DOSPTYP_EXTENDED        5
   54 #define DOSPTYP_EXTENDEDX       15
   55 #define DOSPTYP_ONTRACK         84
   56 #include <sys/diskslice.h>
   57 #include <sys/malloc.h>
   58 #include <sys/syslog.h>
   59 
   60 #define TRACE(str)      do { if (dsi_debug) printf str; } while (0)
   61 
   62 static volatile u_char dsi_debug;
   63 
   64 /*
   65  * This is what we have embedded in every boot1 for supporting the bogus
   66  * "Dangerously Dedicated" mode.  However, the old table is broken because
   67  * it has an illegal geometry in it - it specifies 256 heads (heads = end
   68  * head + 1) which causes nasty stuff when that wraps to zero in bios code.
   69  * eg: divide by zero etc.  This caused the dead-thinkpad problem, numerous
   70  * SCSI bios crashes, EFI to crash, etc.
   71  * 
   72  * We still have to recognize the old table though, even though we stopped
   73  * inflicting it apon the world.
   74  */
   75 static struct dos_partition historical_bogus_partition_table[NDOSPART] = {
   76         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   77         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   78         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   79         { 0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000, },
   80 };
   81 static struct dos_partition historical_bogus_partition_table_fixed[NDOSPART] = {
   82         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   83         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   84         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
   85         { 0x80, 0, 1, 0, DOSPTYP_386BSD, 254, 255, 255, 0, 50000, },
   86 };
   87 
   88 static int check_part(char *sname, struct dos_partition *dp,
   89                            u_long offset, int nsectors, int ntracks,
   90                            u_long mbr_offset);
   91 static void mbr_extended(dev_t dev, struct disklabel *lp,
   92                               struct diskslices *ssp, u_long ext_offset,
   93                               u_long ext_size, u_long base_ext_offset,
   94                               int nsectors, int ntracks, u_long mbr_offset,
   95                               int level);
   96 static int mbr_setslice(char *sname, struct disklabel *lp,
   97                              struct diskslice *sp, struct dos_partition *dp,
   98                              u_long br_offset);
   99 
  100 static int
  101 check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
  102         char    *sname;
  103         struct dos_partition *dp;
  104         u_long  offset;
  105         int     nsectors;
  106         int     ntracks;
  107         u_long  mbr_offset;
  108 {
  109         int     chs_ecyl;
  110         int     chs_esect;
  111         int     chs_scyl;
  112         int     chs_ssect;
  113         int     error;
  114         u_long  esector;
  115         u_long  esector1;
  116         u_long  secpercyl;
  117         u_long  ssector;
  118         u_long  ssector1;
  119 
  120         secpercyl = (u_long)nsectors * ntracks;
  121         chs_scyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
  122         chs_ssect = DPSECT(dp->dp_ssect);
  123         ssector = chs_ssect - 1 + dp->dp_shd * nsectors + chs_scyl * secpercyl
  124                   + mbr_offset;
  125         ssector1 = offset + dp->dp_start;
  126 
  127         /*
  128          * If ssector1 is on a cylinder >= 1024, then ssector can't be right.
  129          * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
  130          * apart from the cylinder being reduced modulo 1024.  Always allow
  131          * 1023/255/63, because this is the official way to represent
  132          * pure-LBA for the starting position.
  133          */
  134         if ((ssector < ssector1
  135              && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
  136                   && chs_scyl == 1023)
  137                  || (secpercyl != 0
  138                      && (ssector1 - ssector) % (1024 * secpercyl) == 0)))
  139             || (dp->dp_scyl == 255 && dp->dp_shd == 255
  140                 && dp->dp_ssect == 255)) {
  141                 TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
  142                        sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
  143                 ssector = ssector1;
  144         }
  145 
  146         chs_ecyl = DPCYL(dp->dp_ecyl, dp->dp_esect);
  147         chs_esect = DPSECT(dp->dp_esect);
  148         esector = chs_esect - 1 + dp->dp_ehd * nsectors + chs_ecyl * secpercyl
  149                   + mbr_offset;
  150         esector1 = ssector1 + dp->dp_size - 1;
  151 
  152         /*
  153          * Allow certain bogus C/H/S values for esector, as above.  However,
  154          * heads == 255 isn't really legal and causes some BIOS crashes.  The
  155          * correct value to indicate a pure-LBA end is 1023/heads-1/sectors -
  156          * usually 1023/254/63.  "heads" is base 0, "sectors" is base 1.
  157          */
  158         if ((esector < esector1
  159              && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
  160                   && chs_ecyl == 1023)
  161                  || (secpercyl != 0
  162                      && (esector1 - esector) % (1024 * secpercyl) == 0)))
  163             || (dp->dp_ecyl == 255 && dp->dp_ehd == 255
  164                 && dp->dp_esect == 255)) {
  165                 TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
  166                        sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
  167                 esector = esector1;
  168         }
  169 
  170         error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
  171         if (bootverbose)
  172                 printf("%s: type 0x%x, start %lu, end = %lu, size %lu %s\n",
  173                        sname, dp->dp_typ, ssector1, esector1,
  174                        (u_long)dp->dp_size, error ? "" : ": OK");
  175         if (ssector != ssector1 && bootverbose)
  176                 printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
  177                        sname, chs_scyl, dp->dp_shd, chs_ssect,
  178                        ssector, ssector1);
  179         if (esector != esector1 && bootverbose)
  180                 printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
  181                        sname, chs_ecyl, dp->dp_ehd, chs_esect,
  182                        esector, esector1);
  183         return (error);
  184 }
  185 
  186 int
  187 dsinit(dev, lp, sspp)
  188         dev_t   dev;
  189         struct disklabel *lp;
  190         struct diskslices **sspp;
  191 {
  192         struct buf *bp;
  193         u_char  *cp;
  194         int     dospart;
  195         struct dos_partition *dp;
  196         struct dos_partition *dp0;
  197         struct dos_partition dpcopy[NDOSPART];
  198         int     error;
  199         int     max_ncyls;
  200         int     max_nsectors;
  201         int     max_ntracks;
  202         u_long  mbr_offset;
  203         char    partname[2];
  204         u_long  secpercyl;
  205         char    *sname;
  206         struct diskslice *sp;
  207         struct diskslices *ssp;
  208 
  209         mbr_offset = DOSBBSECTOR;
  210 reread_mbr:
  211         /* Read master boot record. */
  212         bp = geteblk((int)lp->d_secsize);
  213         bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
  214         bp->b_blkno = mbr_offset;
  215         bp->b_bcount = lp->d_secsize;
  216         bp->b_iocmd = BIO_READ;
  217         DEV_STRATEGY(bp, 1);
  218         if (bufwait(bp) != 0) {
  219                 disk_err(&bp->b_io, "reading primary partition table: error",
  220                     0, 1);
  221                 error = EIO;
  222                 goto done;
  223         }
  224 
  225         /* Weakly verify it. */
  226         cp = bp->b_data;
  227         sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, partname);
  228         if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
  229                 if (bootverbose)
  230                         printf("%s: invalid primary partition table: no magic\n",
  231                                sname);
  232                 error = EINVAL;
  233                 goto done;
  234         }
  235 
  236         /* Make a copy of the partition table to avoid alignment problems. */
  237         memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
  238 
  239         dp0 = &dpcopy[0];
  240 
  241         /* Check for "Ontrack Diskmanager". */
  242         for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
  243                 if (dp->dp_typ == DOSPTYP_ONTRACK) {
  244                         if (bootverbose)
  245                                 printf(
  246             "%s: Found \"Ontrack Disk Manager\" on this disk.\n", sname);
  247                         bp->b_flags |= B_INVAL | B_AGE;
  248                         brelse(bp);
  249                         mbr_offset = 63;
  250                         goto reread_mbr;
  251                 }
  252         }
  253 
  254         if (bcmp(dp0, historical_bogus_partition_table,
  255                  sizeof historical_bogus_partition_table) == 0 ||
  256             bcmp(dp0, historical_bogus_partition_table_fixed,
  257                  sizeof historical_bogus_partition_table_fixed) == 0) {
  258                 if (bootverbose)
  259                         printf(
  260     "%s: invalid primary partition table: Dangerously Dedicated (ignored)\n",
  261     sname);
  262                 error = EINVAL;
  263                 goto done;
  264         }
  265 
  266         /* Guess the geometry. */
  267         /*
  268          * TODO:
  269          * Perhaps skip entries with 0 size.
  270          * Perhaps only look at entries of type DOSPTYP_386BSD.
  271          */
  272         max_ncyls = 0;
  273         max_nsectors = 0;
  274         max_ntracks = 0;
  275         for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
  276                 int     ncyls;
  277                 int     nsectors;
  278                 int     ntracks;
  279 
  280                 ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
  281                 if (max_ncyls < ncyls)
  282                         max_ncyls = ncyls;
  283                 nsectors = DPSECT(dp->dp_esect);
  284                 if (max_nsectors < nsectors)
  285                         max_nsectors = nsectors;
  286                 ntracks = dp->dp_ehd + 1;
  287                 if (max_ntracks < ntracks)
  288                         max_ntracks = ntracks;
  289         }
  290 
  291         /*
  292          * Check that we have guessed the geometry right by checking the
  293          * partition entries.
  294          */
  295         /*
  296          * TODO:
  297          * As above.
  298          * Check for overlaps.
  299          * Check against d_secperunit if the latter is reliable.
  300          */
  301         error = 0;
  302         for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
  303                 if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
  304                     && dp->dp_start == 0 && dp->dp_size == 0)
  305                         continue;
  306                 sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
  307                                RAW_PART, partname);
  308 
  309                 /*
  310                  * Temporarily ignore errors from this check.  We could
  311                  * simplify things by accepting the table eariler if we
  312                  * always ignore errors here.  Perhaps we should always
  313                  * accept the table if the magic is right but not let
  314                  * bad entries affect the geometry.
  315                  */
  316                 check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
  317                            mbr_offset);
  318         }
  319         if (error != 0)
  320                 goto done;
  321 
  322         /*
  323          * Accept the DOS partition table.
  324          * First adjust the label (we have been careful not to change it
  325          * before we can guarantee success).
  326          */
  327         secpercyl = (u_long)max_nsectors * max_ntracks;
  328         if (secpercyl != 0) {
  329                 lp->d_nsectors = max_nsectors;
  330                 lp->d_ntracks = max_ntracks;
  331                 lp->d_secpercyl = secpercyl;
  332                 lp->d_ncylinders = lp->d_secperunit / secpercyl;
  333         }
  334 
  335         /*
  336          * We are passed a pointer to a suitably initialized minimal
  337          * slices "struct" with no dangling pointers in it.  Replace it
  338          * by a maximal one.  This usually oversizes the "struct", but
  339          * enlarging it while searching for logical drives would be
  340          * inconvenient.
  341          */
  342         free(*sspp, M_DEVBUF);
  343         ssp = dsmakeslicestruct(MAX_SLICES, lp);
  344         *sspp = ssp;
  345 
  346         /* Initialize normal slices. */
  347         sp = &ssp->dss_slices[BASE_SLICE];
  348         for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
  349                 sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
  350                                RAW_PART, partname);
  351                 (void)mbr_setslice(sname, lp, sp, dp, mbr_offset);
  352         }
  353         ssp->dss_nslices = BASE_SLICE + NDOSPART;
  354 
  355         /* Handle extended partitions. */
  356         sp -= NDOSPART;
  357         for (dospart = 0; dospart < NDOSPART; dospart++, sp++)
  358                 if (sp->ds_type == DOSPTYP_EXTENDED ||
  359                     sp->ds_type == DOSPTYP_EXTENDEDX)
  360                         mbr_extended(bp->b_dev, lp, ssp,
  361                                      sp->ds_offset, sp->ds_size, sp->ds_offset,
  362                                      max_nsectors, max_ntracks, mbr_offset, 1);
  363 
  364         /*
  365          * mbr_extended() abuses ssp->dss_nslices for the number of slices
  366          * that would be found if there were no limit on the number of slices
  367          * in *ssp.  Cut it back now.
  368          */
  369         if (ssp->dss_nslices > MAX_SLICES)
  370                 ssp->dss_nslices = MAX_SLICES;
  371 
  372 done:
  373         bp->b_flags |= B_INVAL | B_AGE;
  374         brelse(bp);
  375         if (error == EINVAL)
  376                 error = 0;
  377         return (error);
  378 }
  379 
  380 static void
  381 mbr_extended(dev, lp, ssp, ext_offset, ext_size, base_ext_offset, nsectors,
  382              ntracks, mbr_offset, level)
  383         dev_t   dev;
  384         struct disklabel *lp;
  385         struct diskslices *ssp;
  386         u_long  ext_offset;
  387         u_long  ext_size;
  388         u_long  base_ext_offset;
  389         int     nsectors;
  390         int     ntracks;
  391         u_long  mbr_offset;
  392         int     level;
  393 {
  394         struct buf *bp;
  395         u_char  *cp;
  396         int     dospart;
  397         struct dos_partition *dp;
  398         struct dos_partition dpcopy[NDOSPART];
  399         u_long  ext_offsets[NDOSPART];
  400         u_long  ext_sizes[NDOSPART];
  401         char    partname[2];
  402         int     slice;
  403         char    *sname;
  404         struct diskslice *sp;
  405 
  406         if (level >= 16) {
  407                 printf(
  408         "%s: excessive recursion in search for slices; aborting search\n",
  409                        devtoname(dev));
  410                 return;
  411         }
  412 
  413         /* Read extended boot record. */
  414         bp = geteblk((int)lp->d_secsize);
  415         bp->b_dev = dev;
  416         bp->b_blkno = ext_offset;
  417         bp->b_bcount = lp->d_secsize;
  418         bp->b_iocmd = BIO_READ;
  419         DEV_STRATEGY(bp, 1);
  420         if (bufwait(bp) != 0) {
  421                 disk_err(&bp->b_io, "reading extended partition table: error",
  422                     0, 1);
  423                 goto done;
  424         }
  425 
  426         /* Weakly verify it. */
  427         cp = bp->b_data;
  428         if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
  429                 sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART,
  430                                partname);
  431                 if (bootverbose)
  432                         printf("%s: invalid extended partition table: no magic\n",
  433                                sname);
  434                 goto done;
  435         }
  436 
  437         /* Make a copy of the partition table to avoid alignment problems. */
  438         memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
  439 
  440         slice = ssp->dss_nslices;
  441         for (dospart = 0, dp = &dpcopy[0]; dospart < NDOSPART;
  442             dospart++, dp++) {
  443                 ext_sizes[dospart] = 0;
  444                 if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
  445                     && dp->dp_start == 0 && dp->dp_size == 0)
  446                         continue;
  447                 if (dp->dp_typ == DOSPTYP_EXTENDED ||
  448                     dp->dp_typ == DOSPTYP_EXTENDEDX) {
  449                         static char buf[32];
  450 
  451                         sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE,
  452                                        RAW_PART, partname);
  453                         snprintf(buf, sizeof(buf), "%s", sname);
  454                         if (strlen(buf) < sizeof buf - 11)
  455                                 strcat(buf, "<extended>");
  456                         check_part(buf, dp, base_ext_offset, nsectors,
  457                                    ntracks, mbr_offset);
  458                         ext_offsets[dospart] = base_ext_offset + dp->dp_start;
  459                         ext_sizes[dospart] = dp->dp_size;
  460                 } else {
  461                         sname = dsname(dev, dkunit(dev), slice, RAW_PART,
  462                                        partname);
  463                         check_part(sname, dp, ext_offset, nsectors, ntracks,
  464                                    mbr_offset);
  465                         if (slice >= MAX_SLICES) {
  466                                 printf("%s: too many slices\n", sname);
  467                                 slice++;
  468                                 continue;
  469                         }
  470                         sp = &ssp->dss_slices[slice];
  471                         if (mbr_setslice(sname, lp, sp, dp, ext_offset) != 0)
  472                                 continue;
  473                         slice++;
  474                 }
  475         }
  476         ssp->dss_nslices = slice;
  477 
  478         /* If we found any more slices, recursively find all the subslices. */
  479         for (dospart = 0; dospart < NDOSPART; dospart++)
  480                 if (ext_sizes[dospart] != 0)
  481                         mbr_extended(dev, lp, ssp, ext_offsets[dospart],
  482                                      ext_sizes[dospart], base_ext_offset,
  483                                      nsectors, ntracks, mbr_offset, ++level);
  484 
  485 done:
  486         bp->b_flags |= B_INVAL | B_AGE;
  487         brelse(bp);
  488 }
  489 
  490 static int
  491 mbr_setslice(sname, lp, sp, dp, br_offset)
  492         char    *sname;
  493         struct disklabel *lp;
  494         struct diskslice *sp;
  495         struct dos_partition *dp;
  496         u_long  br_offset;
  497 {
  498         u_long  offset;
  499         u_long  size;
  500 
  501         offset = br_offset + dp->dp_start;
  502         if (offset > lp->d_secperunit || offset < br_offset) {
  503                 printf(
  504                 "%s: slice starts beyond end of the disk: rejecting it\n",
  505                        sname);
  506                 return (1);
  507         }
  508         size = lp->d_secperunit - offset;
  509         if (size >= dp->dp_size)
  510                 size = dp->dp_size;
  511         else
  512                 printf(
  513 "%s: slice extends beyond end of disk: truncating from %lu to %lu sectors\n",
  514                        sname, (u_long)dp->dp_size, size);
  515         sp->ds_offset = offset;
  516         sp->ds_size = size;
  517         sp->ds_type = dp->dp_typ;
  518 #ifdef PC98_ATCOMPAT
  519         /* Fake FreeBSD(98). */
  520         if (sp->ds_type == DOSPTYP_386BSD)
  521                 sp->ds_type = 0x94;
  522 #endif
  523 #if 0
  524         lp->d_subtype |= (lp->d_subtype & 3) | dospart | DSTYPE_INDOSPART;
  525 #endif
  526         return (0);
  527 }
  528 
  529 #ifdef __alpha__
  530 void
  531 alpha_fix_srm_checksum(bp)
  532         struct buf *bp;
  533 {
  534         u_int64_t *p;
  535         u_int64_t sum;
  536         int i;
  537 
  538         p = (u_int64_t *) bp->b_data;
  539         sum = 0;
  540         for (i = 0; i < 63; i++)
  541                 sum += p[i];
  542         p[63] = sum;
  543 }
  544 #endif

Cache object: a113936b417a33ad7fa42701e3679d9a


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