diff options
Diffstat (limited to 'scsi/disk_label.c')
-rw-r--r-- | scsi/disk_label.c | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/scsi/disk_label.c b/scsi/disk_label.c deleted file mode 100644 index ab20378..0000000 --- a/scsi/disk_label.c +++ /dev/null @@ -1,692 +0,0 @@ -/* - * Copyright (c) 1996 The University of Utah and - * the Computer Systems Laboratory at the University of Utah (CSL). - * All rights reserved. - * - * Permission to use, copy, modify and distribute this software is hereby - * granted provided that (1) source code retains these copyright, permission, - * and disclaimer notices, and (2) redistributions including binaries - * reproduce the notices in supporting documentation, and (3) all advertising - * materials mentioning features or use of this software display the following - * acknowledgement: ``This product includes software developed by the - * Computer Systems Laboratory at the University of Utah.'' - * - * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS - * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF - * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * CSL requests users of this software to return to csl-dist@cs.utah.edu any - * improvements that they make and grant CSL redistribution rights. - * - * Author: Kevin T. Van Maren, University of Utah CSL - */ - -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -/* - * Copyright (c) 1994 Shantanu Goel - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - */ - -/* This file contains the partition code that is used by the Mach - * device drivers (ide & scsi). */ - -#include <scsi/compat_30.h> -#include <sys/types.h> - -#include <scsi/rz_labels.h> -#include <i386at/disk.h> /* combine & rename these... */ - -#define SECTOR_SIZE 512 /* BAD!!! */ - -#define DSLICE(dev) ((dev >> 4) & 0x3f) -#define DPART(dev) (dev & 0xf) - -/* note: 0 will supress ALL output; - 1 is 'normal' output; 2 is verbose; 3 is Very verbose */ -#define PARTITION_DEBUG 1 - -#define min(x,y) (x<y?x:y) - -/* - * Label that is filled in with extra info - */ -struct disklabel default_label = -{ - DISKMAGIC, DTYPE_SCSI, 0, - "SCSI", "", - DEV_BSIZE, 1, 1, 1, 1, 1, 0, 0, 0, - 3600, 1, 1, 1, 0, 0, 0, - {0,}, {0,}, - DISKMAGIC, 0, - 8, 8192, 8192, - {{ -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }, - { -1, 0, 1024, FS_BSDFFS, 8, 3 }} -}; - - - -/* the device driver calls this just to save some info it got from the HW */ -/* This is a bad holdover from the disklabel days, and needs to go */ -fudge_bsd_label(struct disklabel *label, int type, int total_secs, int heads, int sectors, int sectorsize, int n) -{ - *label=default_label; - - label->d_ncylinders = total_secs/(heads*sectors); - label->d_ntracks = heads; - label->d_nsectors = sectors; - - label->d_secpercyl = heads*sectors; - label->d_secperunit = total_secs; - - /* this is never used, but ... */ - label->d_partitions[MAXPARTITIONS].p_offset = 0; - label->d_partitions[MAXPARTITIONS].p_size = total_secs; - - /* ?? - */ - label->d_secsize = sectorsize; - label->d_type = type; - label->d_subtype = 0xa; /* ??? */ - - label->d_npartitions = n; /* up to 'c' */ - label->d_checksum = 0; - - /* should do a checksum on it now */ -} - - - -/* This is placed here to - a. provide comparability with existing servers - b. allow the use of FreeBSD-style slices to access ANY disk partition - c. provide an easy migration path to lites-based partition code - by only passing the drive name to get the entire disk (sd0). - - This will be called by every routine that needs to access partition info - based on a device number. It is slower than the old method of indexing - into a disklabel, but is more flexible, and reasonably fast in the (future) - case where Lites will access the whole disk. An array of disklabels - could have been used, but this is more compact and general. The underlying - structure does not limit it to 2-levels, but keeping the kernel interface - simple does. */ - - -/* this code and data structure based on conversation with Bryan Ford */ -/* Note: this is called ON EVERY read or write. It makes sense to - optimize this for the common case. Hopefully the common case - will become the '0,0' case, as partitioning is moved out of the - kernel. (Downside is kernel can't protect filesystems from each other). - It is slower than indexing into a 1-D array, but not much. */ - -struct diskpart *lookup_part(struct diskpart *array, int dev_number) -{ -/* Note: 10 bit encoding to get partitions 0-15 (0,a-h typically), and slices - * 0-63 - */ - - int slice = DSLICE(dev_number); - int part = DPART(dev_number); - struct diskpart *s; - - if (slice == 0) /* compatability slice */ - { - if (part == 0) /* whole disk */ - return &array[0]; - - if (array[0].type == DISKPART_DOS) - { - int i; - for (i = 0; i < array[0].nsubs; i++) - { - s = &array[0].subs[i]; - if ( s->type == DISKPART_BSD - || s->type == DISKPART_VTOC) - { - if (part > s->nsubs) - return 0; - return (&s->subs[part-1]); - } - } - } - - if (part > array[0].nsubs) - return 0; - return(&array[0].subs[part-1]); - } - else - { - if ( array[0].type != DISKPART_DOS - || slice > array[0].nsubs) - return 0; - - s = &array[0].subs[slice-1]; - - if (part == 0) /* whole slice */ - return (s); - if (part > s->nsubs) - return 0; - - return (&s->subs[part-1]); - } -} - - - - -static inline void fill_array(struct diskpart *array, int start, int size, - struct diskpart *subs, int nsubs, short type, short fsys) -{ - array->start=start; - array->size=size; - array->subs=subs; - array->nsubs=nsubs; - array->type=type; - array->fsys=fsys; -#if (PARTITION_DEBUG > 2) - printf("fill: type %d:%d, start %d, size %d, %d parts\n",type,fsys, - start,size,nsubs); -#endif -} - - - - -void print_array(struct diskpart *array, int level) -{ - int i,j; - struct diskpart *subs; - -#if (PARTITION_DEBUG) - subs=array[0].subs; - - for (i=0;i<array[0].nsubs;i++) { - for (j=0;j<level;j++) - printf(" "); - printf("%c: %d, %d, %d, %d (%d subparts)\n",'a'+i, - subs[i].start, subs[i].size, subs[i].fsys, - subs[i].type, subs[i].nsubs); - if (subs[i].nsubs>0) - print_array(&subs[i], level+1); - } -#endif -} - - - -/* individual routines to find the drive labels. - There needs to be a function for every different method for partitioning - much of the following code is derived from the SCSI/IDE drivers */ - -int get_dos(struct diskpart *array, char *buff, int start, - void *driver_info, int (*bottom_read_fun)(), - char *name, int max_part) -{ - - bios_label_t *mp; - struct bios_partition_info *pp; - - int count, i, j; - int pstart, psize; - int ext=-1, mystart=start, mybase; - int first=1; - - /* note: start is added, although a start != 0 is meaningless - to DOS and anything else... */ - - /* check the boot sector for a partition table. */ - (*bottom_read_fun)(driver_info, start, buff); /* always in sector 0 */ - - /* - * Check for valid partition table. - */ - mp = (bios_label_t *)&buff[BIOS_LABEL_BYTE_OFFSET]; - if (mp->magic != BIOS_LABEL_MAGIC) { -#if (PARTITION_DEBUG>1) - printf("%s invalid partition table\n", name); -#endif - return(0); /* didn't add any partitions */ - } -#if (PARTITION_DEBUG>1) - printf("DOS partition table found\n"); -#endif - - count=min(4,max_part); /* always 4 (primary) partitions */ -#if (PARTITION_DEBUG) - if (count<4) printf("More partitions than space!\n"); -#endif - - - /* fill the next 4 entries in the array */ - for (i=0, pp=(struct bios_partition_info *)mp->partitions; - i<count; i++,pp++) { - - fill_array(&array[i], pp->offset, pp->n_sectors, NULL, 0, - DISKPART_NONE, pp->systid); - if ((pp->systid == DOS_EXTENDED) &&(ext<0)) { - mystart+=pp->offset; - ext=i; - } - } - - /* if there is an extended partition, find all the logical partitions */ - /* note: logical start at '5' (extended is one of the numbered 1-4) */ - - /* logical partitions 'should' be nested inside the primary, but - then it would be impossible to NAME a disklabel inside a logical - partition, which would be nice to do */ -#if (PARTITION_DEBUG>1) - if (ext>=0) - printf("extended partition found: %d\n",ext); -#endif 0 - - while (ext>=0) { - pp = &(((struct bios_partition_info *)mp->partitions)[ext]); - - /* read the EXTENDED partition table */ - if (first) { - mybase=mystart; - first=0; - } else { - mybase=mystart+pp->offset; - } - - (*bottom_read_fun)(driver_info, mybase, buff); - - if (mp->magic != BIOS_LABEL_MAGIC) { -#if (PARTITION_DEBUG>1) - printf("%s invalid expanded magic\n", name); -#endif - return(count);/*don't add any more partitions*/ - } - - /* just in case more than one partition is there...*/ - /* search the EXTENDED partition table */ - ext=-1; - for (j=0,pp=(struct bios_partition_info *)mp->partitions; - j<4; j++,pp++) { - - if (pp->systid && (pp->systid!=DOS_EXTENDED)) { - if (count<max_part) { - fill_array(&array[count], - mybase +pp->offset, - pp->n_sectors, NULL, 0, DISKPART_NONE, - pp->systid); - count++; } - else { -#if (PARTITION_DEBUG) - printf("More partitions than space!\n"); -#endif - return(count); - } - } else if ((ext<0) &&(pp->systid==DOS_EXTENDED)) { - ext=j; - /* recursivly search the chain here */ - } - } - } -#if (PARTITION_DEBUG>1) - printf("%d dos partitions\n",count); -#endif 0 - return(count); /* number dos partitions found */ - -} - - - -/* this should work on the bare drive, or in a dos partition */ -int get_disklabel(struct diskpart *array, char *buff, int start, - void *driver_info, int (*bottom_read_fun)(), - char *name, int max_part) -{ - struct disklabel *dlp; - int mybase = start + (512 * LBLLOC)/SECTOR_SIZE, i; - int count; - - (*bottom_read_fun)(driver_info, mybase, buff); - - dlp = (struct disklabel *)buff; - if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { -#if (PARTITION_DEBUG>1) - printf("%s no BSD label found\n",name); -#endif - return(0); /* no partitions added */ - } -#if (PARTITION_DEBUG>1) - printf(" BSD LABEL\n"); -#endif 0 - /* note: BSD disklabel offsets are from start of DRIVE -- uuggh */ - - count=min(8,max_part); /* always 8 in a disklabel */ -#if (PARTITION_DEBUG) - if (count<8) printf("More partitions than space!\n"); -#endif - /* COPY into the array */ - for (i=0;i<count;i++) - fill_array(&array[i], /* mybase + */ - dlp->d_partitions[i].p_offset, - dlp->d_partitions[i].p_size, - NULL, 0, DISKPART_NONE, dlp->d_partitions[i].p_fstype); - - /* note: p_fstype is not the same set as the DOS types */ - - return(count); /* 'always' 8 partitions in disklabel -- if space */ - -/* UNREACHED CODE FOLLOWS: (alternative method in scsi) */ -#if 0 - (*bottom_read_fun)(driver_info, (start)+LABELSECTOR, buff); - - register int j; - boolean_t found; - - for (j = LABELOFFSET, found = FALSE; - j < (SECTOR_SIZE-sizeof(struct disklabel)); - j += sizeof(int)) { - search = (struct disklabel *)&buff[j]; - if (search->d_magic == DISKMAGIC && - search->d_magic2 == DISKMAGIC) { - found = TRUE; - break; - } - } - if (found) { -#if (PARTITION_DEBUG>1) - printf("Label found in LABELSECTOR\n"); -#endif - } else { - search = 0; - } - - -#endif 0 - -} - - -/* NOT TESTED! */ -/* VTOC in sector 29 */ -int get_vtoc(struct diskpart *array, char *buff, int start, - void *driver_info, int (*bottom_read_fun)(), - char *name, int max_part) -{ - struct evtoc *evp; - int n,i; - struct disklabel lpl; - struct disklabel *lp = &lpl; - -#if (PARTITION_DEBUG) - printf("Read VTOC.\n"); -#endif - (*bottom_read_fun)(driver_info, start +PDLOCATION, buff); - evp = (struct evtoc *)buff; - if (evp->sanity != VTOC_SANE) { -#if (PARTITION_DEBUG) - printf("%s evtoc corrupt or not found\n", name); -#endif - return(0); - } - n = min(evp->nparts,max_part); /* no longer DISKLABEL limitations... */ -#if 0 - n = (evp->nparts > MAXPARTITIONS) ? MAXPARTITIONS : evp->nparts; -#endif 0 - - for (i = 0; i < n; i++) - fill_array(&array[i], /* mybase + */ - evp->part[i].p_start, - evp->part[i].p_size, - NULL, 0, DISKPART_NONE, FS_BSDFFS); - - return(n); /* (evp->nparts) */ -} - - -/* NOT TESTED! */ -int get_omron(struct diskpart *array, char *buff, int start, - void *driver_info, int (*bottom_read_fun)(), - char *name, int max_part) -{ - - struct disklabel *label; - - /* here look for an Omron label */ - register omron_label_t *part; - int i; - -#if (PARTITION_DEBUG) - printf("Looking for Omron label...\n"); -#endif - - (*bottom_read_fun)(driver_info, start+ - OMRON_LABEL_BYTE_OFFSET/SECTOR_SIZE, buff); - - part = (omron_label_t*)&buff[OMRON_LABEL_BYTE_OFFSET%SECTOR_SIZE]; - if (part->magic == OMRON_LABEL_MAGIC) { -#if (PARTITION_DEBUG) - printf("{Using OMRON label}"); -#endif - for (i = 0; i < 8; i++) { - label->d_partitions[i].p_size = part->partitions[i].n_sectors; - label->d_partitions[i].p_offset = part->partitions[i].offset; - } - bcopy(part->packname, label->d_packname, 16); - label->d_ncylinders = part->ncyl; - label->d_acylinders = part->acyl; - label->d_ntracks = part->nhead; - label->d_nsectors = part->nsect; - /* Many disks have this wrong, therefore.. */ -#if 0 - label->d_secperunit = part->maxblk; -#else - label->d_secperunit = label->d_ncylinders * label->d_ntracks * - label->d_nsectors; -#endif 0 - - return(8); - } -#if (PARTITION_DEBUG) - printf("No Omron label found.\n"); -#endif - return(0); -} - - -/* NOT TESTED! */ -int get_dec(struct diskpart *array, char *buff, int start, - void *driver_info, int (*bottom_read_fun)(), - char *name, int max_part) -{ - struct disklabel *label; - - /* here look for a DEC label */ - register dec_label_t *part; - int i; - -#if (PARTITION_DEBUG) - printf("Checking for dec_label...\n"); -#endif - - (*bottom_read_fun)(driver_info, start + - DEC_LABEL_BYTE_OFFSET/SECTOR_SIZE, buff); - - if (part->magic == DEC_LABEL_MAGIC) { -#if (PARTITION_DEBUG) - printf("{Using DEC label}"); -#endif - for (i = 0; i < 8; i++) { - label->d_partitions[i].p_size = part->partitions[i].n_sectors; - label->d_partitions[i].p_offset = part->partitions[i].offset; - } - return(8); - } -#if (PARTITION_DEBUG) - printf("No dec label found.\n"); -#endif - - return(0); -} - - - - -/* array is a pointer to an array of partition_info structures */ -/* array_size is the number of pre-allocated entries there are */ -int get_only_partition(void *driver_info, int (*bottom_read_fun)(), - struct diskpart *array, int array_size, - int disk_size, char *drive_name) -{ - char buff[SECTOR_SIZE]; - int i,n,cnt; - int arrsize; - struct diskpart *res; - - /* first fill in the entire disk stuff */ - /* or should the calling routine do that already? */ - - fill_array(array, 0, disk_size, NULL, 0, -1, -1); - - /* while the structure does not preclude additional nestings, - additional ones make no sense currently, so they are not - checked (Mach can't handle them anyway). It might be nice - if for all partitions found, all types of sub-partitions - were looked for (unnecessary). This will be done when this - is moved out of ther kernel, and there is some way to name them */ - - arrsize = array_size -1; /* 1 for whole disk */ - - /* search for dos partition table */ - /* find all the partitions (including logical) */ - n=get_dos(&array[1], buff, 0, - driver_info, (bottom_read_fun), drive_name, - arrsize); - - if (n>0) { - fill_array(array, 0, disk_size, &array[1], n, - DISKPART_DOS, 256+DISKPART_DOS); - arrsize-=n; - - - /* search each one for a BSD disklabel (iff BSDOS) */ - /* note: searchine extended and logical partitions */ - for (i=0;i<n;i++) - if (array[i+1].fsys==BSDOS) { -#if (PARTITION_DEBUG) - printf("BSD OS slice: %d\n",i+1); -#endif - cnt=get_disklabel(&array[n+1], buff, - array[i+1].start, - driver_info, (bottom_read_fun), - drive_name,arrsize); - - if (cnt>0) { - arrsize-=cnt; - fill_array(&array[i+1],array[i+1].start, - array[i+1].size, &array[n+1], - cnt, DISKPART_BSD, - array[i+1].fsys); - } - n+=cnt; - } - - /* search for VTOC -- in a DOS partition as well */ - for (i=0;i<n;i++) - if (array[i+1].fsys==UNIXOS) { -#if (PARTITION_DEBUG) - printf("UNIXOS (vtoc) partition\n"); -#endif - cnt=get_vtoc(&array[n+1], buff, - array[i+1].start, - driver_info, (bottom_read_fun), - drive_name,arrsize); - - if (cnt>0) { - arrsize-=cnt; - fill_array(&array[i+1],array[i+1].start, - array[i+1].size, &array[n+1], - cnt, DISKPART_VTOC, - array[i+1].fsys); - } - n+=cnt; - } - } - - /* search for only disklabel */ - if (n==0) { - fill_array(array, 0, disk_size, &array[1], n, DISKPART_BSD, - 256+DISKPART_BSD); - n=get_disklabel(&array[1], buff, 0, driver_info, - (bottom_read_fun), drive_name,arrsize); - } - - /* search for only VTOC -- NOT TESTED! */ - if (n==0) { - fill_array(array, 0, disk_size, &array[1], n, DISKPART_VTOC, - 256+DISKPART_VTOC); - n=get_vtoc(&array[1], buff, 0, driver_info, (bottom_read_fun), - drive_name,arrsize); - } -#if 0 - /* search for only omron -- NOT TESTED! */ - if (n==0) { - fill_array(array, 0, disk_size, &array[1], n, DISKPART_OMRON, - 256+DISKPART_OMRON); - n=get_omron(&array[1], buff, 0,driver_info, (bottom_read_fun), - drive_name,arrsize); - } - - /* search for only dec -- NOT TESTED! */ - if (n==0) { - fill_array(array, 0, disk_size, &array[1], n, DISKPART_DEC, - 256+DISKPART_DEC); - n=get_dec(&array[1], buff, 0, driver_info, (bottom_read_fun), - drive_name,arrsize); - } -#endif 0 - -#if (PARTITION_DEBUG) /* print out what we found */ - print_array(array,0); -#endif - -} - - |