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/pc_scsi_label.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,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:        pc_scsi_label.c,v $
   29  * Revision 2.9  93/11/17  18:42:05  dbg
   30  *      Delinted.  Added ANSI function prototypes.
   31  *      [93/09/28            dbg]
   32  * 
   33  * Revision 2.8  93/08/10  16:02:19  mrt
   34  *      Moved here from i386at/grab_bob_label.c as the code now works
   35  *      on scsi disks on many platforms.
   36  *              We now use bsd labels internally and convert from "local labels"
   37  *              if we find them on the disk.
   38  *      [93/08/05            rvb]
   39  * 
   40  * Revision 2.7  93/03/09  11:18:39  danner
   41  *      If there is no recognizable label, we must return sensible
   42  *      defaults for getstatus or freak out diskutil.  Alternatively,
   43  *      we could ship a new diskutil.
   44  *      [93/02/23            rvb]
   45  * 
   46  * Revision 2.6  92/07/09  22:53:52  rvb
   47  *      No need to print out the relation between capacity and stated geometry.
   48  *      Also adjust GETPARMS answer's to the adaptec's view of reality.
   49  *      [92/06/18            rvb]
   50  *      tgt->unit_no is not set up correctly now; should use masterno instead
   51  *      [92/05/22  17:31:10  rvb]
   52  * 
   53  *      Fixed by Jukka Virtanen <jtv@kampi.hut.fi>
   54  * 
   55  * Revision 2.5  92/04/03  12:08:41  rpd
   56  *      Reviewed with and blessed (?) by af.
   57  *      [92/04/01            rvb]
   58  *      Merged bernadat's change to mainline.  Made conditional
   59  *      on i386 vs AT386.
   60  *      [92/03/16            rvb]
   61  *      Add AT specific setstatus/getstatus flavors
   62  *      to support vtoc, diskutil, verify ...
   63  *      [92/03/04            bernadat]
   64  * 
   65  * Revision 2.4  92/02/23  22:43:04  elf
   66  *      Dropped first scsi_softc argument.
   67  *      [92/02/22  19:58:21  af]
   68  * 
   69  * Revision 2.3  92/02/19  16:29:46  elf
   70  *      On 25-Jan, did not consider NO ACTIVE mach parition.
   71  *      [92/01/31            rvb]
   72  * 
   73  *      Add "BIOS" support -- always boot mach partition NOT active one.
   74  *      [92/01/25            rvb]
   75  * 
   76  * Revision 2.2  91/08/24  11:57:41  af
   77  *      Temporarily created, till we evaporate the religious issues.
   78  *      [91/08/02            af]
   79  * 
   80  */
   81 /* This goes away as soon as we move it in the Ux server */
   82 
   83 #include <mach/std_types.h>
   84 #include <kern/kern_io.h>
   85 #include <kern/memory.h>
   86 #include <vm/vm_kern.h>
   87 #include <scsi/compat_30.h>
   88 #include <scsi/scsi.h>
   89 #include <scsi/scsi_defs.h>
   90 #include <scsi/rz.h>
   91 #include <scsi/rz_labels.h>
   92 #include <sys/types.h>
   93 #include <sys/ioctl.h>
   94 
   95 #define LABEL_DEBUG(x,y) if (label_flag&x) y
   96 
   97 #include <i386at/disk.h>
   98 #include <i386at/hdreg.h>
   99 #include <device/device_types.h>
  100 #include <device/disk_status.h>
  101 
  102 int grab_bob_label(
  103         target_info_t           *tgt,
  104         struct disklabel        *label,
  105         io_req_t                ior,
  106         struct bios_partition_info *bpart)
  107 {
  108         register int            i, n;
  109         struct evtoc            *evp;
  110         struct bios_partition_info *ospart = (struct bios_partition_info *)0;
  111         struct bios_partition_info *first_part = bpart;
  112         int                     upart;
  113         int                     dev_bsize = tgt->block_size;
  114         extern int              label_flag;
  115 
  116 #ifdef  old
  117         {
  118                 int nmach = 0;
  119                 int     mabr = 0,
  120                         mbr = 0;
  121 
  122                 for (i = 0; i < 4; i++) {
  123                         if (bpart[i].systid == UNIXOS) {
  124                                 if (!nmach++)
  125                                         mbr = i;
  126                                 if (bpart[i].bootid == BIOS_BOOTABLE)
  127                                         mabr = i;
  128                         }
  129                 }
  130                 if (mabr)
  131                         i = mabr;
  132                 else if (nmach == 1)
  133                         i = mbr;
  134                 else if (nmach == 0)
  135                         return 0;       /* DOS, no Mach */
  136                 else {
  137                         printf("Warning: More than one Mach partition and none active.\n");
  138                         printf("Using DOS partition #%d\n", mbr);
  139                         i = mbr;
  140                 }
  141         }
  142 #else   /* old */
  143         for (i = 0; i < 4; i++, bpart++) {
  144                 LABEL_DEBUG(1, print_dos_partition(i, bpart));
  145                 if (bpart->systid == UNIXOS || bpart->systid == BSDOS) {
  146                         if (ospart != 0) {
  147                                 if (bpart->bootid == ACTIVE)
  148                                         ospart = bpart;
  149                         } else
  150                                 ospart = bpart;
  151                 }
  152         }
  153         if (ospart == 0)
  154                 return 0;
  155 #endif  /* old */
  156         OS = ospart->systid;
  157         if (OS == UNIXOS)
  158                 printf("sd%d: MACH OS ", tgt->target_id);
  159         if (OS == BSDOS)
  160                 printf("sd%d: XXXBSD OS ", tgt->target_id);
  161         upart = ospart - first_part;
  162         tgt->dev_info.disk.labeloffset = 0;
  163         tgt->dev_info.disk.labelsector = (ospart->offset + LBLLOC) * 512 / dev_bsize;
  164         /*
  165          * In rz_labels:rz_bios_label(), we have set up DOS partitions 0-3 to correspond
  166          * to the parittions 0-3 in the label.  Hence we use the "upart" above, in
  167          * the line below.
  168          */
  169         ior->io_unit = (tgt->masterno<<6) + (tgt->target_id<<3) + (upart);
  170         ior->io_count = DEV_BSIZE;
  171         ior->io_error = 0;
  172         ior->io_op = IO_READ;
  173         ior->io_recnum = 29;    /* that's where the vtoc is */
  174         scdisk_strategy(ior);
  175         iowait(ior);
  176         evp = (struct evtoc *)ior->io_data;
  177 
  178         if (evp->sanity != VTOC_SANE) {
  179                 printf("vtoc insane\n");
  180                 return 0;
  181         }
  182 
  183         printf("LOCAL LABEL ");
  184         LABEL_DEBUG(4,print_local_label(evp, "ev:"));
  185 
  186         bcopy(evp->label, label->d_packname, 16);/* truncates, too bad */
  187         n = evp->nparts;
  188         if (n >= MAXPARTITIONS)
  189                 n = MAXPARTITIONS;
  190         fudge_bsd_label(label, DTYPE_SCSI, evp->cyls, evp->tracks, evp->sectors, n);
  191 #ifdef  you_care
  192         if (label->d_secperunit != evp->tracks * evp->sectors * evp->cyls)
  193                 printf("sd%d: capacity (%d) != S*H*C (%d)\n", tgt->target_id,
  194                         label->d_secperunit, evp->tracks * evp->sectors * evp->cyls);
  195 #endif
  196         /* copy info on first MAXPARTITIONS */
  197                 /* "c" is never read; always calculated */
  198         label->d_partitions[2].p_size = label->d_partitions[upart].p_size;
  199         label->d_partitions[2].p_offset = label->d_partitions[upart].p_offset;
  200         for (i = 0; i < n ; i++) {
  201                 if (i == 2)
  202                         continue;
  203                 bzero(&(label->d_partitions[i]), sizeof (struct partition));
  204                 label->d_partitions[i].p_size = evp->part[i].p_size;
  205                 label->d_partitions[i].p_offset = evp->part[i].p_start;
  206                 label->d_partitions[i].p_fstype = FS_BSDFFS;
  207         }
  208         for ( ; i < MAXPARTITIONS; i++) {
  209                 if (i == 2)
  210                         continue;
  211                 bzero(&(label->d_partitions[i]), sizeof (struct partition));
  212         }
  213                 /* whole disk */
  214         label->d_partitions[MAXPARTITIONS].p_size = -1;
  215         label->d_partitions[MAXPARTITIONS].p_offset = 0;
  216         label->d_checksum = dkcksum(label);
  217         LABEL_DEBUG(0x20,print_bsd_label(label, "   "));
  218         return 1;
  219 }
  220 
  221 int scsi_abs_sec = -1;
  222 int scsi_abs_count = -1;
  223 
  224 io_return_t
  225 scsi_rw_abs(
  226         dev_t           dev,
  227         io_buf_ptr_t    data,
  228         int             rw,
  229         int             sec,
  230         natural_t       count)
  231 
  232 {
  233         io_req_t        ior;
  234         io_return_t     error;
  235 
  236         io_req_alloc(ior,0);
  237         ior->io_next = 0;
  238         ior->io_unit = dev & (~(MAXPARTITIONS-1));      /* sort of */
  239         ior->io_unit |= PARTITION_ABSOLUTE;
  240         ior->io_data = data;
  241         ior->io_count = count;
  242         ior->io_recnum = sec;
  243         ior->io_error = 0;
  244         if (rw == IO_READ)
  245                 ior->io_op = IO_READ;
  246         else
  247                 ior->io_op = IO_WRITE;
  248         scdisk_strategy(ior);
  249         iowait(ior);
  250         error = ior->io_error;
  251         io_req_free(ior);
  252         return error;
  253 }
  254 
  255 io_return_t
  256 scsi_i386_get_status(
  257         int             dev,
  258         target_info_t   *tgt,
  259         int             flavor,
  260         dev_status_t    status,
  261         natural_t       *status_count)
  262 {
  263 
  264         switch (flavor) {
  265         case V_GETPARMS: {
  266                 struct disklabel *lp = &tgt->dev_info.disk.l;
  267                 struct disk_parms *dp = (struct disk_parms *)status;
  268                 extern struct disklabel scsi_default_label;
  269                 int part = rzpartition(dev);
  270 
  271                 if (*status_count < sizeof (struct disk_parms)/sizeof(int))
  272                         return D_INVALID_OPERATION;
  273                 dp->dp_type = DPT_WINI; 
  274                 dp->dp_secsiz = lp->d_secsize;
  275                 if (lp->d_nsectors == scsi_default_label.d_nsectors &&
  276                     lp->d_ntracks == scsi_default_label.d_ntracks &&
  277                     lp->d_ncylinders == scsi_default_label.d_ncylinders) {
  278                         /* I guess there is nothing there */
  279                         /* Well, then, Adaptecs like ... */
  280                         dp->dp_sectors = 32;
  281                         dp->dp_heads = 64;
  282                         dp->dp_cyls = lp->d_secperunit / 64 / 32 ;
  283                 } else {
  284                         dp->dp_sectors = lp->d_nsectors;
  285                         dp->dp_heads = lp->d_ntracks;
  286                         dp->dp_cyls = lp->d_ncylinders;
  287                 }
  288 
  289                 dp->dp_dossectors = 32;
  290                 dp->dp_dosheads = 64;
  291                 dp->dp_doscyls = lp->d_secperunit / 64 / 32;
  292                 dp->dp_ptag = 0;
  293                 dp->dp_pflag = 0;
  294                 dp->dp_pstartsec = lp->d_partitions[part].p_offset;
  295                 dp->dp_pnumsec = lp->d_partitions[part].p_size;
  296                 *status_count = sizeof(struct disk_parms)/sizeof(int);
  297                 break;
  298         }
  299         case V_RDABS:
  300                 if (*status_count < DEV_BSIZE/sizeof (int)) {
  301                         printf("RDABS bad size %x", *status_count);
  302                         return D_INVALID_OPERATION;
  303                 }
  304                 if (scsi_rw_abs(dev,
  305                                 (io_buf_ptr_t) status,
  306                                 IO_READ,
  307                                 scsi_abs_sec,
  308                                 DEV_BSIZE) != D_SUCCESS)
  309                         return D_INVALID_OPERATION;
  310                 *status_count = DEV_BSIZE/sizeof(int);
  311                 break;
  312         case V_VERIFY: {
  313                 int count = scsi_abs_count * DEV_BSIZE;
  314                 int sec = scsi_abs_sec;
  315                 char *scsi_verify_buf;
  316 
  317                 (void) kmem_alloc(kernel_map,
  318                                   (vm_offset_t *) &scsi_verify_buf,
  319                                   PAGE_SIZE);
  320 
  321                 *status = 0;
  322                 while (count > 0) {
  323                         int xcount = (count < PAGE_SIZE) ? count : PAGE_SIZE;
  324                         if (scsi_rw_abs(dev, scsi_verify_buf, IO_READ,
  325                                         sec, xcount) != D_SUCCESS)
  326                         {
  327                                 *status = BAD_BLK;
  328                                 break;
  329                         } else {
  330                                 count -= xcount;
  331                                 sec += xcount / DEV_BSIZE;
  332                         }
  333                 }
  334                 (void) kmem_free(kernel_map,
  335                                  (vm_offset_t) scsi_verify_buf,
  336                                  PAGE_SIZE);
  337                 *status_count = 1;
  338                 break;
  339         }
  340         default:
  341                 return D_INVALID_OPERATION;
  342         }
  343         return D_SUCCESS;
  344 }
  345 
  346 io_return_t
  347 scsi_i386_set_status(
  348         int             dev,
  349         target_info_t   *tgt,
  350         int             flavor,
  351         dev_status_t    status,
  352         natural_t       status_count)
  353 {
  354         switch (flavor) {
  355         case V_SETPARMS:
  356                 printf("scsdisk_set_status: invalid flavor V_SETPARMS\n");
  357                 return D_INVALID_OPERATION;
  358                 break;
  359         case V_REMOUNT:
  360                 tgt->flags &= ~TGT_ONLINE;
  361                 break;
  362         case V_ABS:
  363                 scsi_abs_sec = status[0];
  364                 if (status_count == 2)
  365                         scsi_abs_count = status[1];
  366                 break;
  367         case V_WRABS:
  368                 if (status_count < DEV_BSIZE/sizeof (int)) {
  369                         printf("RDABS bad size %x", status_count);
  370                         return D_INVALID_OPERATION;
  371                 }
  372                 if (scsi_rw_abs(dev,
  373                                 (io_buf_ptr_t) status,
  374                                 IO_WRITE,
  375                                 scsi_abs_sec,
  376                                 DEV_BSIZE) != D_SUCCESS)
  377                         return D_INVALID_OPERATION;
  378                 break;
  379         default:
  380                 return D_INVALID_OPERATION;
  381         }
  382         return D_SUCCESS;
  383 }

Cache object: 6f2481423d04eb544a6da03cdfbc0e60


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