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/scsi/rz_labels.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  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990,1989 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        rz_labels.c,v $
   29  * Revision 2.11  93/11/17  18:44:36  dbg
   30  *      Need to always keep d_partitions[MAXPARTITIONS] correct, so
   31  *      always reset it ourselves.
   32  *      [93/10/08            rvb]
   33  * 
   34  * Revision 2.10  93/08/10  15:19:51  mrt
   35  *      We now use bsd labels internally and convert from "local labels"
   36  *      if we find them on the disk.
   37  *      [93/08/03  20:36:46  rvb]
   38  * 
   39  * Revision 2.9  93/05/10  21:22:41  rvb
   40  *      Removed depends on DEV_BSIZE.
   41  *      [93/05/06  10:09:09  af]
   42  * 
   43  * Revision 2.8  93/03/09  11:18:35  danner
   44  *      If there is no recognizable label, we must set p_size of the
   45  *      MAXPARTITION slice.  We use MAXPARTITION to do ABSOLUTE reads.
   46  *      [93/02/23            rvb]
   47  * 
   48  * Revision 2.7  92/08/03  17:53:58  jfriedl
   49  *      removed silly prototypes
   50  *      [92/08/02            jfriedl]
   51  * 
   52  * Revision 2.6  92/05/21  17:23:47  jfriedl
   53  *      tried prototypes.
   54  *      [92/05/20            jfriedl]
   55  * 
   56  * Revision 2.5  92/04/03  12:10:09  rpd
   57  *      Let "grab_bob_label" return failure so we take the default.
   58  *      [92/04/01            rvb]
   59  * 
   60  * Revision 2.4  92/02/23  22:44:31  elf
   61  *      Actually, scan for all possible (bogus) label formats.
   62  *      This makes it possible to cross-mount disks even if
   63  *      they do not have the standard BSD label.
   64  *      [92/02/22            af]
   65  * 
   66  * Revision 2.3  91/08/24  12:28:06  af
   67  *      Created, splitting out DEC-specific code from rz_disk.c and
   68  *      adding some more.
   69  *      [91/06/26            af]
   70  * 
   71  */
   72 /*
   73  *      File: rz_labels.c
   74  *      Author: Alessandro Forin, Carnegie Mellon University
   75  *      Date:   6/91
   76  *
   77  *      Routines for various vendor's disk label formats.
   78  */
   79 
   80 #include <platforms.h>
   81 
   82 #include <mach/std_types.h>
   83 #include <kern/memory.h>
   84 #include <scsi/compat_30.h>
   85 #include <scsi/scsi_defs.h>
   86 #include <scsi/rz_labels.h>
   87 
   88 #define LABEL_DEBUG(x,y) if (label_flag&x) y
   89 
   90 
   91 /*
   92  * Find and convert from a DEC label to BSD
   93  */
   94 boolean_t
   95 rz_dec_label(
   96         target_info_t           *tgt,
   97         struct disklabel        *label,
   98         io_req_t                ior)
   99 {
  100         /* here look for a DEC label */
  101         register scsi_dec_label_t       *part;
  102         char                            *data;
  103         int                             i, dev_bsize = tgt->block_size;
  104 
  105         ior->io_count = dev_bsize;
  106         ior->io_op = IO_READ;
  107         tgt->ior = ior;
  108         scdisk_read( tgt, DEC_LABEL_BYTE_OFFSET/dev_bsize, ior);
  109         iowait(ior);
  110         data = (char *)ior->io_data;
  111         part = (scsi_dec_label_t*)&data[DEC_LABEL_BYTE_OFFSET%dev_bsize];
  112         if (part->magic == DEC_LABEL_MAGIC) {
  113                 if (scsi_debug)
  114                 printf("{Using DEC label}");
  115                 for (i = 0; i < 8; i++) {
  116                         label->d_partitions[i].p_size = part->partitions[i].n_sectors;
  117                         label->d_partitions[i].p_offset = part->partitions[i].offset;
  118                 }
  119                 return TRUE;
  120         }
  121         return FALSE;
  122 }
  123 
  124 /*
  125  * Find and convert from a Omron label to BSD
  126  */
  127 boolean_t
  128 rz_omron_label(
  129         target_info_t           *tgt,
  130         struct disklabel        *label,
  131         io_req_t                ior)
  132 {
  133         /* here look for an Omron label */
  134         register scsi_omron_label_t     *part;
  135         char                            *data;
  136         int                             i, dev_bsize = tgt->block_size;
  137 
  138         ior->io_count = dev_bsize;
  139         ior->io_op = IO_READ;
  140         tgt->ior = ior;
  141         scdisk_read( tgt, OMRON_LABEL_BYTE_OFFSET/dev_bsize, ior);
  142         iowait(ior);
  143         data = (char *)ior->io_data;
  144         part = (scsi_omron_label_t*)&data[OMRON_LABEL_BYTE_OFFSET%dev_bsize];
  145         if (part->magic == OMRON_LABEL_MAGIC) {
  146                 if (scsi_debug)
  147                 printf("{Using OMRON label}");
  148                 for (i = 0; i < 8; i++) {
  149                         label->d_partitions[i].p_size = part->partitions[i].n_sectors;
  150                         label->d_partitions[i].p_offset = part->partitions[i].offset;
  151                 }
  152                 bcopy(part->packname, label->d_packname, 16);
  153                 label->d_ncylinders = part->ncyl;
  154                 label->d_acylinders = part->acyl;
  155                 label->d_ntracks = part->nhead;
  156                 label->d_nsectors = part->nsect;
  157                 /* Many disks have this wrong, therefore.. */
  158 #if 0
  159                 label->d_secperunit = part->maxblk;
  160 #else
  161                 label->d_secperunit = label->d_ncylinders * label->d_ntracks *
  162                                         label->d_nsectors;
  163 #endif
  164                 return TRUE;
  165         }
  166         return FALSE;
  167 }
  168 
  169 /*
  170  * Find and convert from a Intel BIOS label to BSD
  171  */
  172 extern int label_flag;
  173 extern int OS;
  174 #define BSDOS 165
  175 #define LBLLOC 1
  176 
  177 boolean_t
  178 rz_bios_bsd_label(
  179         target_info_t           *tgt,
  180         struct disklabel        *label,
  181         io_req_t                ior,
  182         struct bios_partition_info *ospart)
  183 {
  184         struct disklabel        *dlp;
  185         int                     dev_bsize = tgt->block_size;
  186         int                     i;
  187         extern int              allow_bsd_label;
  188 
  189         ior->io_count = dev_bsize;
  190         ior->io_op = IO_READ;
  191         tgt->ior = ior;
  192         scdisk_read( tgt, (ospart->offset + LBLLOC) * 512 / dev_bsize, ior);
  193         iowait(ior);
  194         dlp = (struct disklabel *)ior->io_data;
  195 
  196         if (dlp->d_magic  != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
  197                 if (OS == BSDOS) {
  198                         printf("NO BSD LABEL!!\n");
  199                 }
  200                 return FALSE;
  201         }
  202 
  203         printf("BSD LABEL ");
  204         LABEL_DEBUG(2,print_bsd_label(dlp, "dk:"));
  205         /*
  206          * here's where we dump label
  207          */
  208         if (allow_bsd_label == 0)
  209                 return FALSE;
  210 
  211         i = label->d_secperunit;
  212         *label = *dlp;
  213         label->d_secperunit = i;
  214                 /*
  215                  * The disklabel program should insure the invariant below
  216                  * when it writes a label.  But it does not seem to.
  217                  */
  218         label->d_partitions[MAXPARTITIONS].p_size = -1;
  219         label->d_partitions[MAXPARTITIONS].p_offset = 0;
  220         label->d_checksum = dkcksum(label);
  221 
  222         tgt->dev_info.disk.labeloffset = 0;
  223         tgt->dev_info.disk.labelsector = (ospart->offset + LBLLOC) * 512 / dev_bsize;
  224 
  225         LABEL_DEBUG(0x20,print_bsd_label(dlp, "   "));
  226         return TRUE;
  227 }
  228 
  229 boolean_t
  230 rz_bios_label(
  231         target_info_t           *tgt,
  232         struct disklabel        *label,
  233         io_req_t                ior)
  234 {
  235         /* here look for a BIOS label */
  236         char                            *data;
  237         int                             i, dev_bsize = tgt->block_size;
  238         scsi_bios_label_t               part;
  239 
  240         ior->io_count = dev_bsize;
  241         ior->io_op = IO_READ;
  242         tgt->ior = ior;
  243         scdisk_read( tgt, BIOS_LABEL_BYTE_OFFSET/dev_bsize, ior);
  244         iowait(ior);
  245         data = (char *)ior->io_data;
  246         /*
  247          * It's safer to just copy the data here and not worry about
  248          * scdisk_read's down the line will clobber the buffer.
  249          */
  250         part = *(scsi_bios_label_t*)&data[BIOS_LABEL_BYTE_OFFSET%dev_bsize];
  251         if (((scsi_bios_label_t*)&data[BIOS_LABEL_BYTE_OFFSET%dev_bsize])->magic 
  252              == BIOS_LABEL_MAGIC) {
  253                 struct bios_partition_info *bpart, *ospart = (struct bios_partition_info *)0;
  254                 if (scsi_debug)
  255                         printf("{Using BIOS label}");
  256                 for (i = 0; i < 4; i++) {
  257                         bpart = &(((struct bios_partition_info *)part.partitions)[i]);
  258                         LABEL_DEBUG(1,print_dos_partition(i, bpart));
  259                         label->d_partitions[i].p_size = bpart->n_sectors;
  260                         label->d_partitions[i].p_offset = bpart->offset;
  261                         if (bpart->systid == UNIXOS || bpart->systid == BSDOS) {
  262                                 if (ospart != 0) {
  263                                         if (bpart->bootid == BIOS_BOOTABLE)
  264                                                 ospart = bpart;
  265                                 } else
  266                                         ospart = bpart;
  267                         }
  268                 }
  269                 tgt->dev_info.disk.l.d_partitions[MAXPARTITIONS].p_offset= 0;
  270                 tgt->dev_info.disk.l.d_partitions[MAXPARTITIONS].p_size  = -1;
  271 
  272                 if (ospart == 0)
  273                         return FALSE;
  274                 OS = ospart->systid;
  275                 if (OS == UNIXOS)
  276                         printf("sd%d: MACH OS ", tgt->target_id);
  277                 if (OS == BSDOS)
  278                         printf("sd%d: XXXBSD OS ", tgt->target_id);
  279 
  280                 if (rz_bios_bsd_label(tgt, label, ior, ospart))
  281                         return TRUE;
  282 
  283 #ifdef  AT386   /* this goes away real fast */
  284                 if (!grab_bob_label(tgt, label, ior,
  285                                     ((struct bios_partition_info *)part.partitions)))
  286                         return FALSE;           /* take default setup of "a" and "c" */
  287 #else
  288                 label->d_npartitions = 4;
  289 #endif
  290                 label->d_bbsize = BIOS_BOOT0_SIZE;
  291                 return TRUE;
  292         }
  293         return FALSE;
  294 }
  295 
  296 /*
  297  * Try all of the above
  298  */
  299 boolean_t rz_vendor_label(
  300         target_info_t           *tgt,
  301         struct disklabel        *label,
  302         io_req_t                ior)
  303 {
  304         /* If for any reason there might be problems someday.. */
  305 #ifdef  VENDOR_LABEL
  306         if (VENDOR_LABEL( tgt, label, ior)) return TRUE;
  307 #endif  /*VENDOR_LABEL*/
  308 
  309         if (rz_dec_label( tgt, label, ior)) return TRUE;
  310         if (rz_bios_label( tgt, label, ior)) return TRUE;
  311         if (rz_omron_label( tgt, label, ior)) return TRUE;
  312         return FALSE;
  313 }
  314 

Cache object: ebea0e20fa8e34e288071e42ad0a8dc1


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