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

Cache object: c78d8c4915283491348ef921840f6679


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