diff options
Diffstat (limited to 'usr/src')
42 files changed, 2139 insertions, 1094 deletions
| diff --git a/usr/src/cmd/diskscan/diskscan.c b/usr/src/cmd/diskscan/diskscan.c index 4c311b37bf..0f9de773f4 100644 --- a/usr/src/cmd/diskscan/diskscan.c +++ b/usr/src/cmd/diskscan/diskscan.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -168,7 +168,7 @@ main(int argc, char *argv[]) {  static void  scandisk(char *device, int devfd, int writeflag)  { -	int	 trksiz = NBPSCTR * dkg.dkg_nsect; +	int	trksiz = 0;  	char	*verbuf;  	diskaddr_t cursec;  	int	 cylsiz =  dkg.dkg_nsect * dkg.dkg_nhead; @@ -176,6 +176,15 @@ scandisk(char *device, int devfd, int writeflag)  	char	*rptr;  	diskaddr_t tmpend = 0;  	diskaddr_t tmpsec = 0; +	struct dk_minfo	mediainfo; +	uint_t  sector_size; + +	if ((ioctl(devfd, DKIOCGMEDIAINFO, &mediainfo)) == 0) { +		sector_size = mediainfo.dki_lbsize; +	} else { +		sector_size = NBPSCTR; +	} +	trksiz =  sector_size * dkg.dkg_nsect;  /* #define LIBMALLOC */ @@ -187,23 +196,25 @@ scandisk(char *device, int devfd, int writeflag)  	/* make track buffer sector aligned */ -	if (mallopt(M_GRAIN, 0x200)) { +	if (mallopt(M_GRAIN, sector_size)) {  		perror("mallopt");  		exit(1);  	} -	if ((verbuf = malloc(NBPSCTR * dkg.dkg_nsect)) == (char *)NULL) { +	if ((verbuf = malloc(sector_size * dkg.dkg_nsect)) == +	    (char *)NULL) {  		perror("malloc");  		exit(1);  	}  #else -	if ((verbuf = malloc(0x200 + NBPSCTR * dkg.dkg_nsect)) +	if ((verbuf = malloc(sector_size + sector_size * dkg.dkg_nsect))  	    == (char *)NULL) {  		perror("malloc");  		exit(1);  	} -	verbuf = (char *)(((unsigned long)verbuf + 0x00000200) & 0xfffffe00); +	verbuf = (char *)((((unsigned long)verbuf + sector_size)) & +	    (-sector_size));  #endif @@ -238,7 +249,7 @@ scandisk(char *device, int devfd, int writeflag)  	}  	for (cursec = 0; cursec < unix_size; cursec +=  dkg.dkg_nsect) { -		if (llseek(devfd, cursec * NBPSCTR, 0) == -1) { +		if (llseek(devfd, cursec * sector_size, 0) == -1) {  			(void) fprintf(stderr,  			    "Error seeking sector %llu Cylinder %llu\n",  			    cursec, cursec / cylsiz); @@ -261,7 +272,8 @@ scandisk(char *device, int devfd, int writeflag)  				 *  then announce the sector bad on stderr  				 */ -				if (llseek(devfd, tmpsec * NBPSCTR, 0) == -1) { +				if (llseek(devfd, tmpsec * sector_size, +				    0) == -1) {  					(void) fprintf(stderr, "Error seeking "  					    "sector %llu Cylinder %llu\n",  					    tmpsec, cursec / cylsiz); @@ -270,7 +282,8 @@ scandisk(char *device, int devfd, int writeflag)  				report("Writing", tmpsec); -				if (write(devfd, verbuf, NBPSCTR) != NBPSCTR) { +				if (write(devfd, verbuf, sector_size) +				    != sector_size) {  					(void) fprintf(stderr,  					    "%llu\n", tmpsec + unix_base);  					numbadwr++; @@ -283,7 +296,7 @@ scandisk(char *device, int devfd, int writeflag)  	do_readonly:  	for (cursec = 0; cursec < unix_size; cursec +=  dkg.dkg_nsect) { -		if (llseek(devfd, cursec * NBPSCTR, 0) == -1) { +		if (llseek(devfd, cursec * sector_size, 0) == -1) {  			(void) fprintf(stderr,  			    "Error seeking sector %llu Cylinder %llu\n",  			    cursec, cursec / cylsiz); @@ -300,14 +313,16 @@ scandisk(char *device, int devfd, int writeflag)  		if (read(devfd, verbuf, trksiz) != trksiz) {  			tmpend = cursec +  dkg.dkg_nsect;  			for (tmpsec = cursec; tmpsec < tmpend; tmpsec++) { -				if (llseek(devfd, tmpsec * NBPSCTR, 0) == -1) { +				if (llseek(devfd, tmpsec * sector_size, +				    0) == -1) {  					(void) fprintf(stderr, "Error seeking"  					    " sector %llu Cylinder %llu\n",  					    tmpsec, cursec / cylsiz);  					verexit(1);  				}  				report("Reading", tmpsec); -				if (read(devfd, verbuf, NBPSCTR) != NBPSCTR) { +				if (read(devfd, verbuf, sector_size) != +				    sector_size) {  					(void) fprintf(stderr, "%llu\n",  					    tmpsec + unix_base);  					numbadrd++; diff --git a/usr/src/cmd/fdisk/fdisk.c b/usr/src/cmd/fdisk/fdisk.c index 6a0447bbcd..e20bea17ad 100644 --- a/usr/src/cmd/fdisk/fdisk.c +++ b/usr/src/cmd/fdisk/fdisk.c @@ -559,7 +559,7 @@ main(int argc, char *argv[])  	 * in that case leave the minfo structure zeroed  	 */  	if (ioctl(Dev, DKIOCGMEDIAINFO, &minfo)) { -		memset(&minfo, 0, sizeof (minfo)); +		(void) memset(&minfo, 0, sizeof (minfo));  	}  	/* Get the disk geometry */ @@ -628,7 +628,12 @@ main(int argc, char *argv[])  		Numcyl = disk_geom.dkg_ncyl;  		heads = disk_geom.dkg_nhead;  		sectors = disk_geom.dkg_nsect; -		sectsiz = 512; + +		if (minfo.dki_lbsize != 0) +			sectsiz = minfo.dki_lbsize; +		else +			sectsiz = 512; +  		acyl = disk_geom.dkg_acyl;  		/* @@ -690,7 +695,11 @@ main(int argc, char *argv[])  		Numcyl = disk_geom.dkg_ncyl;  		heads = disk_geom.dkg_nhead;  		sectors = disk_geom.dkg_nsect; -		sectsiz = 512; +		if (minfo.dki_lbsize != 0) +			sectsiz = minfo.dki_lbsize; +		else +			sectsiz = 512; +  		acyl = disk_geom.dkg_acyl;  		(void) printf("* Label geometry for device %s\n", Dfltdev);  		(void) printf( @@ -751,7 +760,7 @@ main(int argc, char *argv[])  		dev_capacity = minfo.dki_capacity;  	/* Allocate memory to hold three complete sectors */ -	Bootsect = (char *)malloc(3 * sectsiz); +	Bootsect = (char *)calloc(3 * sectsiz, 1);  	if (Bootsect == NULL) {  		(void) fprintf(stderr,  		    "fdisk: Unable to obtain enough buffer memory" @@ -2819,8 +2828,8 @@ disptbl(void)  	(void) printf(HOME);  	(void) printf(T_LINE);  	(void) printf("             Total disk size is %d cylinders\n", Numcyl); -	(void) printf("             Cylinder size is %d (512 byte) blocks\n\n", -	    heads * sectors); +	(void) printf("             Cylinder size is %d (%d byte) blocks\n\n", +	    heads * sectors, sectsiz);  	(void) printf(  	    "                                               Cylinders\n");  	(void) printf( @@ -3165,7 +3174,7 @@ getlong(char **bp)  /*   * copy_Table_to_Bootblk - * Copy the table into the 512 boot record. Note that the unused + * Copy the table into the boot record. Note that the unused   * entries will always be the last ones in the table and they are   * marked with 100 in sysind. The the unused portion of the table   * is padded with zeros in the bytes after the used entries. @@ -3638,7 +3647,8 @@ clear_efi(void)  	 */  	dk_ioc.dki_lba = efi_vtoc->efi_last_u_lba + 1;  	dk_ioc.dki_length -= efi_vtoc->efi_lbasize; -	dk_ioc.dki_data++; +	dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data + +	    efi_vtoc->efi_lbasize);  	if (io_debug) {  		(void) fprintf(stderr,  		    "\tClearing backup partition table at block %lld\n", @@ -3656,7 +3666,8 @@ clear_efi(void)  	 */  	dk_ioc.dki_lba = efi_vtoc->efi_last_lba;  	dk_ioc.dki_length = efi_vtoc->efi_lbasize; -	dk_ioc.dki_data--; +	dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data - +	    efi_vtoc->efi_lbasize);  	if (io_debug) {  		(void) fprintf(stderr, "\tClearing backup label at block "  		    "%lld\n", dk_ioc.dki_lba); @@ -3685,14 +3696,14 @@ static void  clear_vtoc(int table, int part)  {  	struct ipart *clr_table; -	struct dk_label disk_label; +	char *disk_label;  	uint32_t pcyl, ncyl, count;  	diskaddr_t backup_block, solaris_offset;  	ssize_t bytes;  	off_t seek_byte;  #ifdef DEBUG -	struct dk_label	read_label; +	char *read_label;  #endif /* DEBUG */  	if (table == OLD) { @@ -3701,7 +3712,10 @@ clear_vtoc(int table, int part)  		clr_table = &Table[part];  	} -	(void) memset(&disk_label, 0, sizeof (struct dk_label)); +	disk_label = (char *)calloc(sectsiz, 1); +	if (disk_label == NULL) { +		return; +	}  	seek_byte = (off_t)(lel(clr_table->relsect) + VTOC_OFFSET) * sectsiz; @@ -3716,12 +3730,13 @@ clear_vtoc(int table, int part)  		(void) fprintf(stderr,  		    "\tError seeking to primary label at byte %llu\n",  		    (uint64_t)seek_byte); +		free(disk_label);  		return;  	} -	bytes = write(Dev, &disk_label, sizeof (struct dk_label)); +	bytes = write(Dev, disk_label, sectsiz); -	if (bytes != sizeof (struct dk_label)) { +	if (bytes != sectsiz) {  		(void) fprintf(stderr,  		    "\tWarning: only %d bytes written to clear primary"  		    " VTOC!\n", bytes); @@ -3732,6 +3747,7 @@ clear_vtoc(int table, int part)  		(void) fprintf(stderr,  		    "DEBUG: Error seeking to primary label at byte %llu\n",  		    (uint64_t)seek_byte); +		free(disk_label);  		return;  	} else {  		(void) fprintf(stderr, @@ -3739,15 +3755,21 @@ clear_vtoc(int table, int part)  		    (uint64_t)seek_byte);  	} -	bytes = read(Dev, &read_label, sizeof (struct dk_label)); +	read_label = (char *)calloc(sectsiz, 1); +	if (read_label == NULL) { +		free(disk_label); +		return; +	} + +	bytes = read(Dev, read_label, sectsiz); -	if (bytes != sizeof (struct dk_label)) { +	if (bytes != sectsiz) {  		(void) fprintf(stderr,  		    "DEBUG: Warning: only %d bytes read of label\n",  		    bytes);  	} -	if (memcmp(&disk_label, &read_label, sizeof (struct dk_label)) != 0) { +	if (memcmp(disk_label, read_label, sectsiz) != 0) {  		(void) fprintf(stderr,  		    "DEBUG: Warning: disk_label and read_label differ!!!\n");  	} else { @@ -3765,12 +3787,16 @@ clear_vtoc(int table, int part)  	    (heads * sectors)) + ((heads - 1) * sectors) + 1;  	for (count = 1; count < 6; count++) { -		seek_byte = (off_t)(solaris_offset + backup_block) * 512; +		seek_byte = (off_t)(solaris_offset + backup_block) * sectsiz;  		if (lseek(Dev, seek_byte, SEEK_SET) == -1) {  			(void) fprintf(stderr,  			    "\tError seeking to backup label at byte %llu on "  			    "%s.\n", (uint64_t)seek_byte, Dfltdev); +			free(disk_label); +#ifdef DEBUG +			free(read_label); +#endif /* DEBUG */  			return;  		} @@ -3781,9 +3807,9 @@ clear_vtoc(int table, int part)  			    (uint64_t)(solaris_offset + backup_block));  		} -		bytes = write(Dev, &disk_label, sizeof (struct dk_label)); +		bytes = write(Dev, disk_label, sectsiz); -		if (bytes != sizeof (struct dk_label)) { +		if (bytes != sectsiz) {  			(void) fprintf(stderr,  			    "\t\tWarning: only %d bytes written to "  			    "clear backup VTOC at block %llu!\n", bytes, @@ -3795,6 +3821,8 @@ clear_vtoc(int table, int part)  		(void) fprintf(stderr,  		    "DEBUG: Error seeking to backup label at byte %llu\n",  		    (uint64_t)seek_byte); +		free(disk_label); +		free(read_label);  		return;  	} else {  		(void) fprintf(stderr, @@ -3802,15 +3830,15 @@ clear_vtoc(int table, int part)  		    (uint64_t)seek_byte);  	} -	bytes = read(Dev, &read_label, sizeof (struct dk_label)); +	bytes = read(Dev, read_label, sectsiz); -	if (bytes != sizeof (struct dk_label)) { +	if (bytes != sectsiz) {  		(void) fprintf(stderr,  		    "DEBUG: Warning: only %d bytes read of backup label\n",  		    bytes);  	} -	if (memcmp(&disk_label, &read_label, sizeof (struct dk_label)) != 0) { +	if (memcmp(disk_label, read_label, sectsiz) != 0) {  		(void) fprintf(stderr,  		    "DEBUG: Warning: disk_label and read_label differ!!!\n");  	} else { @@ -3818,10 +3846,16 @@ clear_vtoc(int table, int part)  		    "DEBUG: Good compare of disk_label and backup "  		    "read_label\n");  	} +  #endif /* DEBUG */  		backup_block += 2;  	} + +#ifdef DEBUG +	free(read_label); +#endif /* DEBUG */ +	free(disk_label);  }  #define	FDISK_STANDARD_LECTURE \ diff --git a/usr/src/cmd/fmthard/fmthard.c b/usr/src/cmd/fmthard/fmthard.c index 900bd8be6e..98faee8db3 100644 --- a/usr/src/cmd/fmthard/fmthard.c +++ b/usr/src/cmd/fmthard/fmthard.c @@ -29,7 +29,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -125,8 +125,8 @@ static char *uboot = "";  #endif	/* various platform-specific definitions */  static char	*ufirm = "firm"; -#if defined(_SUNOS_VTOC_16)  static int		sectsiz; +#if defined(_SUNOS_VTOC_16)  static struct extvtoc	disk_vtoc;  #endif	/* defined(_SUNOS_VTOC_16) */ @@ -143,6 +143,7 @@ main(int argc, char **argv)  #endif	/* defined(_SUNOS_VTOC_8) */  	struct dk_gpt	*disk_efi;  	struct dk_geom	disk_geom; +	struct dk_minfo	minfo;  	int		n; @@ -203,24 +204,32 @@ main(int argc, char **argv)  	if (stat(argv[optind], (struct stat *)&statbuf) == -1) {  		(void) fprintf(stderr, -			"fmthard:  Cannot stat device %s\n", -			argv[optind]); +		    "fmthard:  Cannot stat device %s\n", +		    argv[optind]);  		exit(1);  	}  	if ((statbuf.st_mode & S_IFMT) != S_IFCHR) {  		(void) fprintf(stderr, -			"fmthard:  %s must be a raw device.\n", -			argv[optind]); +		    "fmthard:  %s must be a raw device.\n", +		    argv[optind]);  		exit(1);  	}  	if ((fd = open(argv[optind], O_RDWR|O_NDELAY)) < 0) {  		(void) fprintf(stderr, "fmthard:  Cannot open device %s - %s\n", -			argv[optind], strerror(errno)); +		    argv[optind], strerror(errno));  		exit(1);  	} +	if (ioctl(fd, DKIOCGMEDIAINFO, &minfo) == 0) { +		sectsiz = minfo.dki_lbsize; +	} + +	if (sectsiz == 0) { +		sectsiz = SECSIZE; +	} +  	/*  	 * Get the geometry information for this disk from the driver  	 */ @@ -233,7 +242,7 @@ main(int argc, char **argv)  			eflag++;  		} else {  			(void) fprintf(stderr, -				"%s: Cannot get disk geometry\n", argv[optind]); +			    "%s: Cannot get disk geometry\n", argv[optind]);  			(void) close(fd);  			exit(1);  		} @@ -295,7 +304,7 @@ main(int argc, char **argv)  			FILE *fp;  			if ((fp = fopen(dfile, "r")) == NULL) {  				(void) fprintf(stderr, "Cannot open file %s\n", -					dfile); +				    dfile);  				(void) close(fd);  				exit(1);  			} @@ -307,7 +316,6 @@ main(int argc, char **argv)  		}  	} -  	/*  	 * Print the modified VTOC, rather than updating the disk  	 */ @@ -326,10 +334,10 @@ main(int argc, char **argv)  			(void) memcpy(disk_vtoc.v_volume, vname, n);  		} else {  			for (c = 0; c < disk_efi->efi_nparts; c++) { -			    if (disk_efi->efi_parts[c].p_tag == +				if (disk_efi->efi_parts[c].p_tag ==  				    V_RESERVED) {  				(void) memcpy(&disk_efi->efi_parts[c].p_name, -					    vname, n); +				    vname, n);  				}  			}  		} @@ -388,7 +396,7 @@ display(struct dk_geom *geom, struct extvtoc *vtoc, char *device)  	}  	(void) printf("*\n");  	(void) printf("* Dimensions:\n"); -	(void) printf("*     %d bytes/sector\n", SECSIZE); +	(void) printf("*     %d bytes/sector\n", sectsiz);  	(void) printf("*      %d sectors/track\n", geom->dkg_nsect);  	(void) printf("*       %d tracks/cylinder\n", geom->dkg_nhead);  	(void) printf("*     %d cylinders\n", geom->dkg_pcyl); @@ -404,10 +412,10 @@ display(struct dk_geom *geom, struct extvtoc *vtoc, char *device)  		if (vtoc->v_part[i].p_size > 0)  			(void) printf(  "    %d		%d	0%x		%llu		%llu\n", -				i, vtoc->v_part[i].p_tag, -				vtoc->v_part[i].p_flag, -				vtoc->v_part[i].p_start, -				vtoc->v_part[i].p_size); +			    i, vtoc->v_part[i].p_tag, +			    vtoc->v_part[i].p_flag, +			    vtoc->v_part[i].p_start, +			    vtoc->v_part[i].p_size);  	}  	exit(0);  } @@ -444,10 +452,10 @@ display64(struct dk_gpt *efi, char *device)  		if (efi->efi_parts[i].p_size > 0)  			(void) printf(  "    %d		%d	0%x		%8lld	%8lld\n", -				i, efi->efi_parts[i].p_tag, -				efi->efi_parts[i].p_flag, -				efi->efi_parts[i].p_start, -				efi->efi_parts[i].p_size); +			    i, efi->efi_parts[i].p_tag, +			    efi->efi_parts[i].p_flag, +			    efi->efi_parts[i].p_start, +			    efi->efi_parts[i].p_size);  	}  	exit(0);  } @@ -474,8 +482,8 @@ insert(char *data, struct extvtoc *vtoc)  	}  	if (part >= V_NUMPAR) {  		(void) fprintf(stderr, -			"Error in data \"%s\": No such partition %x\n", -			data, part); +		    "Error in data \"%s\": No such partition %x\n", +		    data, part);  		exit(1);  	}  	vtoc->v_part[part].p_tag = (ushort_t)tag; @@ -505,8 +513,8 @@ insert64(char *data, struct dk_gpt *efi)  	}  	if (part >= efi->efi_nparts) {  		(void) fprintf(stderr, -			"Error in data \"%s\": No such partition %x\n", -			data, part); +		    "Error in data \"%s\": No such partition %x\n", +		    data, part);  		exit(1);  	}  	efi->efi_parts[part].p_tag = (ushort_t)tag; @@ -558,19 +566,19 @@ load(FILE *fp, struct dk_geom *geom, struct extvtoc *vtoc)  		if (sscanf(line, "%d %d %x %llu %llu",  		    &part, &tag, &flag, &start, &size) != 5) {  			(void) fprintf(stderr, "Syntax error: \"%s\"\n", -				line); +			    line);  			exit(1);  		}  		if (part >= V_NUMPAR) {  			(void) fprintf(stderr, -				"No such partition %x: \"%s\"\n", -				part, line); +			    "No such partition %x: \"%s\"\n", +			    part, line);  			exit(1);  		}  		if (!eflag && ((start % nblks) != 0 || (size % nblks) != 0)) {  			(void) fprintf(stderr,  "Partition %d not aligned on cylinder boundary: \"%s\"\n", -					part, line); +			    part, line);  			exit(1);  		}  		vtoc->v_part[part].p_tag = (ushort_t)tag; @@ -609,7 +617,7 @@ load64(FILE *fp, int fd, struct dk_gpt **efi)  		if (sscanf(line, "%d %d %x %lld %lld",  		    &part, &tag, &flag, &start, &size) != 5) {  			(void) fprintf(stderr, "Syntax error: \"%s\"\n", -				line); +			    line);  			exit(1);  		}  		mem = realloc(mem, sizeof (*mem) * (nlines + 1)); @@ -624,13 +632,13 @@ load64(FILE *fp, int fd, struct dk_gpt **efi)  		}  		nlines++;  		if (part > max_part) -		    max_part = part; +			max_part = part;  	}  	max_part++;  	if ((i = efi_alloc_and_init(fd, max_part, efi)) < 0) {  		(void) fprintf(stderr, -				"efi_alloc_and_init failed: %d\n", i); +		    "efi_alloc_and_init failed: %d\n", i);  		exit(1);  	}  	for (i = 0; i < (*efi)->efi_nparts; ++i) { @@ -645,14 +653,14 @@ load64(FILE *fp, int fd, struct dk_gpt **efi)  		if (sscanf(mem[i], "%d %d %x %lld %lld",  		    &part, &tag, &flag, &start, &size) != 5) {  			(void) fprintf(stderr, "Syntax error: \"%s\"\n", -				line); +			    line);  			exit(1);  		}  		free(mem[i]);  		if (part >= (*efi)->efi_nparts) {  			(void) fprintf(stderr, -				"No such partition %x: \"%s\"\n", -				part, line); +			    "No such partition %x: \"%s\"\n", +			    part, line);  			exit(1);  		}  		(*efi)->efi_parts[part].p_tag = (ushort_t)tag; @@ -668,12 +676,13 @@ load64(FILE *fp, int fd, struct dk_gpt **efi)  static void  usage()  { -	(void) fprintf(stderr,  #if defined(sparc) +	(void) fprintf(stderr,  "Usage:	fmthard [ -i ] [ -n volumename ] [ -s datafile ] [ -d arguments] \  raw-device\n");  #elif defined(i386) +	(void) fprintf(stderr,  "Usage:	fmthard [ -i ] [ -S ] [-I geom_file]  \  -n volumename | -s datafile  [ -d arguments] raw-device\n"); @@ -710,8 +719,6 @@ validate(struct dk_geom *geom, struct extvtoc *vtoc)  	vtoc->v_version = V_VERSION;  	vtoc->v_sanity = VTOC_SANE;  	vtoc->v_nparts = V_NUMPAR; -	if (sectsiz == 0) -		sectsiz = SECSIZE;  	if (vtoc->v_sectorsz == 0)  		vtoc->v_sectorsz = sectsiz;  #endif				/* defined(_SUNOS_VTOC_16) */ @@ -730,19 +737,19 @@ full size of disk.  The full disk capacity is %llu sectors.\n", i, fullsz);  		if (vtoc->v_part[i].p_size == 0)  			continue;	/* Undefined partition */  		if ((vtoc->v_part[i].p_start % nblks) || -				(vtoc->v_part[i].p_size % nblks)) { +		    (vtoc->v_part[i].p_size % nblks)) {  			(void) fprintf(stderr, "\  fmthard: Partition %d not aligned on cylinder boundary \n", i);  				exit(1);  		}  		if (vtoc->v_part[i].p_start > fullsz || -			vtoc->v_part[i].p_start + -				vtoc->v_part[i].p_size > fullsz) { +		    vtoc->v_part[i].p_start + +		    vtoc->v_part[i].p_size > fullsz) {  			(void) fprintf(stderr, "\  fmthard: Partition %d specified as %llu sectors starting at %llu\n\  \tdoes not fit. The full disk contains %llu sectors.\n", -				i, vtoc->v_part[i].p_size, -				vtoc->v_part[i].p_start, fullsz); +			    i, vtoc->v_part[i].p_size, +			    vtoc->v_part[i].p_start, fullsz);  #if defined(sparc)  			exit(1);  #endif @@ -763,7 +770,7 @@ fmthard: Partition %d specified as %llu sectors starting at %llu\n\  				    (isize != 0) && (jsize != 0)) {  					endsect = jstart + jsize -1;  					if ((jstart <= istart) && -						(istart <= endsect)) { +					    (istart <= endsect)) {  						(void) fprintf(stderr, "\  fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\  \tonly on partition on the full disk partition).\n", @@ -804,13 +811,13 @@ validate64(struct dk_gpt *efi)  		if (efi->efi_parts[i].p_tag == V_RESERVED)  			resv_part++;  		if (efi->efi_parts[i].p_start > fullsz || -			efi->efi_parts[i].p_start + -				efi->efi_parts[i].p_size > fullsz) { +		    efi->efi_parts[i].p_start + +		    efi->efi_parts[i].p_size > fullsz) {  			(void) fprintf(stderr, "\  fmthard: Partition %d specified as %lld sectors starting at %lld\n\  \tdoes not fit. The full disk contains %lld sectors.\n", -				i, efi->efi_parts[i].p_size, -				efi->efi_parts[i].p_start, fullsz); +			    i, efi->efi_parts[i].p_size, +			    efi->efi_parts[i].p_start, fullsz);  			exit(1);  		} @@ -827,7 +834,7 @@ fmthard: Partition %d specified as %lld sectors starting at %lld\n\  				    (isize != 0) && (jsize != 0)) {  					endsect = jstart + jsize - 1;  					if ((jstart <= istart) && -						(istart <= endsect)) { +					    (istart <= endsect)) {  						(void) fprintf(stderr, "\  fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\  \tonly on partition on the full disk partition).\n", @@ -863,10 +870,10 @@ vread(int fd, struct extvtoc *vtoc, char *devname)  		}  		if (i == VT_EINVAL) {  			(void) fprintf(stderr, "%s: Invalid VTOC\n", -				devname); +			    devname);  		} else {  			(void) fprintf(stderr, "%s: Cannot read VTOC\n", -				devname); +			    devname);  		}  		exit(1);  	} @@ -881,12 +888,12 @@ vread64(int fd, struct dk_gpt **efi_hdr, char *devname)  	if ((i = efi_alloc_and_read(fd, efi_hdr)) < 0) {  		if (i == VT_EINVAL)  			(void) fprintf(stderr, -				"%s: this disk must be labeled first\n", -				devname); +			    "%s: this disk must be labeled first\n", +			    devname);  		else  			(void) fprintf(stderr, -				"%s: read_efi failed %d\n", -				devname, i); +			    "%s: read_efi failed %d\n", +			    devname, i);  		exit(1);  	}  	lastlba = (*efi_hdr)->efi_last_u_lba; @@ -904,10 +911,10 @@ vwrite(int fd, struct extvtoc *vtoc, char *devname)  		if (i == VT_EINVAL) {  			(void) fprintf(stderr,  			"%s: invalid entry exists in vtoc\n", -				devname); +			    devname);  		} else {  			(void) fprintf(stderr, "%s: Cannot write VTOC\n", -				devname); +			    devname);  		}  		exit(1);  	} @@ -925,10 +932,10 @@ vwrite64(int fd, struct dk_gpt *efi, char *devname)  		if (i == VT_EINVAL) {  			(void) fprintf(stderr,  			"%s: invalid entry exists in vtoc\n", -				devname); +			    devname);  		} else {  			(void) fprintf(stderr, "%s: Cannot write EFI\n", -				devname); +			    devname);  		}  		exit(1);  	} diff --git a/usr/src/cmd/format/analyze.c b/usr/src/cmd/format/analyze.c index 8d8404b280..64417130d2 100644 --- a/usr/src/cmd/format/analyze.c +++ b/usr/src/cmd/format/analyze.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -461,7 +461,7 @@ scan_repair(bn, mode)  {  	int	status;  	int	result = 1; -	char	buf[SECSIZE]; +	char	*buf;  	int	buf_is_good;  	int	i; @@ -471,6 +471,11 @@ scan_repair(bn, mode)  		return (result);  	} +	buf = malloc(cur_blksz); +	if (buf == NULL) { +		err_print("Warning: no memory.\n\n"); +		return (result); +	}  	enter_critical();  	/* @@ -509,7 +514,7 @@ scan_repair(bn, mode)  		 * determine if the new block appears ok.  		 */  		if (!buf_is_good) { -			bzero(buf, SECSIZE); +			bzero(buf, cur_blksz);  			fmt_print("Warning: Block %llu zero-filled.\n", bn);  		} else {  			fmt_print("ok.\n"); @@ -565,7 +570,7 @@ scan_repair(bn, mode)  	}  	exit_critical(); - +	free(buf);  	return (result);  } @@ -596,7 +601,7 @@ analyze_blocks(flags, blkno, blkcnt, data, init, driver_flags, xfercntp)  	/*  	 * Initialize the pattern buffer if necessary.  	 */ -	nints = (diskaddr_t)blkcnt * SECSIZE / sizeof (int); +	nints = (diskaddr_t)blkcnt * cur_blksz / sizeof (int);  	if ((flags & SCAN_PATTERN) && init) {  		for (i = 0; i < nints; i++)  			*((int *)((int *)pattern_buf + i)) = data; @@ -724,7 +729,7 @@ verify_blocks(int flags,  	int		status, i, nints;  	unsigned	*ptr = (uint_t *)pattern_buf; -	nints = SECSIZE / sizeof (int); +	nints = cur_blksz / sizeof (int);  	/*  	 * Initialize the pattern buffer if we are in write pass. diff --git a/usr/src/cmd/format/auto_sense.c b/usr/src/cmd/format/auto_sense.c index 094c6c2c1d..57d44562a6 100644 --- a/usr/src/cmd/format/auto_sense.c +++ b/usr/src/cmd/format/auto_sense.c @@ -223,8 +223,6 @@ static char		*get_sun_disk_name(  static char		*get_generic_disk_name(  				char		*disk_name,  				struct scsi_inquiry *inquiry); -static int		force_blocksize(int fd); -static int		raw_format(int fd);  static char		*strcopy(  				char	*dst,  				char	*src, @@ -308,10 +306,10 @@ auto_efi_sense(int fd, struct efi_info *label)  	 */  	if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { -	    if (option_msg && diag_msg) { -		err_print("DKIOCINFO failed\n"); -	    } -	    return (NULL); +		if (option_msg && diag_msg) { +			err_print("DKIOCINFO failed\n"); +		} +		return (NULL);  	}  	if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) {  		ctlr = find_direct_ctlr_info(&dkinfo); @@ -337,11 +335,11 @@ auto_efi_sense(int fd, struct efi_info *label)  	disk->dtype_next = NULL;  	(void) strlcpy(disk->vendor, label->vendor, -		    sizeof (disk->vendor)); +	    sizeof (disk->vendor));  	(void) strlcpy(disk->product, label->product, -		    sizeof (disk->product)); +	    sizeof (disk->product));  	(void) strlcpy(disk->revision, label->revision, -		    sizeof (disk->revision)); +	    sizeof (disk->revision));  	disk->capacity = label->capacity;  	part = (struct partition_info *) @@ -554,11 +552,6 @@ auto_label_init(struct dk_label *label)  		disk_info.dki_lbsize = DEV_BSIZE;  	} -	if (disk_info.dki_lbsize != DEV_BSIZE) { -		err_print("auto_label_init: lbasize is not 512\n"); -		goto auto_label_init_out; -	} -  	dk_ioc_back.dki_data = databack;  	/* @@ -584,7 +577,7 @@ auto_label_init(struct dk_label *label)  		goto auto_label_init_out;  	} -	backsigp = (efi_gpt_t *)((uintptr_t)dk_ioc_back.dki_data + DEV_BSIZE); +	backsigp = (efi_gpt_t *)((uintptr_t)dk_ioc_back.dki_data + cur_blksz);  	backsig = backsigp->efi_gpt_Signature; @@ -736,7 +729,7 @@ new_direct_disk_type(  	disk->dtype_rpm = label->dkl_rpm;  	part = (struct partition_info *) -		zalloc(sizeof (struct partition_info)); +	    zalloc(sizeof (struct partition_info));  	pt = disk->dtype_plist;  	if (pt == NULL) {  		disk->dtype_plist = part; @@ -764,11 +757,11 @@ new_direct_disk_type(  #elif defined(_SUNOS_VTOC_16)  		part->pinfo_map[i].dkl_cylno = -			label->dkl_vtoc.v_part[i].p_start / -			    ((blkaddr_t)(disk->dtype_nhead * -			    disk->dtype_nsect - apc)); +		    label->dkl_vtoc.v_part[i].p_start / +		    ((blkaddr_t)(disk->dtype_nhead * +		    disk->dtype_nsect - apc));  		part->pinfo_map[i].dkl_nblk = -			label->dkl_vtoc.v_part[i].p_size; +		    label->dkl_vtoc.v_part[i].p_size;  #else  #error No VTOC format defined.  #endif				/* defined(_SUNOS_VTOC_8) */ @@ -779,7 +772,7 @@ new_direct_disk_type(  	 */  	if (label->dkl_vtoc.v_version == V_VERSION) {  		(void) memcpy(disk_info->v_volume, label->dkl_vtoc.v_volume, -			LEN_DKL_VVOL); +		    LEN_DKL_VVOL);  		part->vtoc = label->dkl_vtoc;  	} else {  		(void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL); @@ -845,10 +838,10 @@ auto_sense(  		deflt = 1;  		ioparam.io_charlist = confirm_list;  		if (input(FIO_MSTR, FORMAT_MSG, '?', &ioparam, -				&deflt, DATA_INPUT) == 0) { +		    &deflt, DATA_INPUT) == 0) {  			force_format_dat = 1;  		} else if (input(FIO_MSTR, GENERIC_MSG, '?', &ioparam, -				&deflt, DATA_INPUT) == 0) { +		    &deflt, DATA_INPUT) == 0) {  			force_generic = 1;  		}  	} @@ -890,7 +883,7 @@ auto_sense(  	}  	if (option_msg && diag_msg) {  		err_print("blocks:  %llu (0x%llx)\n", -			capacity.sc_capacity, capacity.sc_capacity); +		    capacity.sc_capacity, capacity.sc_capacity);  		err_print("blksize: %u\n", capacity.sc_lbasize);  	} @@ -910,7 +903,7 @@ auto_sense(  	if (force_generic) {  		return (generic_disk_sense(fd, can_prompt, label, -			&inquiry, &capacity, disk_name)); +		    &inquiry, &capacity, disk_name));  	}  	/* @@ -918,7 +911,7 @@ auto_sense(  	 */  	if ((disk_type = find_scsi_disk_by_name(disk_name)) != NULL) {  		if (use_existing_disk_type(fd, can_prompt, label, -				&inquiry, disk_type, &capacity)) { +		    &inquiry, disk_type, &capacity)) {  			return (disk_type);  		}  		if (force_format_dat) { @@ -931,7 +924,7 @@ auto_sense(  	 */  	return (generic_disk_sense(fd, can_prompt, label, -			&inquiry, &capacity, disk_name)); +	    &inquiry, &capacity, disk_name));  } @@ -964,7 +957,6 @@ generic_disk_sense(  		struct mode_geometry	page4;  		uchar_t			buf4[MAX_MODE_SENSE_SIZE];  	} u_page4; -	struct scsi_capacity_16		new_capacity;  	struct mode_format		*page3 = &u_page3.page3;  	struct mode_geometry		*page4 = &u_page4.page4;  	struct scsi_ms_header		header; @@ -982,38 +974,6 @@ generic_disk_sense(  	}  	/* -	 * If the device's block size is not 512, we have to -	 * change block size, reformat, and then sense the -	 * geometry.  To do this, we must be able to prompt -	 * the user. -	 */ -	if (capacity->sc_lbasize != DEV_BSIZE) { -		if (!can_prompt) { -			return (NULL); -		} -		if (force_blocksize(fd)) { -			goto err; -		} - -		/* -		 * Get the capacity again, since this has changed -		 */ -		if (uscsi_read_capacity(fd, &new_capacity)) { -			goto err; -		} -		if (option_msg && diag_msg) { -			err_print("blocks:  %llu (0x%llx)\n", -				new_capacity.sc_capacity, -				    new_capacity.sc_capacity); -			err_print("blksize: %u\n", new_capacity.sc_lbasize); -		} -		capacity = &new_capacity; -		if (capacity->sc_lbasize != DEV_BSIZE) { -			goto err; -		} -	} - -	/*  	 * Get the number of blocks from Read Capacity data. Note that  	 * the logical block address range from 0 to capacity->sc_capacity.  	 * Limit the size to 2 TB (UINT32_MAX) to use with SMI labels. @@ -1028,7 +988,7 @@ generic_disk_sense(  	 * Get current Page 3 - Format Parameters page  	 */  	if (uscsi_mode_sense(fd, DAD_MODE_FORMAT, MODE_SENSE_PC_CURRENT, -			(caddr_t)&u_page3, MAX_MODE_SENSE_SIZE, &header)) { +	    (caddr_t)&u_page3, MAX_MODE_SENSE_SIZE, &header)) {  		setdefault = 1;  	} @@ -1036,7 +996,7 @@ generic_disk_sense(  	 * Get current Page 4 - Drive Geometry page  	 */  	if (uscsi_mode_sense(fd, DAD_MODE_GEOMETRY, MODE_SENSE_PC_CURRENT, -			(caddr_t)&u_page4, MAX_MODE_SENSE_SIZE, &header)) { +	    (caddr_t)&u_page4, MAX_MODE_SENSE_SIZE, &header)) {  		setdefault = 1;  	} @@ -1071,7 +1031,7 @@ generic_disk_sense(  			    &nsect);  		} else {  			pcyl = (page4->cyl_ub << 16) + (page4->cyl_mb << 8) + -				page4->cyl_lb; +			    page4->cyl_lb;  			nhead = page4->heads;  			nsect = page3->sect_track;  		} @@ -1094,7 +1054,12 @@ generic_disk_sense(  		}  	} -	if (setdefault == 1) { +	/* +	 * Mode sense page 3 and page 4 are obsolete in SCSI-3. For +	 * newly developed large sector size disk, we will not rely on +	 * those two pages but compute geometry directly. +	 */ +	if ((setdefault == 1) || (capacity->sc_lbasize != DEV_BSIZE)) {  		/*  		 * If the number of cylinders or the number of heads reported  		 * is zero, we think the inquiry of page 3 and page 4 failed. @@ -1223,7 +1188,7 @@ generic_disk_sense(  				    p, nhead, n);  				if (input(FIO_INT, "Select one of the above "  				    "choices ", ':', &ioparam, -					&deflt, DATA_INPUT) == 2) { +				    &deflt, DATA_INPUT) == 2) {  					pcyl = p;  					nsect = n;  				} @@ -1239,16 +1204,16 @@ generic_disk_sense(  	 */  	if ((pcyl > MAXIMUM_NO_CYLINDERS && -		((nsect > MAXIMUM_NO_SECTORS) || -		(nhead > MAXIMUM_NO_HEADS))) || -		((nsect > MAXIMUM_NO_SECTORS) && -		(nhead > MAXIMUM_NO_HEADS))) { +	    ((nsect > MAXIMUM_NO_SECTORS) || +	    (nhead > MAXIMUM_NO_HEADS))) || +	    ((nsect > MAXIMUM_NO_SECTORS) && +	    (nhead > MAXIMUM_NO_HEADS))) {  		err_print("This disk is too big to label. " -			" You will lose some blocks.\n"); +		    " You will lose some blocks.\n");  	}  	if ((pcyl > MAXIMUM_NO_CYLINDERS) || -		(nsect > MAXIMUM_NO_SECTORS) || -		(nhead > MAXIMUM_NO_HEADS)) { +	    (nsect > MAXIMUM_NO_SECTORS) || +	    (nhead > MAXIMUM_NO_HEADS)) {  		u_ioparam_t	ioparam;  		int		order;  		char		msg[256]; @@ -1259,45 +1224,45 @@ generic_disk_sense(  		switch (order) {  		case 0x7: /* pcyl > nhead > nsect */  			nblocks = -				square_box(nblocks, -					&pcyl, MAXIMUM_NO_CYLINDERS, -					&nhead, MAXIMUM_NO_HEADS, -					&nsect, MAXIMUM_NO_SECTORS); +			    square_box(nblocks, +			    &pcyl, MAXIMUM_NO_CYLINDERS, +			    &nhead, MAXIMUM_NO_HEADS, +			    &nsect, MAXIMUM_NO_SECTORS);  			break;  		case 0x6: /* pcyl > nsect > nhead */  			nblocks = -				square_box(nblocks, -					&pcyl, MAXIMUM_NO_CYLINDERS, -					&nsect, MAXIMUM_NO_SECTORS, -					&nhead, MAXIMUM_NO_HEADS); +			    square_box(nblocks, +			    &pcyl, MAXIMUM_NO_CYLINDERS, +			    &nsect, MAXIMUM_NO_SECTORS, +			    &nhead, MAXIMUM_NO_HEADS);  			break;  		case 0x4: /* nsect > pcyl > nhead */  			nblocks = -				square_box(nblocks, -					&nsect, MAXIMUM_NO_SECTORS, -					&pcyl, MAXIMUM_NO_CYLINDERS, -					&nhead, MAXIMUM_NO_HEADS); +			    square_box(nblocks, +			    &nsect, MAXIMUM_NO_SECTORS, +			    &pcyl, MAXIMUM_NO_CYLINDERS, +			    &nhead, MAXIMUM_NO_HEADS);  			break;  		case 0x0: /* nsect > nhead > pcyl */  			nblocks = -				square_box(nblocks, -					&nsect, MAXIMUM_NO_SECTORS, -					&nhead, MAXIMUM_NO_HEADS, -					&pcyl, MAXIMUM_NO_CYLINDERS); +			    square_box(nblocks, +			    &nsect, MAXIMUM_NO_SECTORS, +			    &nhead, MAXIMUM_NO_HEADS, +			    &pcyl, MAXIMUM_NO_CYLINDERS);  			break;  		case 0x3: /* nhead > pcyl > nsect */  			nblocks = -				square_box(nblocks, -					&nhead, MAXIMUM_NO_HEADS, -					&pcyl, MAXIMUM_NO_CYLINDERS, -					&nsect, MAXIMUM_NO_SECTORS); +			    square_box(nblocks, +			    &nhead, MAXIMUM_NO_HEADS, +			    &pcyl, MAXIMUM_NO_CYLINDERS, +			    &nsect, MAXIMUM_NO_SECTORS);  			break;  		case 0x1: /* nhead > nsect > pcyl */  			nblocks = -				square_box(nblocks, -					&nhead, MAXIMUM_NO_HEADS, -					&nsect, MAXIMUM_NO_SECTORS, -					&pcyl, MAXIMUM_NO_CYLINDERS); +			    square_box(nblocks, +			    &nhead, MAXIMUM_NO_HEADS, +			    &nsect, MAXIMUM_NO_SECTORS, +			    &pcyl, MAXIMUM_NO_CYLINDERS);  			break;  		default:  			/* How did we get here? */ @@ -1305,10 +1270,10 @@ generic_disk_sense(  			/* Do something useful */  			nblocks = -				square_box(nblocks, -					&nhead, MAXIMUM_NO_HEADS, -					&nsect, MAXIMUM_NO_SECTORS, -					&pcyl, MAXIMUM_NO_CYLINDERS); +			    square_box(nblocks, +			    &nhead, MAXIMUM_NO_HEADS, +			    &nsect, MAXIMUM_NO_SECTORS, +			    &pcyl, MAXIMUM_NO_CYLINDERS);  			break;  		}  		if (option_msg && diag_msg && @@ -1333,7 +1298,7 @@ generic_disk_sense(  			ioparam.io_charlist = confirm_list;  			if (input(FIO_MSTR, msg, '?', &ioparam, -				&deflt, DATA_INPUT) != 0) +			    &deflt, DATA_INPUT) != 0)  				break;  			ioparam.io_bounds.lower = MINIMUM_NO_HEADS; @@ -1417,7 +1382,7 @@ generic_disk_sense(  			char	old_name[DISK_NAME_MAX];  			(void) strcpy(old_name, disk_name);  			(void) get_generic_disk_name(disk_name, -				inquiry); +			    inquiry);  			if (option_msg && diag_msg) {  				err_print(  "Changing disk type name from '%s' to '%s'\n", old_name, disk_name); @@ -1457,7 +1422,6 @@ use_existing_disk_type(  	struct disk_type	*disk_type,  	struct scsi_capacity_16	*capacity)  { -	struct scsi_capacity_16	new_capacity;  	int			pcyl;  	int			acyl;  	int			nhead; @@ -1465,40 +1429,6 @@ use_existing_disk_type(  	int			rpm;  	/* -	 * If the device's block size is not 512, we have to -	 * change block size, reformat, and then sense the -	 * geometry.  To do this, we must be able to prompt -	 * the user. -	 */ -	if (capacity->sc_lbasize != DEV_BSIZE) { -		if (!can_prompt) { -			return (0); -		} -		if (force_blocksize(fd)) { -			goto err; -		} - -		/* -		 * Get the capacity again, since this has changed -		 */ -		if (uscsi_read_capacity(fd, &new_capacity)) { -			goto err; -		} - -		if (option_msg && diag_msg) { -			err_print("blocks:  %llu (0x%llx)\n", -			    new_capacity.sc_capacity, -			    new_capacity.sc_capacity); -			err_print("blksize: %u\n", new_capacity.sc_lbasize); -		} - -		capacity = &new_capacity; -		if (capacity->sc_lbasize != DEV_BSIZE) { -			goto err; -		} -	} - -	/*  	 * Construct a new label out of the format.dat  	 */  	pcyl = disk_type->dtype_pcyl; @@ -1545,7 +1475,7 @@ use_existing_disk_type(  err:  	if (option_msg && diag_msg) {  		err_print( -			"Configuration via format.dat geometry failed\n"); +		    "Configuration via format.dat geometry failed\n");  	}  	return (0);  } @@ -1589,11 +1519,11 @@ build_default_partition(  	 * is in integral number of megabytes.  	 */  	capacity = ((diskaddr_t)(label->dkl_ncyl) * label->dkl_nhead * -	    label->dkl_nsect) / (1024 * 1024) / DEV_BSIZE; +	    label->dkl_nsect) / (1024 * 1024) / cur_blksz;  	dpt = default_partitions;  	for (i = 0; i < DEFAULT_PARTITION_TABLE_SIZE; i++, dpt++) {  		if (capacity >= dpt->min_capacity && -				capacity < dpt->max_capacity) { +		    capacity < dpt->max_capacity) {  			break;  		}  	} @@ -1623,7 +1553,7 @@ build_default_partition(  			 * cylinders.  Always give what they  			 * asked or more, never less.  			 */ -			nblks = pt->partitions[i] * ((1024*1024)/DEV_BSIZE); +			nblks = pt->partitions[i] * ((1024*1024)/cur_blksz);  			nblks += (blks_per_cyl - 1);  			ncyls[i] = nblks / blks_per_cyl;  			freecyls -= ncyls[i]; @@ -1639,7 +1569,7 @@ build_default_partition(  				    i, ncyls[i]);  			}  			err_print("Free cylinders exhausted (%d)\n", -				freecyls); +			    freecyls);  		}  		return (0);  	} @@ -1733,13 +1663,13 @@ build_default_partition(  #if defined(_SUNOS_VTOC_8)  	label->dkl_map[2].dkl_cylno = 0;  	label->dkl_map[2].dkl_nblk = -		label->dkl_ncyl * label->dkl_nhead * label->dkl_nsect; +	    label->dkl_ncyl * label->dkl_nhead * label->dkl_nsect;  #elif defined(_SUNOS_VTOC_16)  	label->dkl_vtoc.v_part[2].p_start = 0;  	label->dkl_vtoc.v_part[2].p_size = -		(label->dkl_ncyl + label->dkl_acyl) * label->dkl_nhead * -			label->dkl_nsect; +	    (label->dkl_ncyl + label->dkl_acyl) * label->dkl_nhead * +	    label->dkl_nsect;  #else  #error No VTOC format defined.  #endif				/* defined(_SUNOS_VTOC_8) */ @@ -1776,13 +1706,12 @@ build_default_partition(  			} else {  				err_print("%6.2fMB  ", scaled);  			} -			err_print(" %6d cylinders\n",  #if defined(_SUNOS_VTOC_8) +			err_print(" %6d cylinders\n",  			    label->dkl_map[i].dkl_nblk/blks_per_cyl); -  #elif defined(_SUNOS_VTOC_16) +			err_print(" %6d cylinders\n",  			    label->dkl_vtoc.v_part[i].p_size/blks_per_cyl); -  #else  #error No VTOC format defined.  #endif				/* defined(_SUNOS_VTOC_8) */ @@ -1810,16 +1739,16 @@ find_scsi_disk_type(  	ctlr = find_scsi_ctlr_type();  	for (dp = ctlr->ctype_dlist; dp != NULL; dp = dp->dtype_next) { -	    if (dp->dtype_asciilabel) { -		if ((strcmp(dp->dtype_asciilabel, disk_name) == 0) && -				dp->dtype_pcyl == label->dkl_pcyl && -				dp->dtype_ncyl == label->dkl_ncyl && -				dp->dtype_acyl == label->dkl_acyl && -				dp->dtype_nhead == label->dkl_nhead && -				dp->dtype_nsect == label->dkl_nsect) { -			return (dp); +		if (dp->dtype_asciilabel) { +			if ((strcmp(dp->dtype_asciilabel, disk_name) == 0) && +			    dp->dtype_pcyl == label->dkl_pcyl && +			    dp->dtype_ncyl == label->dkl_ncyl && +			    dp->dtype_acyl == label->dkl_acyl && +			    dp->dtype_nhead == label->dkl_nhead && +			    dp->dtype_nsect == label->dkl_nsect) { +				return (dp); +			}  		} -	    }  	}  	return ((struct disk_type *)NULL); @@ -1839,11 +1768,11 @@ find_scsi_disk_by_name(  	ctlr = find_scsi_ctlr_type();  	for (dp = ctlr->ctype_dlist; dp != NULL; dp = dp->dtype_next) { -	    if (dp->dtype_asciilabel) { -		if ((strcmp(dp->dtype_asciilabel, disk_name) == 0)) { -			return (dp); +		if (dp->dtype_asciilabel) { +			if ((strcmp(dp->dtype_asciilabel, disk_name) == 0)) { +				return (dp); +			}  		} -	    }  	}  	return ((struct disk_type *)NULL); @@ -1997,7 +1926,7 @@ new_scsi_disk_type(  	 */  	if (part == NULL) {  		part = (struct partition_info *) -			zalloc(sizeof (struct partition_info)); +		    zalloc(sizeof (struct partition_info));  		pt = disk->dtype_plist;  		if (pt == NULL) {  			disk->dtype_plist = part; @@ -2024,11 +1953,11 @@ new_scsi_disk_type(  #elif defined(_SUNOS_VTOC_16)  			part->pinfo_map[i].dkl_cylno = -				label->dkl_vtoc.v_part[i].p_start / -				    ((blkaddr32_t)(disk->dtype_nhead * -				    disk->dtype_nsect - apc)); +			    label->dkl_vtoc.v_part[i].p_start / +			    ((blkaddr32_t)(disk->dtype_nhead * +			    disk->dtype_nsect - apc));  			part->pinfo_map[i].dkl_nblk = -				label->dkl_vtoc.v_part[i].p_size; +			    label->dkl_vtoc.v_part[i].p_size;  #else  #error No VTOC format defined.  #endif				/* defined(_SUNOS_VTOC_8) */ @@ -2042,7 +1971,7 @@ new_scsi_disk_type(  	 */  	if (label->dkl_vtoc.v_version == V_VERSION) {  		(void) memcpy(disk_info->v_volume, label->dkl_vtoc.v_volume, -			LEN_DKL_VVOL); +		    LEN_DKL_VVOL);  		part->vtoc = label->dkl_vtoc;  	} else {  		(void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL); @@ -2151,112 +2080,16 @@ get_generic_disk_name(  	(void) memset(disk_name, 0, DISK_NAME_MAX);  	p = strcopy(disk_name, inquiry->inq_vid, -		sizeof (inquiry->inq_vid)); +	    sizeof (inquiry->inq_vid));  	*p++ = '-';  	p = strcopy(p, inquiry->inq_pid, sizeof (inquiry->inq_pid));  	*p++ = '-';  	p = strcopy(p, inquiry->inq_revision, -		sizeof (inquiry->inq_revision)); +	    sizeof (inquiry->inq_revision));  	return (disk_name);  } - - -static int -force_blocksize( -	int	fd) -{ -	union { -		struct mode_format	page3; -		uchar_t			buf3[MAX_MODE_SENSE_SIZE]; -	} u_page3; -	struct mode_format		*page3 = &u_page3.page3; -	struct scsi_ms_header		header; - -	if (check("\ -Must reformat device to 512-byte blocksize.  Continue") == 0) { - -		/* -		 * Get current Page 3 - Format Parameters page -		 */ -		if (uscsi_mode_sense(fd, DAD_MODE_FORMAT, -			MODE_SENSE_PC_CURRENT, (caddr_t)&u_page3, -			MAX_MODE_SENSE_SIZE, &header)) { -			goto err; -		} - -		/* -		 * Make our changes to the geometry -		 */ -		header.mode_header.length = 0; -		header.mode_header.device_specific = 0; -		page3->mode_page.ps = 0; -		page3->data_bytes_sect = DEV_BSIZE; - -		/* -		 * make sure that logical block size is of -		 * DEV_BSIZE. -		 */ -		header.block_descriptor.blksize_hi = (DEV_BSIZE >> 16); -		header.block_descriptor.blksize_mid = (DEV_BSIZE >> 8); -		header.block_descriptor.blksize_lo = (char)(DEV_BSIZE); -		/* -		 * Select current Page 3 - Format Parameters page -		 */ -		if (uscsi_mode_select(fd, DAD_MODE_FORMAT, -			MODE_SELECT_PF, (caddr_t)&u_page3, -			MODESENSE_PAGE_LEN(&u_page3), &header)) { -			goto err; -		} - -		/* -		 * Now reformat the device -		 */ -		if (raw_format(fd)) { -			goto err; -		} -		return (0); -	} - -err: -	if (option_msg && diag_msg) { -		err_print( -			"Reformat device to 512-byte blocksize failed\n"); -	} -	return (1); -} - -static int -raw_format( -	int	fd) -{ -	union scsi_cdb			cdb; -	struct uscsi_cmd		ucmd; -	struct scsi_defect_hdr		defect_hdr; - -	(void) memset((char *)&ucmd, 0, sizeof (ucmd)); -	(void) memset((char *)&cdb, 0, sizeof (union scsi_cdb)); -	(void) memset((char *)&defect_hdr, 0, sizeof (defect_hdr)); -	cdb.scc_cmd = SCMD_FORMAT; -	ucmd.uscsi_cdb = (caddr_t)&cdb; -	ucmd.uscsi_cdblen = CDB_GROUP0; -	ucmd.uscsi_bufaddr = (caddr_t)&defect_hdr; -	ucmd.uscsi_buflen = sizeof (defect_hdr); -	cdb.cdb_opaque[1] = FPB_DATA; - -	/* -	 * Issue the format ioctl -	 */ -	fmt_print("Formatting...\n"); -	(void) fflush(stdout); -	if (uscsi_cmd(fd, &ucmd, -		(option_msg && diag_msg) ? F_NORMAL : F_SILENT)) { -		return (1); -	} -	return (0); -} -  /*   * Copy a string of characters from src to dst, for at   * most n bytes.  Strip all leading and trailing spaces, @@ -2383,7 +2216,8 @@ square_box(  	 * any blocks.  	 */ -	for (i = 0; (((*dim1)>>i)&1) == 0 && ((*dim1)>>i) > lim1; i++); +	for (i = 0; (((*dim1)>>i)&1) == 0 && ((*dim1)>>i) > lim1; i++) +		;  	if (i) {  		*dim1 = ((*dim1)>>i);  		*dim3 = ((*dim3)<<i); diff --git a/usr/src/cmd/format/ctlr_ata.c b/usr/src/cmd/format/ctlr_ata.c index 2f417b9b78..c8f982d71b 100644 --- a/usr/src/cmd/format/ctlr_ata.c +++ b/usr/src/cmd/format/ctlr_ata.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -155,7 +155,7 @@ ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr,  	blkno = (blkaddr_t)blk64;  	bzero((caddr_t)&dadkio_rwcmd, sizeof (struct dadkio_rwcmd)); -	tmpsec = secnt * 512; +	tmpsec = secnt * cur_blksz;  	/* Doing raw read */  	dadkio_rwcmd.cmd = (dir == DIR_READ) ? DADKIO_RWCMD_READ : @@ -213,12 +213,15 @@ ata_rdwr(int dir, int fd, diskaddr_t blk64, int secnt, caddr_t bufaddr,  int  ata_ck_format()  { -	unsigned char bufaddr[2048]; +	char *bufaddr;  	int status; +	bufaddr = (char *)zalloc(4 * cur_blksz);  	status = ata_rdwr(DIR_READ, cur_file, (diskaddr_t)1, 4,  	    (caddr_t)bufaddr, 0, NULL); +	free(bufaddr); +  	return (!status);  } diff --git a/usr/src/cmd/format/ctlr_scsi.c b/usr/src/cmd/format/ctlr_scsi.c index c9ddee8f15..c16327832d 100644 --- a/usr/src/cmd/format/ctlr_scsi.c +++ b/usr/src/cmd/format/ctlr_scsi.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -264,7 +264,7 @@ scsi_rdwr(dir, fd, blkno, secnt, bufaddr, flags, xfercntp)  		}  		ucmd.uscsi_cdb = (caddr_t)&cdb;  		ucmd.uscsi_bufaddr = bufaddr; -		ucmd.uscsi_buflen = nsectors * SECSIZE; +		ucmd.uscsi_buflen = nsectors * cur_blksz;  		rc = uscsi_cmd(fd, &ucmd, flags);  		if (rc != 0) @@ -290,7 +290,7 @@ scsi_rdwr(dir, fd, blkno, secnt, bufaddr, flags, xfercntp)  		blkno += nsectors;  		secnt -= nsectors; -		bufaddr += nsectors * SECSIZE; +		bufaddr += nsectors * cur_blksz;  	}  	/* @@ -326,7 +326,7 @@ scsi_ck_format(void)  	 * Try to read the first four blocks.  	 */  	status = scsi_rdwr(DIR_READ, cur_file, (diskaddr_t)0, 4, -		(caddr_t)cur_buf, F_SILENT, NULL); +	    (caddr_t)cur_buf, F_SILENT, NULL);  	return (!status);  } @@ -498,7 +498,7 @@ scsi_raw_format(void)  	    "by format verification and surface analysis.\n\n");  	if (check("Retry format without mode selects and Grown Defects list") -		!= 0) { +	    != 0) {  		return (-1);  	} @@ -580,18 +580,18 @@ scsi_format_time()  	 * If it fail, try to use the saved or current instead.  	 */  	status = uscsi_mode_sense(cur_file, DAD_MODE_GEOMETRY, -		MODE_SENSE_PC_DEFAULT, (caddr_t)page4, -		MAX_MODE_SENSE_SIZE, &header); +	    MODE_SENSE_PC_DEFAULT, (caddr_t)page4, +	    MAX_MODE_SENSE_SIZE, &header);  	if (status) {  		status = uscsi_mode_sense(cur_file, DAD_MODE_GEOMETRY, -			MODE_SENSE_PC_SAVED, (caddr_t)page4, -			MAX_MODE_SENSE_SIZE, &header); +		    MODE_SENSE_PC_SAVED, (caddr_t)page4, +		    MAX_MODE_SENSE_SIZE, &header);  	}  	if (status) {  		status = uscsi_mode_sense(cur_file, DAD_MODE_GEOMETRY, -			MODE_SENSE_PC_CURRENT, (caddr_t)page4, -			MAX_MODE_SENSE_SIZE, &header); +		    MODE_SENSE_PC_CURRENT, (caddr_t)page4, +		    MAX_MODE_SENSE_SIZE, &header);  	}  	if (status) {  		return (0); @@ -609,7 +609,7 @@ scsi_format_time()  	page4->rpm = BE_16(page4->rpm);  	p4_cylinders = (page4->cyl_ub << 16) + (page4->cyl_mb << 8) + -		page4->cyl_lb; +	    page4->cyl_lb;  	p4_heads = page4->heads;  	p4_rpm = page4->rpm; @@ -618,7 +618,7 @@ scsi_format_time()  	 */  	if (p4_rpm < MIN_RPM || p4_rpm > MAX_RPM) {  		err_print("Mode sense page(4) reports rpm value as %d," -			" adjusting it to %d\n", p4_rpm, AVG_RPM); +		    " adjusting it to %d\n", p4_rpm, AVG_RPM);  		p4_rpm = AVG_RPM;  	} @@ -626,7 +626,7 @@ scsi_format_time()  		return (0);  	format_time = ((scsi_format_revolutions * p4_heads * -			p4_cylinders) + p4_rpm) / p4_rpm; +	    p4_cylinders) + p4_rpm) / p4_rpm;  	if (option_msg && diag_msg) {  		err_print("       pcyl:    %d\n", p4_cylinders); @@ -1027,8 +1027,8 @@ scsi_ms_page3(scsi2_flag)  	tmp5 = page3->alt_tracks_vol;  	tmp6 = page3->alt_sect_zone; -	flag = (page3->data_bytes_sect != SECSIZE); -	page3->data_bytes_sect = SECSIZE; +	flag = (page3->data_bytes_sect != cur_blksz); +	page3->data_bytes_sect = cur_blksz;  	flag |= (page3->interleave != 1);  	page3->interleave = 1; @@ -1844,7 +1844,8 @@ scsi_convert_list_to_new(list, def_list, list_format)  		len = def_list->length / sizeof (struct scsi_bfi_defect);  		old_defect = def_list->list;  		new_defect = (struct defect_entry *) -				zalloc(LISTSIZE(len) * SECSIZE); +		    zalloc(deflist_size(cur_blksz, len) * +		    cur_blksz);  		list->header.magicno = (uint_t)DEFECT_MAGIC;  		list->list = new_defect; @@ -2618,7 +2619,7 @@ uscsi_reserve_release(int fd, int cmd)  	ucmd.uscsi_cdb = (caddr_t)&cdb;  	ucmd.uscsi_cdblen = CDB_GROUP0;  	status = uscsi_cmd(fd, &ucmd, -		(option_msg && diag_msg) ? F_NORMAL : F_SILENT); +	    (option_msg && diag_msg) ? F_NORMAL : F_SILENT);  	if (status) {  		/* @@ -2630,14 +2631,14 @@ uscsi_reserve_release(int fd, int cmd)  		(void) memset((char *)&cdb, 0, sizeof (union scsi_cdb));  		ucmd.uscsi_cdb = (caddr_t)&cdb;  		cdb.scc_cmd = (cmd == SCMD_RESERVE) ? -			SCMD_RESERVE_G1 : SCMD_RELEASE_G1; +		    SCMD_RESERVE_G1 : SCMD_RELEASE_G1;  		ucmd.uscsi_cdblen = CDB_GROUP1;  		status = uscsi_cmd(fd, &ucmd, -			(option_msg && diag_msg) ? F_NORMAL : F_SILENT); +		    (option_msg && diag_msg) ? F_NORMAL : F_SILENT);  		if (status) {  			if (option_msg) { -			    err_print("%s failed\n", (cmd == SCMD_RESERVE) ? -				"Reserve" : "Release"); +				err_print("%s failed\n", (cmd == SCMD_RESERVE) ? +				    "Reserve" : "Release");  			}  		}  	} @@ -2916,13 +2917,13 @@ scsi_extract_sense_info_descr(struct scsi_descr_sense_hdr *sdsp, int rqlen)  			 */  			result =  			    (((diskaddr_t)isd->isd_information[0] << 56) | -				((diskaddr_t)isd->isd_information[1] << 48) | -				((diskaddr_t)isd->isd_information[2] << 40) | -				((diskaddr_t)isd->isd_information[3] << 32) | -				((diskaddr_t)isd->isd_information[4] << 24) | -				((diskaddr_t)isd->isd_information[5] << 16) | -				((diskaddr_t)isd->isd_information[6] << 8)  | -				((diskaddr_t)isd->isd_information[7])); +			    ((diskaddr_t)isd->isd_information[1] << 48) | +			    ((diskaddr_t)isd->isd_information[2] << 40) | +			    ((diskaddr_t)isd->isd_information[3] << 32) | +			    ((diskaddr_t)isd->isd_information[4] << 24) | +			    ((diskaddr_t)isd->isd_information[5] << 16) | +			    ((diskaddr_t)isd->isd_information[6] << 8)  | +			    ((diskaddr_t)isd->isd_information[7]));  			break;  		} @@ -2975,7 +2976,7 @@ apply_chg_list(int pageno, int pagsiz, uchar_t *curbits,  	while (chglist != NULL) {  		if (chglist->pageno == pageno && -				chglist->byteno < pagsiz) { +		    chglist->byteno < pagsiz) {  			i = chglist->byteno;  			c = curbits[i];  			switch (chglist->mode) { @@ -3288,16 +3289,16 @@ check_support_for_defects()  	rq = (struct scsi_extended_sense *)ucmd.uscsi_rqbuf;  	status = uscsi_cmd(cur_file, &ucmd, -		(option_msg && diag_msg) ? F_NORMAL : F_SILENT); +	    (option_msg && diag_msg) ? F_NORMAL : F_SILENT);  	if (status != 0) {  		/*  		 * check if read_defect_list_is_supported.  		 */  		if (ucmd.uscsi_rqstatus == STATUS_GOOD && -			rq->es_key == KEY_ILLEGAL_REQUEST && -				rq->es_add_code == INVALID_OPCODE) -				return (0); +		    rq->es_key == KEY_ILLEGAL_REQUEST && +		    rq->es_add_code == INVALID_OPCODE) +			return (0);  	}  	return (1);  } @@ -3335,7 +3336,7 @@ scsi_format_without_defects()  	 * Issue the format ioctl  	 */  	status = uscsi_cmd(cur_file, &ucmd, -		(option_msg && diag_msg) ? F_NORMAL : F_SILENT); +	    (option_msg && diag_msg) ? F_NORMAL : F_SILENT);  	return (status);  } diff --git a/usr/src/cmd/format/defect.c b/usr/src/cmd/format/defect.c index 537a854518..a2f77e1032 100644 --- a/usr/src/cmd/format/defect.c +++ b/usr/src/cmd/format/defect.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -132,8 +132,8 @@ read_list(struct defect_list *list)  		/*  		 * Allocate space for the rest of the list.  		 */ -		size = LISTSIZE(list->header.count); -		list->list = (struct defect_entry *)zalloc(size * SECSIZE); +		size = deflist_size(cur_blksz, list->header.count); +		list->list = (struct defect_entry *)zalloc(size * cur_blksz);  		/*  		 * Try to read in the rest of the list. If there is an  		 * error, or the checksum is wrong, this copy is corrupt. @@ -352,7 +352,7 @@ write_deflist(struct defect_list *list)  		/*  		 * calculate how many sectors the defect list will occupy.  		 */ -		size = LISTSIZE(list->header.count); +		size = deflist_size(cur_blksz, list->header.count);  		/*  		 * Loop for each copy of the list to be written.  Write  		 * out the header of the list followed by the data. @@ -444,9 +444,9 @@ add_def(struct defect_entry *def, struct defect_list *list, int index)  	 * sector, allocate the necessary space.  	 */  	count = list->header.count; -	if (LISTSIZE(count + 1) > LISTSIZE(count)) +	if (deflist_size(cur_blksz, count + 1) > deflist_size(cur_blksz, count))  		list->list = (struct defect_entry *)rezalloc((void *)list->list, -		    LISTSIZE(count + 1) * SECSIZE); +		    deflist_size(cur_blksz, count + 1) * cur_blksz);  	/*  	 * Slip all the defects after this one down one slot in the list.  	 */ @@ -485,3 +485,22 @@ kill_deflist(struct defect_list *list)  	list->list = NULL;  	list->flags = 0;  } + +/* + * This routine returns the defect list size + * according to the sector size. + */ +int +deflist_size(int secsz, int sz) +{ +	int rval; + +	if (secsz == 0) { +		secsz = SECSIZE; +	} + +	rval = sz ? ((sz * sizeof (struct defect_entry) + +	    secsz - 1) / secsz) : 1; + +	return (rval); +} diff --git a/usr/src/cmd/format/defect.h b/usr/src/cmd/format/defect.h index a917144068..7b3990ceee 100644 --- a/usr/src/cmd/format/defect.h +++ b/usr/src/cmd/format/defect.h @@ -2,9 +2,8 @@   * CDDL HEADER START   *   * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License").  You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License.   *   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE   * or http://www.opensolaris.org/os/licensing. @@ -20,15 +19,13 @@   * CDDL HEADER END   */  /* - * Copyright 1991-2002 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  #ifndef	_DEFECT_H  #define	_DEFECT_H -#pragma ident	"%Z%%M%	%I%	%E% SMI" -  #ifdef	__cplusplus  extern "C" {  #endif @@ -82,16 +79,6 @@ struct defect_list {  #define	LISTCOUNT	2  /* - * This defines the size (in sectors) of the defect array given the number - * of defects in the array.  It must be rounded to a sector boundary since - * that is the atomic disk size.  We make a zero length list use up a - * sector because it is convenient to have malloc'd space in every - * non-null list. - */ -#define	LISTSIZE(x)	((x) ? ((x) * sizeof (struct defect_entry) + \ -			SECSIZE - 1) / SECSIZE : 1) - -/*   * These defines are the flags for the defect list.   */  #define	LIST_DIRTY	0x01	/* List needs to be synced */ @@ -135,6 +122,15 @@ void	add_def(struct defect_entry *def, struct defect_list *list,  		int index);  void	kill_deflist(struct defect_list *list); +/* + * This defines the size (in sectors) of the defect array given the number + * of defects in the array.  It must be rounded to a sector boundary since + * that is the atomic disk size.  We make a zero length list use up a + * sector because it is convenient to have malloc'd space in every + * non-null list. + */ +int	deflist_size(int secsz, int sz); +  #ifdef	__cplusplus  }  #endif diff --git a/usr/src/cmd/format/disk_generic.c b/usr/src/cmd/format/disk_generic.c index 3aa205b3c0..d053660a04 100644 --- a/usr/src/cmd/format/disk_generic.c +++ b/usr/src/cmd/format/disk_generic.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -121,8 +121,8 @@ generic_rdwr(dir, fd, blkno, secnt, bufaddr, flags, xfercntp)  	offset_t	tmpsec, status, tmpblk;  	int		ret; -	tmpsec = (offset_t)secnt * UBSIZE; -	tmpblk = (offset_t)blkno * UBSIZE; +	tmpsec = (offset_t)secnt * cur_blksz; +	tmpblk = (offset_t)blkno * cur_blksz;  #if defined(_FIRMWARE_NEEDS_FDISK)  	/* Use "p0" file to seek/read the data  */ diff --git a/usr/src/cmd/format/global.h b/usr/src/cmd/format/global.h index fc3a25a938..241df1e3e5 100644 --- a/usr/src/cmd/format/global.h +++ b/usr/src/cmd/format/global.h @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -107,6 +107,7 @@ int	dev_expert;			/* enable for developer mode */  int	cur_file;			/* file descriptor for current disk */  int	cur_flags;			/* flags for current disk */  int	cur_label;			/* current label type */ +uint_t	cur_blksz;			/* currect disk block size */  struct	disk_info *cur_disk;		/* current disk */  struct	disk_type *cur_dtype;		/* current dtype */  struct	ctlr_info *cur_ctlr;		/* current ctlr */ diff --git a/usr/src/cmd/format/hardware_structs.h b/usr/src/cmd/format/hardware_structs.h index b72ebdf308..81bc40d202 100644 --- a/usr/src/cmd/format/hardware_structs.h +++ b/usr/src/cmd/format/hardware_structs.h @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -62,6 +62,8 @@ struct disk_info {  	char			v_volume[LEN_DKL_VVOL];  						/* volume name from label */  						/* (no terminating null) */ +	uint_t			disk_lbasize;	/* disk block size */ +  };  #define	NSPECIFICS	8 diff --git a/usr/src/cmd/format/io.c b/usr/src/cmd/format/io.c index 1aa2413c65..6e9e4064a9 100644 --- a/usr/src/cmd/format/io.c +++ b/usr/src/cmd/format/io.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -606,11 +606,11 @@ reprompt:  			fmt_print("[%llub, %llue, %llumb, %llugb, %llutb]",  			    efi_deflt->end_sector,  			    efi_deflt->start_sector + efi_deflt->end_sector - 1, -			    (efi_deflt->end_sector * DEV_BSIZE) / +			    (efi_deflt->end_sector * cur_blksz) /  				(1024 * 1024), -			    (efi_deflt->end_sector * DEV_BSIZE) / +			    (efi_deflt->end_sector * cur_blksz) /  				(1024 * 1024 * 1024), -			    (efi_deflt->end_sector * DEV_BSIZE) / +			    (efi_deflt->end_sector * cur_blksz) /  				((uint64_t)1024 * 1024 * 1024 * 1024));  			break;  		case FIO_OPINT: @@ -1518,13 +1518,13 @@ or g(gigabytes)\n");  			fmt_print("Expecting up to %llu sectors,",  			    cur_parts->etoc->efi_last_u_lba);  			fmt_print("or %llu megabytes,", -			    (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ +			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/  				(1024 * 1024));  			fmt_print("or %llu gigabytes\n", -			    (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ +			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/  				(1024 * 1024 * 1024));  			fmt_print("or %llu terabytes\n", -			    (cur_parts->etoc->efi_last_u_lba * DEV_BSIZE)/ +			    (cur_parts->etoc->efi_last_u_lba * cur_blksz)/  				((uint64_t)1024 * 1024 * 1024 * 1024));  			break;  		} @@ -1676,7 +1676,7 @@ or g(gigabytes)\n");  				break;  			}  			return (uint64_t)((float)nmegs * 1024.0 * -				1024.0 * 1024.0 * 1024.0 / DEV_BSIZE); +				1024.0 * 1024.0 * 1024.0 / cur_blksz);  		default:  			err_print( @@ -2102,6 +2102,7 @@ pr_diskline(disk, num)  			type->dtype_acyl, type->dtype_nhead,  			type->dtype_nsect);  	} else if ((type != NULL) && (disk->label_type == L_TYPE_EFI)) { +		cur_blksz = disk->disk_lbasize;  		print_efi_string(type->vendor, type->product,  			type->revision, type->capacity);  	} else if (disk->disk_flags & DSK_RESERVED) { diff --git a/usr/src/cmd/format/label.c b/usr/src/cmd/format/label.c index 3f172c5806..4740baebb2 100644 --- a/usr/src/cmd/format/label.c +++ b/usr/src/cmd/format/label.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -270,11 +270,11 @@ write_label()  {  	int	error = 0, head, sec;  	struct dk_label label; -	struct dk_label new_label;  	struct extvtoc	vtoc;  	struct dk_geom	geom;  	struct dk_gpt	*vtoc64;  	int		nbackups; +	char		*new_label;  #if defined(_SUNOS_VTOC_8)  	int i; @@ -313,7 +313,8 @@ write_label()  	 * Fill in a label structure with the geometry information.  	 */  	(void) memset((char *)&label, 0, sizeof (struct dk_label)); -	(void) memset((char *)&new_label, 0, sizeof (struct dk_label)); +	new_label = zalloc(cur_blksz); +  	label.dkl_pcyl = pcyl;  	label.dkl_ncyl = ncyl;  	label.dkl_acyl = acyl; @@ -358,10 +359,9 @@ write_label()  #if defined(_SUNOS_VTOC_16)  	/* -	 * Also add in v_sectorsz, as the driver will.  Everyone -	 * else is assuming DEV_BSIZE, so we do the same. +	 * Also add in v_sectorsz, as the driver will.  	 */ -	label.dkl_vtoc.v_sectorsz = DEV_BSIZE; +	label.dkl_vtoc.v_sectorsz = cur_blksz;  #endif			/* defined(_SUNOS_VTOC_16) */  	/* @@ -372,6 +372,7 @@ write_label()  	 * Convert the label into a vtoc  	 */  	if (label_to_vtoc(&vtoc, &label) == -1) { +		free(new_label);  		return (-1);  	}  	/* @@ -400,6 +401,7 @@ write_label()  	 * is only for SCSI disks.  	 */  	if (SCSI && do_geometry_sanity_check() != 0) { +		free(new_label);  		return (-1);  	} @@ -444,14 +446,15 @@ write_label()  	for (sec = 1; ((sec < BAD_LISTCNT * 2 + 1) && (sec < nsect));  	    sec += 2) {  		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, (diskaddr_t) -		    ((chs2bn(ncyl + acyl - 1, head, sec)) + solaris_offset), -		    1, (caddr_t)&new_label, F_NORMAL, NULL)) { -			err_print("Warning: error reading backup label.\n"); +		    ((chs2bn(ncyl + acyl - 1, head, sec)) +		    + solaris_offset), 1, new_label, F_NORMAL, NULL)) { +			err_print("Warning: error reading" +			    "backup label.\n");  			error = -1;  		} else { -			if (bcmp((char *)&label, (char *)&new_label, +			if (bcmp((char *)&label, new_label,  			    sizeof (struct dk_label)) == 0) { -					nbackups++; +				nbackups++;  			}  		}  	} @@ -466,6 +469,7 @@ write_label()  	cur_disk->disk_flags |= DSK_LABEL;  	exit_critical(); +	free(new_label);  	return (error);  } @@ -578,7 +582,8 @@ get_disk_info(int fd, struct efi_info *label)  			err_print("Fetch Capacity failed\n");  			return (-1);  		} -		label->capacity = minf.dki_capacity * minf.dki_lbsize / 512; +		label->capacity = +		    minf.dki_capacity * minf.dki_lbsize / cur_blksz;  	} else {  		label->capacity = capacity.sc_capacity; @@ -689,7 +694,7 @@ vtoc_to_label(struct dk_label *label, struct extvtoc *vtoc,  	/*  	 * Sanity-check the vtoc  	 */ -	if (vtoc->v_sanity != VTOC_SANE || vtoc->v_sectorsz != DEV_BSIZE || +	if (vtoc->v_sanity != VTOC_SANE ||  	    vtoc->v_nparts != V_NUMPAR) {  		return (-1);  	} @@ -881,7 +886,7 @@ label_to_vtoc(struct extvtoc *vtoc, struct dk_label *label)  	 */  	vtoc->v_sanity = VTOC_SANE;  	vtoc->v_version = V_VERSION; -	vtoc->v_sectorsz = DEV_BSIZE; +	vtoc->v_sectorsz = cur_blksz;  	vtoc->v_nparts = V_NUMPAR;  	(void) memcpy(vtoc->v_asciilabel, label->dkl_asciilabel, diff --git a/usr/src/cmd/format/main.c b/usr/src/cmd/format/main.c index 5d1d9c6c81..5cdb72a825 100644 --- a/usr/src/cmd/format/main.c +++ b/usr/src/cmd/format/main.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -365,6 +365,7 @@ init_globals(disk)  	cur_label = cur_disk->label_type;  	cur_ctlr = cur_disk->disk_ctlr;  	cur_parts = cur_disk->disk_parts; +	cur_blksz = cur_disk->disk_lbasize;  	cur_ctype = cur_ctlr->ctlr_ctype;  	cur_ops = cur_ctype->ctype_ops;  	cur_flags = 0; @@ -439,8 +440,8 @@ init_globals(disk)  		/*  		 * Allocate the buffers.  		 */ -		cur_buf = (void *) zalloc(BUF_SECTS * SECSIZE); -		pattern_buf = (void *) zalloc(BUF_SECTS * SECSIZE); +		cur_buf = (void *) zalloc(BUF_SECTS * cur_blksz); +		pattern_buf = (void *) zalloc(BUF_SECTS * cur_blksz);  		/*  		 * Tell the user which disk (s)he selected. diff --git a/usr/src/cmd/format/menu_analyze.c b/usr/src/cmd/format/menu_analyze.c index 2b18e3c327..e932c258c8 100644 --- a/usr/src/cmd/format/menu_analyze.c +++ b/usr/src/cmd/format/menu_analyze.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -183,12 +183,12 @@ a_print()  	 * Loop through the data buffer.  	 */  	lines = 0; -	for (i = 0; i < scan_size * SECSIZE / sizeof (int); i += 6) { +	for (i = 0; i < scan_size * cur_blksz / sizeof (int); i += 6) {  		/*  		 * Print the data.  		 */  		for (j = 0; j < 6; j++) -			if (i + j < scan_size * SECSIZE / sizeof (int)) +			if (i + j < scan_size * cur_blksz / sizeof (int))  				fmt_print("0x%08x  ",  				    *((int *)((int *)cur_buf + i + j)));  		fmt_print("\n"); diff --git a/usr/src/cmd/format/menu_command.c b/usr/src/cmd/format/menu_command.c index c5b5ea930e..9c43d41ae0 100644 --- a/usr/src/cmd/format/menu_command.c +++ b/usr/src/cmd/format/menu_command.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -293,8 +293,8 @@ found:  	 * Also, set partition table (best guess) too.  	 */  	if (!option_f && ncyl == 0 && nhead == 0 && nsect == 0 && -		(disk->label_type != L_TYPE_EFI)) { -		    (void) c_type(); +	    (disk->label_type != L_TYPE_EFI)) { +		(void) c_type();  	}  	/* @@ -305,11 +305,11 @@ found:  	if ((cur_disk->label_type == L_TYPE_EFI) &&  	    (cur_disk->disk_parts->etoc->efi_flags & -		EFI_GPT_PRIMARY_CORRUPT)) { -		    err_print("Reading the primary EFI GPT label "); -		    err_print("failed.  Using backup label.\n"); -		    err_print("Use the 'backup' command to restore "); -		    err_print("the primary label.\n"); +	    EFI_GPT_PRIMARY_CORRUPT)) { +		err_print("Reading the primary EFI GPT label "); +		err_print("failed.  Using backup label.\n"); +		err_print("Use the 'backup' command to restore "); +		err_print("the primary label.\n");  	}  #if defined(_SUNOS_VTOC_16) @@ -383,6 +383,7 @@ c_type()  	} else {  		auto_conf_choice = -1;  	} +  	i = first_disk;  	for (tptr = type; tptr != NULL; tptr = tptr->dtype_next) {  		/* @@ -396,7 +397,8 @@ c_type()  			continue;  		}  		if (tptr->dtype_asciilabel) -		    fmt_print("        %d. %s\n", i++, tptr->dtype_asciilabel); +			fmt_print("        %d. %s\n", i++, +			    tptr->dtype_asciilabel);  	}  	other_choice = i;  	fmt_print("        %d. other\n", i); @@ -418,85 +420,89 @@ c_type()  		/*  		 * User chose "auto configure".  		 */ -	    (void) strcpy(x86_devname, cur_disk->disk_name); -	    switch (cur_disk->label_type) { -	    case L_TYPE_SOLARIS: -		if ((tptr = auto_sense(cur_file, 1, &label)) == NULL) { -			err_print("Auto configure failed\n"); -			return (-1); -		} -		fmt_print("%s: configured with capacity of ", -			cur_disk->disk_name); -		nblks = (diskaddr_t)tptr->dtype_ncyl * tptr->dtype_nhead * -			tptr->dtype_nsect; -		scaled = bn2mb(nblks); -		if (scaled > 1024.0) { -			fmt_print("%1.2fGB\n", scaled/1024.0); -		} else { -			fmt_print("%1.2fMB\n", scaled); -		} -		fmt_print("<%s cyl %d alt %d hd %d sec %d>\n", -			tptr->dtype_asciilabel, tptr->dtype_ncyl, -			tptr->dtype_acyl, tptr->dtype_nhead, -			tptr->dtype_nsect); -		break; -	    case L_TYPE_EFI: -		if ((tptr = auto_efi_sense(cur_file, &efi_info)) == NULL) { -			err_print("Auto configure failed\n"); -			return (-1); -		} -		fmt_print("%s: configured with capacity of ", -			cur_disk->disk_name); -		scaled = bn2mb(efi_info.capacity); -		if (scaled > 1024.0) { -			fmt_print("%1.2fGB\n", scaled/1024.0); -		} else { -			fmt_print("%1.2fMB\n", scaled); -		} -		print_efi_string(efi_info.vendor, efi_info.product, -		    efi_info.revision, efi_info.capacity); -		fmt_print("\n"); -		for (nparts = 0; nparts < cur_parts->etoc->efi_nparts; -			nparts++) { -		    if (cur_parts->etoc->efi_parts[nparts].p_tag == -			V_RESERVED) { -			if (cur_parts->etoc->efi_parts[nparts].p_name) { -			    (void) strcpy(volname, -				cur_parts->etoc->efi_parts[nparts].p_name); -			    volinit = 1; +		(void) strcpy(x86_devname, cur_disk->disk_name); +		switch (cur_disk->label_type) { +		case L_TYPE_SOLARIS: +			if ((tptr = auto_sense(cur_file, 1, &label)) == NULL) { +				err_print("Auto configure failed\n"); +				return (-1); +			} +			fmt_print("%s: configured with capacity of ", +			    cur_disk->disk_name); +			nblks = (diskaddr_t)tptr->dtype_ncyl * +			    tptr->dtype_nhead * tptr->dtype_nsect; +			scaled = bn2mb(nblks); +			if (scaled > 1024.0) { +				fmt_print("%1.2fGB\n", scaled/1024.0); +			} else { +				fmt_print("%1.2fMB\n", scaled);  			} +			fmt_print("<%s cyl %d alt %d hd %d sec %d>\n", +			    tptr->dtype_asciilabel, tptr->dtype_ncyl, +			    tptr->dtype_acyl, tptr->dtype_nhead, +			    tptr->dtype_nsect);  			break; -		    } -		} -		enter_critical(); -		if (delete_disk_type(cur_disk->disk_type) != 0) { -			fmt_print("Autoconfiguration failed.\n"); -			return (-1); -		} -		cur_disk->disk_type = tptr; -		cur_disk->disk_parts = tptr->dtype_plist; -		init_globals(cur_disk); -		exit_critical(); -		if (volinit) { -		    for (nparts = 0; nparts < cur_parts->etoc->efi_nparts; -				nparts++) { -			if (cur_parts->etoc->efi_parts[nparts].p_tag == -				V_RESERVED) { -			    (void) strcpy( -				cur_parts->etoc->efi_parts[nparts].p_name, +		case L_TYPE_EFI: +			if ((tptr = auto_efi_sense(cur_file, &efi_info)) +			    == NULL) { +				err_print("Auto configure failed\n"); +				return (-1); +			} +			fmt_print("%s: configured with capacity of ", +			    cur_disk->disk_name); +			scaled = bn2mb(efi_info.capacity); +			if (scaled > 1024.0) { +				fmt_print("%1.2fGB\n", scaled/1024.0); +			} else { +				fmt_print("%1.2fMB\n", scaled); +			} +			cur_blksz = efi_info.e_parts->efi_lbasize; +			print_efi_string(efi_info.vendor, efi_info.product, +			    efi_info.revision, efi_info.capacity); +			fmt_print("\n"); +			for (nparts = 0; nparts < cur_parts->etoc->efi_nparts; +			    nparts++) { +				if (cur_parts->etoc->efi_parts[nparts].p_tag == +				    V_RESERVED) { +					if (cur_parts->etoc->efi_parts[nparts]. +					    p_name) { +						(void) strcpy(volname, +						    cur_parts->etoc->efi_parts +						    [nparts].p_name); +						volinit = 1; +					} +					break; +				} +			} +			enter_critical(); +			if (delete_disk_type(cur_disk->disk_type) != 0) { +				fmt_print("Autoconfiguration failed.\n"); +				return (-1); +			} +			cur_disk->disk_type = tptr; +			cur_disk->disk_parts = tptr->dtype_plist; +			init_globals(cur_disk); +			exit_critical(); +			if (volinit) { +				for (nparts = 0; nparts < +				    cur_parts->etoc->efi_nparts; nparts++) { +				if (cur_parts->etoc->efi_parts[nparts].p_tag == +				    V_RESERVED) { +				(void) strcpy( +				    cur_parts->etoc->efi_parts[nparts].p_name,  				    volname); -			    (void) strlcpy(cur_disk->v_volume, volname, +				(void) strlcpy(cur_disk->v_volume, volname,  				    LEN_DKL_VVOL); -			    break; +				break; +				} +				}  			} -		    } -		} -		return (0); -		break; -	    default: +			return (0); +			break; +		default:  		/* Should never happen */  		return (-1); -	    } +		}  	} else if ((index == other_choice) && (cur_label == L_TYPE_SOLARIS)) {  		/*  		 * User chose "other". @@ -525,14 +531,13 @@ c_type()  		d->dtype_threshold = get_threshold(&d->dtype_options);  		d->dtype_prefetch_min = get_min_prefetch(&d->dtype_options);  		d->dtype_prefetch_max = get_max_prefetch(d->dtype_prefetch_min, -			&d->dtype_options); +		    &d->dtype_options);  		d->dtype_bps = get_bps();  #if defined(sparc)  		d->dtype_dr_type = 0;  #endif /* defined(sparc) */  		d->dtype_asciilabel = get_asciilabel(); -  		/*  		 * Add the new type to the list of possible types for  		 * this controller.  We lock out interrupts so the lists @@ -563,18 +568,18 @@ c_type()  		cur_parts->etoc->efi_last_lba = maxLBA;  		cur_parts->etoc->efi_last_u_lba = maxLBA - 34;  		for (i = 0; i < cur_parts->etoc->efi_nparts; i++) { -		    cur_parts->etoc->efi_parts[i].p_start = 0; -		    cur_parts->etoc->efi_parts[i].p_size = 0; -		    cur_parts->etoc->efi_parts[i].p_tag = V_UNASSIGNED; +			cur_parts->etoc->efi_parts[i].p_start = 0; +			cur_parts->etoc->efi_parts[i].p_size = 0; +			cur_parts->etoc->efi_parts[i].p_tag = V_UNASSIGNED;  		}  		cur_parts->etoc->efi_parts[8].p_start = -			maxLBA - 34 - (1024 * 16); +		    maxLBA - 34 - (1024 * 16);  		cur_parts->etoc->efi_parts[8].p_size = (1024 * 16);  		cur_parts->etoc->efi_parts[8].p_tag = V_RESERVED;  		if (write_label()) { -		    err_print("Write label failed\n"); +			err_print("Write label failed\n");  		} else { -		    cur_disk->disk_flags &= ~DSK_LABEL_DIRTY; +			cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;  		}  		return (0);  	} else { @@ -584,10 +589,10 @@ c_type()  		i = first_disk;  		tptr = type;  		while (i < index) { -		    if (tptr->dtype_asciilabel) { -			i++; -		    } -		    tptr = tptr->dtype_next; +			if (tptr->dtype_asciilabel) { +				i++; +			} +			tptr = tptr->dtype_next;  		}  		if ((tptr->dtype_asciilabel == NULL) &&  		    (tptr->dtype_next != NULL)) { @@ -605,18 +610,19 @@ c_type()  	 * running from a file.  	 */  	if ((tptr != oldtype) && -			checkmount((diskaddr_t)-1, (diskaddr_t)-1)) { +	    checkmount((diskaddr_t)-1, (diskaddr_t)-1)) {  		err_print( -		"Cannot set disk type while it has mounted partitions.\n\n"); +		    "Cannot set disk type while it has mounted " +		    "partitions.\n\n");  		return (-1);  	}  	/*  	 * check for partitions being used for swapping in format zone  	 */  	if ((tptr != oldtype) && -			checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { -		err_print("Cannot set disk type while its partition are \ -currently being used for swapping.\n"); +	    checkswap((diskaddr_t)-1, (diskaddr_t)-1)) { +		err_print("Cannot set disk type while its partition are " +		"currently being used for swapping.\n");  		return (-1);  	} @@ -625,11 +631,11 @@ currently being used for swapping.\n");  	 */  	if ((tptr != oldtype) && -		checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, -		    (diskaddr_t)-1, 0, 0)) { +	    checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1, +	    (diskaddr_t)-1, 0, 0)) {  		err_print("Cannot set disk type while its "  		    "partitions are currently in use.\n"); -				return (-1); +		return (-1);  	}  	/*  	 * If the type selected is different from the previous type, @@ -742,8 +748,8 @@ c_current()  			fmt_print("<type unknown>\n");  		} else if (cur_label == L_TYPE_SOLARIS) {  			fmt_print("<%s cyl %d alt %d hd %d sec %d>\n", -				cur_dtype->dtype_asciilabel, ncyl, -				acyl, nhead, nsect); +			    cur_dtype->dtype_asciilabel, ncyl, +			    acyl, nhead, nsect);  		} else if (cur_label == L_TYPE_EFI) {  			print_efi_string(cur_dtype->vendor,  			    cur_dtype->product, cur_dtype->revision, @@ -753,13 +759,13 @@ c_current()  		fmt_print("%s\n", cur_disk->devfs_name);  	} else {  		fmt_print("%s%d: <", cur_ctlr->ctlr_dname, -			cur_disk->disk_dkinfo.dki_unit); +		    cur_disk->disk_dkinfo.dki_unit);  		if (cur_dtype == NULL) {  			fmt_print("type unknown");  		} else if (cur_label == L_TYPE_SOLARIS) {  			fmt_print("%s cyl %d alt %d hd %d sec %d", -				cur_dtype->dtype_asciilabel, ncyl, -				acyl, nhead, nsect); +			    cur_dtype->dtype_asciilabel, ncyl, +			    acyl, nhead, nsect);  		} else if (cur_label == L_TYPE_EFI) {  			print_efi_string(cur_dtype->vendor,  			    cur_dtype->product, cur_dtype->revision, @@ -811,8 +817,8 @@ c_format()  	 * can only be retrieved after formatting the disk.  	 */  	if ((cur_ctype->ctype_flags & CF_SCSI) && !EMBEDDED_SCSI && -		(cur_ctype->ctype_flags & CF_DEFECTS) && -			! (cur_flags & DISK_FORMATTED)) { +	    (cur_ctype->ctype_flags & CF_DEFECTS) && +	    ! (cur_flags & DISK_FORMATTED)) {  		cur_list.flags |= LIST_RELOAD;  	} else if (cur_list.list == NULL && !EMBEDDED_SCSI) { @@ -827,25 +833,25 @@ c_format()  	 */  	ioparam.io_bounds.lower = start = 0;  	if (cur_label == L_TYPE_SOLARIS) { -	    if (cur_ctype->ctype_flags & CF_SCSI) { -		ioparam.io_bounds.upper = end = datasects() - 1; -	    } else { -		ioparam.io_bounds.upper = end = physsects() - 1; -	    } +		if (cur_ctype->ctype_flags & CF_SCSI) { +			ioparam.io_bounds.upper = end = datasects() - 1; +		} else { +			ioparam.io_bounds.upper = end = physsects() - 1; +		}  	} else { -	    ioparam.io_bounds.upper = end = cur_parts->etoc->efi_last_lba; +		ioparam.io_bounds.upper = end = cur_parts->etoc->efi_last_lba;  	}  	if (! (cur_ctlr->ctlr_flags & DKI_FMTVOL)) {  		deflt = ioparam.io_bounds.lower;  		start = input(FIO_BN, -			"Enter starting block number", ':', -			&ioparam, (int *)&deflt, DATA_INPUT); +		    "Enter starting block number", ':', +		    &ioparam, (int *)&deflt, DATA_INPUT);  		ioparam.io_bounds.lower = start;  		deflt = ioparam.io_bounds.upper;  		end = input(FIO_BN, -			"Enter ending block number", ':', -			&ioparam, (int *)&deflt, DATA_INPUT); +		    "Enter ending block number", ':', +		    &ioparam, (int *)&deflt, DATA_INPUT);  	}  	/*  	 * Some disks can format tracks.  Make sure the whole track is @@ -853,7 +859,7 @@ c_format()  	 */  	if (cur_ctlr->ctlr_flags & DKI_FMTTRK) {  		if (bn2s(start) != 0 || -				bn2s(end) != sectors(bn2h(end)) - 1) { +		    bn2s(end) != sectors(bn2h(end)) - 1) {  			err_print("Controller requires formatting of ");  			err_print("entire tracks.\n");  			return (-1); @@ -886,13 +892,22 @@ currently being used for swapping.\n");  	 */  	if (checkdevinuse(cur_disk->disk_name, start, end, 0, 0)) {  		err_print("Cannot format disk while its partitions " -			    "are currently in use.\n"); +		    "are currently in use.\n"); +		return (-1); +	} + +	if (cur_disk->disk_lbasize != DEV_BSIZE) { +		fmt_print("Current disk sector size is %d Byte, format\n" +		    "will change the sector size to 512 Byte. ", +		    cur_disk->disk_lbasize); +		if (check("Continue")) {  			return (-1); +		}  	}  	if (SCSI && (format_time = scsi_format_time()) > 0) {  		fmt_print( -		    "Ready to format.  Formatting cannot be interrupted\n" +		    "\nReady to format.  Formatting cannot be interrupted\n"  		    "and takes %d minutes (estimated). ", format_time);  	} else if (cur_dtype->dtype_options & SUP_FMTTIME) { @@ -913,7 +928,7 @@ currently being used for swapping.\n");  		 * ms.  		 */  		format_time = ((60000 / cur_dtype->dtype_rpm) +1) * -			format_tracks + format_cyls * 7; +		    format_tracks + format_cyls * 7;  		/*  		 * 20% done tick (sec)  		 */ @@ -964,7 +979,7 @@ currently being used for swapping.\n");  	 */  	clock = time((time_t *)0);  	fmt_print("Beginning format. The current time is %s\n", -		ctime(&clock)); +	    ctime(&clock));  	enter_critical();  	/*  	 * Mark the defect list dirty so it will be rewritten when we are @@ -980,15 +995,15 @@ currently being used for swapping.\n");  	 * dirty so it will be rewritten.  	 */  	if (cur_disk->label_type == L_TYPE_SOLARIS) { -	    if (start < totalsects() && end >= datasects()) { -		if (cur_disk->disk_flags & DSK_LABEL) -			cur_flags |= LABEL_DIRTY; -	    } +		if (start < totalsects() && end >= datasects()) { +			if (cur_disk->disk_flags & DSK_LABEL) +				cur_flags |= LABEL_DIRTY; +		}  	} else if (cur_disk->label_type == L_TYPE_EFI) { -	    if (start < 34) { -		if (cur_disk->disk_flags & DSK_LABEL) -		    cur_flags |= LABEL_DIRTY; -	    } +		if (start < 34) { +			if (cur_disk->disk_flags & DSK_LABEL) +				cur_flags |= LABEL_DIRTY; +		}  	}  	if (start == 0) {  		cur_flags |= LABEL_DIRTY; @@ -1078,7 +1093,7 @@ c_repair()  	diskaddr_t	bn;  	int		status;  	u_ioparam_t	ioparam; -	char		buf[SECSIZE]; +	char		*buf;  	int		buf_is_good;  	int		block_has_error;  	int		i; @@ -1125,13 +1140,13 @@ c_repair()  	 */  	ioparam.io_bounds.lower = 0;  	if (cur_disk->label_type == L_TYPE_SOLARIS) { -	    ioparam.io_bounds.upper = physsects() - 1; +		ioparam.io_bounds.upper = physsects() - 1;  	} else { -	    ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba; +		ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;  	}  	bn = input(FIO_BN, -		"Enter absolute block number of defect", ':', -		&ioparam, (int *)NULL, DATA_INPUT); +	    "Enter absolute block number of defect", ':', +	    &ioparam, (int *)NULL, DATA_INPUT);  	/*  	 * Check to see if there is a mounted file system over the  	 * specified sector.  If there is, make sure the user is @@ -1156,6 +1171,9 @@ being used for swapping.\ncontinue"))  			return (-1);  	} +	buf = zalloc((cur_disk->disk_lbasize == 0) ? +	    SECSIZE : cur_disk->disk_lbasize); +  	/*  	 * Try to read the sector before repairing it.  If we can  	 * get good data out of it, we can write that data back @@ -1169,7 +1187,7 @@ being used for swapping.\ncontinue"))  	block_has_error = 1;  	for (i = 0; i < 5; i++) {  		status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, -				1, buf, (F_SILENT | F_ALLERRS), NULL); +		    1, buf, (F_SILENT | F_ALLERRS), NULL);  		if (status)  			break;		/* one of the tries failed */  	} @@ -1177,6 +1195,7 @@ being used for swapping.\ncontinue"))  		block_has_error = 0;  		if (check("\  This block doesn't appear to be bad.  Repair it anyway")) { +			free(buf);  			return (0);  		}  	} @@ -1184,6 +1203,7 @@ This block doesn't appear to be bad.  Repair it anyway")) {  	 * Last chance...  	 */  	if (check("Ready to repair defect, continue")) { +		free(buf);  		return (-1);  	}  	/* @@ -1194,7 +1214,7 @@ This block doesn't appear to be bad.  Repair it anyway")) {  	buf_is_good = 0;  	for (i = 0; i < 5; i++) {  		status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, -					1, buf, F_SILENT, NULL); +		    1, buf, F_SILENT, NULL);  		if (status == 0) {  			buf_is_good = 1;  			break; @@ -1229,13 +1249,13 @@ This block doesn't appear to be bad.  Repair it anyway")) {  		 */  		fmt_print("ok.\n");  		if (!buf_is_good) { -			bzero(buf, SECSIZE); +			bzero(buf, cur_disk->disk_lbasize);  		}  		status = (*cur_ops->op_rdwr)(DIR_WRITE, cur_file, bn, -					1, buf, (F_SILENT | F_ALLERRS), NULL); +		    1, buf, (F_SILENT | F_ALLERRS), NULL);  		if (status == 0) {  			status = (*cur_ops->op_rdwr)(DIR_READ, cur_file, -				bn, 1, buf, (F_SILENT | F_ALLERRS), NULL); +			    bn, 1, buf, (F_SILENT | F_ALLERRS), NULL);  		}  		if (status) {  			fmt_print("The new block %llu (", bn); @@ -1275,6 +1295,8 @@ This block doesn't appear to be bad.  Repair it anyway")) {  		kill_deflist(&work_list);  	}  	exit_critical(); +	free(buf); +  	/*  	 * Return status.  	 */ @@ -1304,9 +1326,9 @@ c_show()  	 */  	ioparam.io_bounds.lower = 0;  	if (cur_disk->label_type == L_TYPE_SOLARIS) { -	    ioparam.io_bounds.upper = physsects() - 1; +		ioparam.io_bounds.upper = physsects() - 1;  	} else { -	    ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba; +		ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;  	}  	bn = input(FIO_BN, "Enter a disk block", ':',  	    &ioparam, (int *)NULL, DATA_INPUT); @@ -1359,7 +1381,7 @@ c_label()  		/* Bleagh, too descriptive */  		if (check_label_with_mount()) {  			err_print("Cannot label disk while it has " -				"mounted partitions.\n\n"); +			    "mounted partitions.\n\n");  			return (-1);  		}  	} @@ -1398,7 +1420,7 @@ c_label()  	 */  	if (cur_parts == NULL) {  		fmt_print("Current Partition Table is not set, " -			"using default.\n"); +		    "using default.\n");  		cur_disk->disk_parts = cur_parts = cur_dtype->dtype_plist;  		if (cur_parts == NULL) {  			err_print("No default available, cannot label.\n"); @@ -1411,53 +1433,55 @@ c_label()  	 */  	if (expert_mode) {  #if defined(_SUNOS_VTOC_8) -	    int 		i; +		int 		i;  #endif -	    int 		choice; -	    u_ioparam_t		ioparam; -	    struct extvtoc	vtoc; -	    struct dk_label	label; -	    struct dk_gpt	*vtoc64; -	    struct efi_info	efinfo; -	    struct disk_type	*dptr; - -	    /* Ask user what label to use */ -	    fmt_print("[0] SMI Label\n"); -	    fmt_print("[1] EFI Label\n"); -	    ioparam.io_bounds.lower = 0; -	    ioparam.io_bounds.upper = 1; -	    if (cur_label == L_TYPE_SOLARIS) -		deflt = 0; -	    else -		deflt = 1; -	    defltptr = &deflt; -	    choice = input(FIO_INT, "Specify Label type", ':', -		&ioparam, defltptr, DATA_INPUT); -	    if ((choice == 0) && (cur_label == L_TYPE_SOLARIS)) { -		goto expert_end; -	    } else if ((choice == 1) && (cur_label == L_TYPE_EFI)) { -		goto expert_end; -	    } -	    switch (choice) { -	    case 0: +		int 		choice; +		u_ioparam_t		ioparam; +		struct extvtoc	vtoc; +		struct dk_label	label; +		struct dk_gpt	*vtoc64; +		struct efi_info	efinfo; +		struct disk_type	*dptr; + +		/* Ask user what label to use */ +		fmt_print("[0] SMI Label\n"); +		fmt_print("[1] EFI Label\n"); +		ioparam.io_bounds.lower = 0; +		ioparam.io_bounds.upper = 1; +		if (cur_label == L_TYPE_SOLARIS) +			deflt = 0; +		else +			deflt = 1; +		defltptr = &deflt; +		choice = input(FIO_INT, "Specify Label type", ':', +		    &ioparam, defltptr, DATA_INPUT); +		if ((choice == 0) && (cur_label == L_TYPE_SOLARIS)) { +			goto expert_end; +		} else if ((choice == 1) && (cur_label == L_TYPE_EFI)) { +			goto expert_end; +		} +		switch (choice) { +		case 0:  		/*  		 * EFI label to SMI label  		 */  		if (cur_dtype->capacity > INFINITY) { -		    fmt_print("Warning: SMI labels only support up to 2 TB.\n"); +			fmt_print("Warning: SMI labels only support up to " +			    "2 TB.\n");  		}  		if (cur_disk->fdisk_part.systid == EFI_PMBR) { -		    fmt_print("Warning: This disk has an EFI label. Changing to" -		    " SMI label will erase all\ncurrent partitions.\n"); -		    if (check("Continue")) +			fmt_print("Warning: This disk has an EFI label. " +			    "Changing to SMI label will erase all\n" +			    "current partitions.\n"); +			if (check("Continue"))  			return (-1);  #if defined(_FIRMWARE_NEEDS_FDISK) -		    fmt_print("You must use fdisk to delete the current " +			fmt_print("You must use fdisk to delete the current "  			    "EFI partition and create a new\n"  			    "Solaris partition before you can convert the "  			    "label.\n"); -		    return (-1); +			return (-1);  #endif  		} @@ -1509,7 +1533,7 @@ c_label()  		} -	    case 1: +		case 1:  		/*  		 * SMI label to EFI label  		 */ @@ -1523,7 +1547,7 @@ c_label()  		}  		if (get_disk_info(cur_file, &efinfo) != 0) { -		    return (-1); +			return (-1);  		}  		(void) memset((char *)&label, 0, sizeof (struct dk_label));  		label.dkl_pcyl = pcyl; @@ -1536,21 +1560,21 @@ c_label()  		label.dkl_nsect = nsect;  #if defined(_SUNOS_VTOC_8)  		for (i = 0; i < NDKMAP; i++) { -		    label.dkl_map[i] = cur_parts->pinfo_map[i]; +			label.dkl_map[i] = cur_parts->pinfo_map[i];  		}  #endif			/* defined(_SUNOS_VTOC_8) */  		label.dkl_magic = DKL_MAGIC;  		label.dkl_vtoc = cur_parts->vtoc;  		if (label_to_vtoc(&vtoc, &label) == -1) { -		    return (-1); +			return (-1);  		}  		if (SMI_vtoc_to_EFI(cur_file, &vtoc64) == -1) { -		    return (-1); +			return (-1);  		}  		if (efi_write(cur_file, vtoc64) != 0) { -		    err_check(vtoc64); -		    err_print("Warning: error writing EFI.\n"); -		    return (-1); +			err_check(vtoc64); +			err_print("Warning: error writing EFI.\n"); +			return (-1);  		} else {  			cur_disk->disk_flags &= ~DSK_LABEL_DIRTY;  		} @@ -1580,7 +1604,7 @@ c_label()  		(void) copy_solaris_part(&cur_disk->fdisk_part);  		return (0); -	    } +		}  	}  expert_end: @@ -1648,7 +1672,7 @@ c_defect()  	 * display appropriate message.  	 */  	if ((cur_ops->op_ex_man == NULL) && (cur_ops->op_ex_cur == NULL) && -		(cur_ops->op_create == NULL) && (cur_ops->op_wr_cur == NULL)) { +	    (cur_ops->op_create == NULL) && (cur_ops->op_wr_cur == NULL)) {  		err_print("Controller does not support defect management\n");  		err_print("or disk supports automatic defect management.\n");  		return (-1); @@ -1667,7 +1691,8 @@ c_defect()  	if ((work_list.list == NULL) && (cur_list.list != NULL)) {  		work_list.header = cur_list.header;  		work_list.list = (struct defect_entry *)zalloc( -		    LISTSIZE(work_list.header.count) * SECSIZE); +		    deflist_size(cur_blksz, work_list.header.count) * +		    cur_blksz);  		for (i = 0; i < work_list.header.count; i++)  			*(work_list.list + i) = *(cur_list.list + i);  		work_list.flags = cur_list.flags & LIST_PGLIST; @@ -1710,6 +1735,7 @@ c_backup()  	struct	partition_info *parts, *plist;  	diskaddr_t	bn;  	int	sec, head, i; +	char	*buf;  	/*  	 * There must be a current disk type (and therefore a current disk). @@ -1736,23 +1762,26 @@ c_backup()  	 * the user is serious.  	 */  	if (cur_disk->label_type == L_TYPE_EFI) { -	    if (((cur_disk->disk_parts->etoc->efi_flags & -		EFI_GPT_PRIMARY_CORRUPT) == 0) && -		check("Disk has a primary label, still continue")) -		    return (-1); -	    fmt_print("Restoring primary label.\n"); -	    if (write_label()) { -		    err_print("Failed\n"); -		    return (-1); -	    } -	    return (0); +		if (((cur_disk->disk_parts->etoc->efi_flags & +		    EFI_GPT_PRIMARY_CORRUPT) == 0) && +		    check("Disk has a primary label, still continue")) +			return (-1); +		fmt_print("Restoring primary label.\n"); +		if (write_label()) { +			err_print("Failed\n"); +			return (-1); +		} +		return (0);  	} else if (((cur_disk->disk_flags & (DSK_LABEL | DSK_LABEL_DIRTY)) == -		DSK_LABEL) && +	    DSK_LABEL) &&  	    (check("Disk has a primary label, still continue"))) {  		return (-1);  	} + +	buf = zalloc(cur_blksz);  	fmt_print("Searching for backup labels...");  	(void) fflush(stdout); +  	/*  	 * Some disks have the backup labels in a strange place.  	 */ @@ -1770,9 +1799,12 @@ c_backup()  		 * Attempt to read it.  		 */  		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, -				1, (char *)&label, F_NORMAL, NULL)) { +		    1, buf, F_NORMAL, NULL)) {  			continue;  		} + +		(void *) memcpy((char *)&label, buf, sizeof (struct dk_label)); +  		/*  		 * Verify that it is a reasonable label.  		 */ @@ -1801,15 +1833,17 @@ c_backup()  				fmt_print("\  Unknown disk type in backup label\n");  				exit_critical(); +				free(buf);  				return (-1);  			}  			fmt_print("Backup label claims different type:\n");  			fmt_print("    <%s cyl %d alt %d hd %d sec %d>\n", -				label.dkl_asciilabel, label.dkl_ncyl, -				label.dkl_acyl, label.dkl_nhead, -				label.dkl_nsect); +			    label.dkl_asciilabel, label.dkl_ncyl, +			    label.dkl_acyl, label.dkl_nhead, +			    label.dkl_nsect);  			if (check("Continue")) {  				exit_critical(); +				free(buf);  				return (-1);  			}  			cur_dtype = dtype; @@ -1828,7 +1862,7 @@ Unknown disk type in backup label\n");  		 */  		if (parts == NULL) {  			parts = (struct partition_info *) -				zalloc(sizeof (struct partition_info)); +			    zalloc(sizeof (struct partition_info));  			plist = dtype->dtype_plist;  			if (plist == NULL)  				dtype->dtype_plist = parts; @@ -1863,22 +1897,28 @@ Unknown disk type in backup label\n");  		 */  		if (EMBEDDED_SCSI) {  			fmt_print("Restoring primary label.\n"); -			if (write_label()) +			if (write_label()) { +				free(buf);  				return (-1); +			}  		} else {  			fmt_print("Restoring primary label and defect list.\n"); -			if (write_label()) +			if (write_label()) { +				free(buf);  				return (-1); +			}  			if (cur_list.list != NULL)  				write_deflist(&cur_list);  		}  		fmt_print("\n"); +		free(buf);  		return (0);  	}  	/*  	 * If we didn't find any backup labels, say so.  	 */  	fmt_print("not found.\n\n"); +	free(buf);  	return (0);  } @@ -1894,8 +1934,8 @@ c_verify_efi()  	status = read_efi_label(cur_file, &efi_info);  	if (status != 0) { -	    err_print("Warning: Could not read label.\n"); -	    return (-1); +		err_print("Warning: Could not read label.\n"); +		return (-1);  	}  	if (cur_parts->etoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {  		err_print("Reading the primary EFI GPT label "); @@ -1906,20 +1946,20 @@ c_verify_efi()  	tmp_pinfo.etoc = efi_info.e_parts;  	fmt_print("\n");  	if (cur_parts->etoc->efi_parts[8].p_name) { -	    fmt_print("Volume name = <%8s>\n", -		cur_parts->etoc->efi_parts[8].p_name); +		fmt_print("Volume name = <%8s>\n", +		    cur_parts->etoc->efi_parts[8].p_name);  	} else { -	    fmt_print("Volume name = <        >\n"); +		fmt_print("Volume name = <        >\n");  	}  	fmt_print("ascii name  = ");  	print_efi_string(efi_info.vendor, efi_info.product,  	    efi_info.revision, efi_info.capacity);  	fmt_print("\n"); -	fmt_print("bytes/sector	=  %d\n", DEV_BSIZE); +	fmt_print("bytes/sector	=  %d\n", cur_blksz);  	fmt_print("sectors = %llu\n", cur_parts->etoc->efi_last_lba);  	fmt_print("accessible sectors = %llu\n", -		cur_parts->etoc->efi_last_u_lba); +	    cur_parts->etoc->efi_last_u_lba);  	print_map(&tmp_pinfo);  	return (0); @@ -1941,6 +1981,7 @@ c_verify()  	int	p_label_found = 0;  	int	b_label_found = 0;  	char	id_str[128]; +	char	*buf;  	/*  	 * There must be a current disk type (and therefore a current disk). @@ -1966,7 +2007,7 @@ c_verify()  	 * Branch off here if the disk is EFI labelled.  	 */  	if (cur_label == L_TYPE_EFI) { -	    return (c_verify_efi()); +		return (c_verify_efi());  	}  	/*  	 * Attempt to read the primary label. @@ -1985,7 +2026,7 @@ c_verify()  		(void) strncpy(id_str, p_label.dkl_asciilabel, 128);  		if ((!checklabel((struct dk_label *)&p_label)) || -			(trim_id(p_label.dkl_asciilabel))) { +		    (trim_id(p_label.dkl_asciilabel))) {  			err_print("\  Warning: Primary label appears to be corrupt.\n");  			p_label_bad = 1; @@ -1995,10 +2036,10 @@ Warning: Primary label appears to be corrupt.\n");  			 * Make sure it matches current label  			 */  			if ((!dtype_match(&p_label, cur_dtype)) || -				(!parts_match(&p_label, cur_parts))) { +			    (!parts_match(&p_label, cur_parts))) {  				err_print("\  Warning: Primary label on disk appears to be different from\ncurrent label.\n"); -			p_label_bad = 1; +				p_label_bad = 1;  			}  		}  	} @@ -2011,6 +2052,8 @@ Warning: Primary label on disk appears to be different from\ncurrent label.\n");  		head = 2;  	else  		head = nhead - 1; + +	buf = zalloc(cur_blksz);  	/*  	 * Loop through each copy of the backup label.  	 */ @@ -2021,8 +2064,12 @@ Warning: Primary label on disk appears to be different from\ncurrent label.\n");  		 * Attempt to read it.  		 */  		if ((*cur_ops->op_rdwr)(DIR_READ, cur_file, bn, -				1, (char *)&b_label, F_NORMAL, NULL)) +		    1, buf, F_NORMAL, NULL))  			continue; + +		(void *) memcpy((char *)&b_label, buf, +		    sizeof (struct dk_label)); +  		/*  		 * Verify that it is a reasonable label.  		 */ @@ -2043,11 +2090,11 @@ Warning: Primary label on disk appears to be different from\ncurrent label.\n");  		 */  		if (p_label_found) {  			if ((strcmp(b_label.dkl_asciilabel, -				p_label.dkl_asciilabel) != 0) || -				(b_label.dkl_ncyl != p_label.dkl_ncyl) || -				(b_label.dkl_acyl != p_label.dkl_acyl) || -				(b_label.dkl_nhead != p_label.dkl_nhead) || -				(b_label.dkl_nsect != p_label.dkl_nsect)) { +			    p_label.dkl_asciilabel) != 0) || +			    (b_label.dkl_ncyl != p_label.dkl_ncyl) || +			    (b_label.dkl_acyl != p_label.dkl_acyl) || +			    (b_label.dkl_nhead != p_label.dkl_nhead) || +			    (b_label.dkl_nsect != p_label.dkl_nsect)) {  				b_label_bad = 1;  			} else {  				for (i = 0; i < NDKMAP; i++) { @@ -2062,13 +2109,16 @@ Warning: Primary label on disk appears to be different from\ncurrent label.\n");  #elif defined(_SUNOS_VTOC_16)  					if ((b_label.dkl_vtoc.v_part[i].p_tag != -					p_label.dkl_vtoc.v_part[i].p_tag) || -					(b_label.dkl_vtoc.v_part[i].p_flag != -					p_label.dkl_vtoc.v_part[i].p_flag) || -					(b_label.dkl_vtoc.v_part[i].p_start != -					p_label.dkl_vtoc.v_part[i].p_start) || -					(b_label.dkl_vtoc.v_part[i].p_size != -					p_label.dkl_vtoc.v_part[i].p_size)) { +					    p_label.dkl_vtoc.v_part[i].p_tag) || +					    (b_label.dkl_vtoc.v_part[i].p_flag +					    != p_label.dkl_vtoc.v_part[i]. +					    p_flag) || +					    (b_label.dkl_vtoc.v_part[i].p_start +					    != p_label.dkl_vtoc.v_part[i]. +					    p_start) || +					    (b_label.dkl_vtoc.v_part[i].p_size +					    != p_label.dkl_vtoc.v_part[i]. +					    p_size)) {  						b_label_bad = 1;  						break;  					} @@ -2104,6 +2154,7 @@ Warning: Check the current partitioning and 'label' the disk or use the\n\  		fmt_print("\nBackup label contents:\n");  		label = &b_label;  	} else { +		free(buf);  		return (0);  	} @@ -2119,9 +2170,9 @@ Warning: Check the current partitioning and 'label' the disk or use the\n\  #elif defined(_SUNOS_VTOC_16)  		tmp_pinfo.pinfo_map[i].dkl_cylno = -			label->dkl_vtoc.v_part[i].p_start / spc(); +		    label->dkl_vtoc.v_part[i].p_start / spc();  		tmp_pinfo.pinfo_map[i].dkl_nblk = -			label->dkl_vtoc.v_part[i].p_size; +		    label->dkl_vtoc.v_part[i].p_size;  #else  #error No VTOC layout defined.  #endif /* defined(_SUNOS_VTOC_8) */ @@ -2143,6 +2194,7 @@ Warning: Check the current partitioning and 'label' the disk or use the\n\  	fmt_print("nsect       = %4d\n", label->dkl_nsect);  	print_map(&tmp_pinfo); +	free(buf);  	return (0);  } @@ -2323,9 +2375,9 @@ being used for swapping.\n\n");  	bcopy(volname, cur_disk->v_volume, min((int)strlen(volname),  	    LEN_DKL_VVOL));  	if (cur_label == L_TYPE_EFI) { -	    bzero(cur_parts->etoc->efi_parts[8].p_name, LEN_DKL_VVOL); -	    bcopy(volname, cur_parts->etoc->efi_parts[8].p_name, -		LEN_DKL_VVOL); +		bzero(cur_parts->etoc->efi_parts[8].p_name, LEN_DKL_VVOL); +		bcopy(volname, cur_parts->etoc->efi_parts[8].p_name, +		    LEN_DKL_VVOL);  	}  	/*  	 * Write the labels out (this will also notify unix) and diff --git a/usr/src/cmd/format/menu_defect.c b/usr/src/cmd/format/menu_defect.c index 9a31134ec9..55388253ae 100644 --- a/usr/src/cmd/format/menu_defect.c +++ b/usr/src/cmd/format/menu_defect.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -92,7 +92,8 @@ d_restore()  	if (cur_list.list != NULL) {  		work_list.header = cur_list.header;  		work_list.list = (struct defect_entry *)zalloc( -		    LISTSIZE(work_list.header.count) * SECSIZE); +		    deflist_size(cur_blksz, work_list.header.count) * +		    cur_blksz);  		for (i = 0; i < work_list.header.count; i++)  			*(work_list.list + i) = *(cur_list.list + i);  	} @@ -230,7 +231,7 @@ and may take a long while. Continue"))  				fmt_print("Extraction complete.\n");  				fmt_print(  "Working list updated, total of %d defects.\n\n", -				work_list.header.count); +				    work_list.header.count);  			} else {  				fmt_print("Extraction failed.\n\n");  			} @@ -277,7 +278,7 @@ d_add()  	ioparam.io_bounds.lower = 0;  	ioparam.io_bounds.upper = 1;  	type = input(FIO_INT, "Select input format (enter its number)", ':', -		&ioparam, &deflt, DATA_INPUT); +	    &ioparam, &deflt, DATA_INPUT);  	fmt_print("\nEnter Control-C to terminate.\n");  loop:  	if (type) { @@ -288,9 +289,9 @@ loop:  		def.bfi = def.nbits = UNKNOWN;  		ioparam.io_bounds.lower = 0;  		if (cur_disk->label_type == L_TYPE_SOLARIS) { -		    ioparam.io_bounds.upper = physsects() - 1; +			ioparam.io_bounds.upper = physsects() - 1;  		} else { -		    ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba; +			ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;  		}  		bn = input(FIO_BN, "Enter defective block number", ':',  		    &ioparam, (int *)NULL, DATA_INPUT); @@ -349,7 +350,7 @@ loop:  		work_list.header.magicno = (uint_t)DEFECT_MAGIC;  		work_list.header.count = 0;  		work_list.list = (struct defect_entry *)zalloc( -		    LISTSIZE(0) * SECSIZE); +		    deflist_size(cur_blksz, 0) * cur_blksz);  	}  	/*  	 * Add the defect to the working list. @@ -420,9 +421,11 @@ d_delete()  	 * If the size of the list in sectors has changed, reallocate  	 * the list to shrink it appropriately.  	 */ -	if (LISTSIZE(count - 1) < LISTSIZE(count)) +	if (deflist_size(cur_blksz, count - 1) < +	    deflist_size(cur_blksz, count))  		work_list.list = (struct defect_entry *)rezalloc( -		    (void *)work_list.list, LISTSIZE(count - 1) * SECSIZE); +		    (void *)work_list.list, +		    deflist_size(cur_blksz, count - 1) * cur_blksz);  	/*  	 * Decrement the defect count.  	 */ @@ -488,7 +491,7 @@ d_print()  		 * before going on.  		 */  		if (one_line || -			(!nomore && ((i + 1) % (tty_lines - 1) == 0))) { +		    (!nomore && ((i + 1) % (tty_lines - 1) == 0))) {  			/*  			 * Get the next character.  			 */ @@ -574,8 +577,8 @@ d_dump()  	 * Print a header containing the magic number, count, and checksum.  	 */  	(void) fprintf(fptr, "0x%08x%8d  0x%08x\n", -		work_list.header.magicno, -		work_list.header.count, work_list.header.cksum); +	    work_list.header.magicno, +	    work_list.header.count, work_list.header.cksum);  	/*  	 * Loop through each defect in the working list.  Write the  	 * defect info to the defect file. @@ -583,8 +586,8 @@ d_dump()  	for (i = 0; i < work_list.header.count; i++) {  		dptr = work_list.list + i;  		(void) fprintf(fptr, "%4d%8d%7d%8d%8d%8d\n", -			i+1, dptr->cyl, dptr->head, -			dptr->bfi, dptr->nbits, dptr->sect); +		    i+1, dptr->cyl, dptr->head, +		    dptr->bfi, dptr->nbits, dptr->sect);  	}  	fmt_print("defect file updated, total of %d defects.\n", i);  	/* @@ -663,13 +666,13 @@ d_load()  	 * Scan in the header.  	 */  	items = fscanf(fptr, "0x%x%d  0x%x\n", &magicno, -		&count, (uint_t *)&cksum); +	    &count, (uint_t *)&cksum);  	/*  	 * If the header is wrong, this isn't a good defect file.  	 */  	if (items != 3 || count < 0 ||  	    (magicno != (uint_t)DEFECT_MAGIC && -				magicno != (uint_t)NO_CHECKSUM)) { +	    magicno != (uint_t)NO_CHECKSUM)) {  		err_print("Defect file is corrupted.\n");  		status = -1;  		goto out; @@ -690,8 +693,8 @@ d_load()  	/*  	 * Allocate space for the new list.  	 */ -	work_list.list = (struct defect_entry *)zalloc(LISTSIZE(count) * -	    SECSIZE); +	work_list.list = (struct defect_entry *)zalloc( +	    deflist_size(cur_blksz, count) * cur_blksz);  	/*  	 * Mark the working list dirty since we are modifying it.  	 */ @@ -806,14 +809,14 @@ commit_list()  		work_list.header.magicno = (uint_t)DEFECT_MAGIC;  		work_list.header.count = 0;  		work_list.list = (struct defect_entry *)zalloc( -		    LISTSIZE(0) * SECSIZE); +		    deflist_size(cur_blksz, 0) * cur_blksz);  	}  	/*  	 * Copy the working list into the current list.  	 */  	cur_list.header = work_list.header;  	cur_list.list = (struct defect_entry *)zalloc( -	    LISTSIZE(cur_list.header.count) * SECSIZE); +	    deflist_size(cur_blksz, cur_list.header.count) * cur_blksz);  	for (i = 0; i < cur_list.header.count; i++)  		*(cur_list.list + i) = *(work_list.list + i);  	/* diff --git a/usr/src/cmd/format/menu_fdisk.c b/usr/src/cmd/format/menu_fdisk.c index 4ebadee5ab..e1affd636a 100644 --- a/usr/src/cmd/format/menu_fdisk.c +++ b/usr/src/cmd/format/menu_fdisk.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -274,11 +274,11 @@ open_cur_file(int mode)  	char	pbuf[MAXPATHLEN];  	switch (mode) { -	    case FD_USE_P0_PATH: +	case FD_USE_P0_PATH:  		(void) get_pname(&pbuf[0]);  		dkpath = pbuf;  		break; -	    case FD_USE_CUR_DISK_PATH: +	case FD_USE_CUR_DISK_PATH:  		if (cur_disk->fdisk_part.systid == SUNIXOS ||  		    cur_disk->fdisk_part.systid == SUNIXOS2) {  			(void) get_sname(&pbuf[0]); @@ -287,7 +287,7 @@ open_cur_file(int mode)  			dkpath = cur_disk->disk_path;  		}  		break; -	    default: +	default:  		err_print("Error: Invalid mode option for opening cur_file\n");  		fullabort();  	} @@ -388,7 +388,7 @@ update_cur_parts()  	for (i = 0; i < NDKMAP; i++) {  #if defined(_SUNOS_VTOC_16)  		if (cur_parts->vtoc.v_part[i].p_tag && -			cur_parts->vtoc.v_part[i].p_tag != V_ALTSCTR) { +		    cur_parts->vtoc.v_part[i].p_tag != V_ALTSCTR) {  			cur_parts->vtoc.v_part[i].p_start = 0;  			cur_parts->vtoc.v_part[i].p_size = 0; @@ -396,9 +396,9 @@ update_cur_parts()  			cur_parts->pinfo_map[i].dkl_nblk = 0;  			cur_parts->pinfo_map[i].dkl_cylno = 0;  			cur_parts->vtoc.v_part[i].p_tag = -				default_vtoc_map[i].p_tag; +			    default_vtoc_map[i].p_tag;  			cur_parts->vtoc.v_part[i].p_flag = -				default_vtoc_map[i].p_flag; +			    default_vtoc_map[i].p_flag;  #if defined(_SUNOS_VTOC_16)  		}  #endif @@ -412,14 +412,14 @@ update_cur_parts()  	cur_parts->pinfo_map[I_PARTITION].dkl_nblk = spc();  	cur_parts->pinfo_map[I_PARTITION].dkl_cylno = 0;  	cur_parts->vtoc.v_part[C_PARTITION].p_start = -		cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect; +	    cur_parts->pinfo_map[C_PARTITION].dkl_cylno * nhead * nsect;  	cur_parts->vtoc.v_part[C_PARTITION].p_size = -		cur_parts->pinfo_map[C_PARTITION].dkl_nblk; +	    cur_parts->pinfo_map[C_PARTITION].dkl_nblk;  	cur_parts->vtoc.v_part[I_PARTITION].p_start = -			cur_parts->pinfo_map[I_PARTITION].dkl_cylno; +	    cur_parts->pinfo_map[I_PARTITION].dkl_cylno;  	cur_parts->vtoc.v_part[I_PARTITION].p_size = -			cur_parts->pinfo_map[I_PARTITION].dkl_nblk; +	    cur_parts->pinfo_map[I_PARTITION].dkl_nblk;  #endif	/* defined(_SUNOS_VTOC_16) */  	parts = cur_dtype->dtype_plist; @@ -438,18 +438,33 @@ get_solaris_part(int fd, struct ipart *ipart)  	int		i;  	struct ipart	ip;  	int		status; +	char		*mbr;  	char		*bootptr;  	struct dk_label	update_label;  	(void) lseek(fd, 0, 0); -	status = read(fd, (caddr_t)&boot_sec, NBPSCTR); -	if (status != NBPSCTR) { +	/* +	 * We may get mbr of different size, but the first 512 bytes +	 * are valid information. +	 */ +	mbr = malloc(cur_blksz); +	if (mbr == NULL) { +		err_print("No memory available.\n"); +		return (-1); +	} +	status = read(fd, mbr, cur_blksz); + +	if (status != cur_blksz) {  		err_print("Bad read of fdisk partition. Status = %x\n", status);  		err_print("Cannot read fdisk partition information.\n"); +		free(mbr);  		return (-1);  	} +	(void) memcpy(&boot_sec, mbr, sizeof (struct mboot)); +	free(mbr); +  	for (i = 0; i < FD_NUMPART; i++) {  		int	ipc; @@ -478,8 +493,8 @@ get_solaris_part(int fd, struct ipart *ipart)  #ifdef DEBUG  			else {  				err_print("Critical geometry values are zero:\n" -					"\tnhead = %d; nsect = %d\n", nhead, -					nsect); +				    "\tnhead = %d; nsect = %d\n", nhead, +				    nsect);  			}  #endif /* DEBUG */ @@ -555,6 +570,7 @@ get_solaris_part(int fd, struct ipart *ipart)  		nsect = cur_dtype->dtype_nsect;  		nhead = cur_dtype->dtype_nhead;  	} +  	return (0);  } @@ -565,6 +581,7 @@ copy_solaris_part(struct ipart *ipart)  	int		status, i, fd;  	struct mboot	mboot; +	char		*mbr;  	struct ipart	ip;  	char		buf[MAXPATHLEN];  	char		*bootptr; @@ -574,7 +591,7 @@ copy_solaris_part(struct ipart *ipart)  	if (stat(buf, &statbuf) == -1 ||  	    !S_ISCHR(statbuf.st_mode) ||  	    ((cur_label == L_TYPE_EFI) && -		(cur_disk->disk_flags & DSK_LABEL_DIRTY))) { +	    (cur_disk->disk_flags & DSK_LABEL_DIRTY))) {  		/*  		 * Make sure to reset solaris_offset to zero if it is  		 *	previously set by a selected disk that @@ -595,14 +612,26 @@ copy_solaris_part(struct ipart *ipart)  		return (-1);  	} -	status = read(fd, (caddr_t)&mboot, sizeof (struct mboot)); +	/* +	 * We may get mbr of different size, but the first 512 bytes +	 * are valid information. +	 */ +	mbr = malloc(cur_blksz); +	if (mbr == NULL) { +		err_print("No memory available.\n"); +		return (-1); +	} +	status = read(fd, mbr, cur_blksz); -	if (status != sizeof (struct mboot)) { +	if (status != cur_blksz) {  		err_print("Bad read of fdisk partition.\n");  		(void) close(fd); +		free(mbr);  		return (-1);  	} +	(void) memcpy(&mboot, mbr, sizeof (struct mboot)); +  	for (i = 0; i < FD_NUMPART; i++) {  		int	ipc; @@ -631,8 +660,8 @@ copy_solaris_part(struct ipart *ipart)  #ifdef DEBUG  			else {  				err_print("Critical geometry values are zero:\n" -					"\tnhead = %d; nsect = %d\n", nhead, -					nsect); +				    "\tnhead = %d; nsect = %d\n", nhead, +				    nsect);  			}  #endif /* DEBUG */ @@ -641,8 +670,8 @@ copy_solaris_part(struct ipart *ipart)  	}  	(void) close(fd); +	free(mbr);  	return (0); -  }  #if defined(_FIRMWARE_NEEDS_FDISK) @@ -652,24 +681,36 @@ auto_solaris_part(struct dk_label *label)  	int		status, i, fd;  	struct mboot	mboot; +	char		*mbr;  	struct ipart	ip;  	char		*bootptr;  	char		pbuf[MAXPATHLEN]; -  	(void) get_pname(&pbuf[0]);  	if ((fd = open_disk(pbuf, O_RDONLY)) < 0) {  		err_print("Error: can't open selected disk '%s'.\n", pbuf);  		return (-1);  	} -	status = read(fd, (caddr_t)&mboot, sizeof (struct mboot)); +	/* +	 * We may get mbr of different size, but the first 512 bytes +	 * are valid information. +	 */ +	mbr = malloc(cur_blksz); +	if (mbr == NULL) { +		err_print("No memory available.\n"); +		return (-1); +	} +	status = read(fd, mbr, cur_blksz); -	if (status != sizeof (struct mboot)) { +	if (status != cur_blksz) {  		err_print("Bad read of fdisk partition.\n"); +		free(mbr);  		return (-1);  	} +	(void) memcpy(&mboot, mbr, sizeof (struct mboot)); +  	for (i = 0; i < FD_NUMPART; i++) {  		int	ipc; @@ -697,11 +738,11 @@ auto_solaris_part(struct dk_label *label)  #ifdef DEBUG  			else {  				err_print("Critical label fields aren't " -					"non-zero:\n" -					"\tlabel->dkl_nhead = %d; " -					"label->dkl_nsect = " -					"%d\n", label->dkl_nhead, -					label->dkl_nsect); +				    "non-zero:\n" +				    "\tlabel->dkl_nhead = %d; " +				    "label->dkl_nsect = " +				    "%d\n", label->dkl_nhead, +				    label->dkl_nsect);  			}  #endif /* DEBUG */ @@ -711,7 +752,7 @@ auto_solaris_part(struct dk_label *label)  	}  	(void) close(fd); - +	free(mbr);  	return (0);  }  #endif	/* defined(_FIRMWARE_NEEDS_FDISK) */ @@ -739,9 +780,9 @@ good_fdisk()  	} else {  		err_print("WARNING - ");  		err_print("This disk may be in use by an application " -			"that has\n\t  modified the fdisk table. Ensure " -			"that this disk is\n\t  not currently in use " -			"before proceeding to use fdisk.\n"); +		    "that has\n\t  modified the fdisk table. Ensure " +		    "that this disk is\n\t  not currently in use " +		    "before proceeding to use fdisk.\n");  		return (0);  	}  } diff --git a/usr/src/cmd/format/misc.c b/usr/src/cmd/format/misc.c index f148cc3115..55ca2e80a8 100644 --- a/usr/src/cmd/format/misc.c +++ b/usr/src/cmd/format/misc.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -867,7 +867,7 @@ bn2mb(uint64_t nblks)  	float	n;  	n = (float)nblks / 1024.0; -	return ((n / 1024.0) * DEV_BSIZE); +	return ((n / 1024.0) * cur_blksz);  } @@ -876,7 +876,7 @@ mb2bn(float mb)  {  	diskaddr_t	n; -	n = (diskaddr_t)(mb * 1024.0 * (1024.0 / DEV_BSIZE)); +	n = (diskaddr_t)(mb * 1024.0 * (1024.0 / cur_blksz));  	return (n);  } @@ -886,7 +886,7 @@ bn2gb(uint64_t nblks)  	float	n;  	n = (float)nblks / (1024.0 * 1024.0); -	return ((n/1024.0) * DEV_BSIZE); +	return ((n/1024.0) * cur_blksz);  } @@ -896,7 +896,7 @@ bn2tb(uint64_t nblks)  	float	n;  	n = (float)nblks / (1024.0 * 1024.0 * 1024.0); -	return ((n/1024.0) * DEV_BSIZE); +	return ((n/1024.0) * cur_blksz);  }  diskaddr_t @@ -904,7 +904,7 @@ gb2bn(float gb)  {  	diskaddr_t	n; -	n = (diskaddr_t)(gb * 1024.0 * 1024.0 * (1024.0 / DEV_BSIZE)); +	n = (diskaddr_t)(gb * 1024.0 * 1024.0 * (1024.0 / cur_blksz));  	return (n);  } diff --git a/usr/src/cmd/format/prompts.c b/usr/src/cmd/format/prompts.c index ce87f06349..e6ef368bbb 100644 --- a/usr/src/cmd/format/prompts.c +++ b/usr/src/cmd/format/prompts.c @@ -2,9 +2,8 @@   * CDDL HEADER START   *   * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License").  You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License.   *   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE   * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,10 @@   * CDDL HEADER END   */  /* - * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ -#pragma ident	"%Z%%M%	%I%	%E% SMI" -  /*   * This file contains functions to prompt the user for various   * disk characteristics.  By isolating these into functions, @@ -196,7 +193,7 @@ get_bpt(n_sects, options)  		*options |= SUP_BPT;  		ioparam.io_bounds.lower = 1;  		ioparam.io_bounds.upper = INFINITY; -		deflt = n_sects * SECSIZE; +		deflt = n_sects * cur_blksz;  		return (input(FIO_INT, "Enter number of bytes/track",  				':', &ioparam, &deflt, DATA_INPUT));  	} @@ -435,7 +432,7 @@ get_bps()  		ioparam.io_bounds.upper = MAX_BPS;  		deflt = AVG_BPS;  		return (input(FIO_INT, "Enter bytes per sector", -			':', &ioparam, &deflt, DATA_INPUT)); +		    ':', &ioparam, &deflt, DATA_INPUT));  	}  	return (0); diff --git a/usr/src/cmd/format/startup.c b/usr/src/cmd/format/startup.c index 99aa8d9d34..fd8e035688 100644 --- a/usr/src/cmd/format/startup.c +++ b/usr/src/cmd/format/startup.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -1607,6 +1607,12 @@ add_device_to_disklist(char *devname, char *devpath)  		}  	} +	if (ioctl(search_file, DKIOCGMEDIAINFO, &mediainfo) == -1) { +		cur_blksz = DEV_BSIZE; +	} else { +		cur_blksz = mediainfo.dki_lbsize; +	} +  	/*  	 * If the type of disk is one we don't know about,  	 * add it to the list. @@ -1708,8 +1714,11 @@ add_device_to_disklist(char *devname, char *devpath)  	 * generic check for reserved disks here, including intel disks.  	 */  	if (dkinfo.dki_ctype == DKC_SCSI_CCS) { +		char	*first_sector; + +		first_sector = zalloc(cur_blksz);  		i = scsi_rdwr(DIR_READ, search_file, (diskaddr_t)0, -		    1, (char *)&search_label, F_SILENT, NULL); +		    1, first_sector, F_SILENT, NULL);  		switch (i) {  		case DSK_RESERVED:  			access_flags |= DSK_RESERVED; @@ -1720,6 +1729,7 @@ add_device_to_disklist(char *devname, char *devpath)  		default:  			break;  		} +		free(first_sector);  	}  #endif /* defined(sparc) */ @@ -1751,6 +1761,11 @@ add_device_to_disklist(char *devname, char *devpath)  	search_disk->disk_name = alloc_string(devname);  	search_disk->disk_path = alloc_string(devpath); +	/* +	 * Remember the lba size of the disk +	 */ +	search_disk->disk_lbasize = cur_blksz; +  	(void) strcpy(x86_devname, devname);  	/* diff --git a/usr/src/cmd/fs.d/fsck.c b/usr/src/cmd/fs.d/fsck.c index 61e0da1622..18e3fe332b 100644 --- a/usr/src/cmd/fs.d/fsck.c +++ b/usr/src/cmd/fs.d/fsck.c @@ -19,16 +19,13 @@   * CDDL HEADER END   */  /* - * Copyright 2007 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */  /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/  /*	  All Rights Reserved  	*/ - -#pragma ident	"%Z%%M%	%I%	%E% SMI" -  #include	<stdio.h>  #include	<errno.h>  #include	<limits.h> @@ -39,9 +36,12 @@  #include	<sys/wait.h>  #include	<sys/vfstab.h>  #include	<sys/mntent.h> +#include	<sys/sysmacros.h>  #include	<locale.h>  #include	<libintl.h> +#include	<sys/dkio.h> +#define	DEV_BSIZE	512  #define	ARGV_MAX	16  #define	FSTYPE_MAX	8  #define	VFS_PATH	"/usr/lib/fs" @@ -217,10 +217,13 @@ main(int argc, char *argv[])  	int	questflg = 0, Fflg = 0, Vflg = 0, sanity = 0;  	char	*subopt;  	FILE	*fd = NULL; +	int	devfd;  	struct vfstab	vget, vref; +	struct dk_minfo dkminfo;  	int preencnt = 0;  	struct devlist *dp, *devs = NULL;  	int status; +	uint_t lbs;  	(void) setlocale(LC_ALL, "");  #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */ @@ -408,6 +411,7 @@ main(int argc, char *argv[])  				myname);  			exit(1);  		} +  		while (optind < argc) {  			/*  			 * If "-F FStype" is specified, use that fs type. @@ -464,6 +468,32 @@ try_again:  				case FSCKDEV:  					vref.vfs_fsckdev = argv[optind]; + +					/* +					 * Check the media sector size +					 */ +					if (((devfd = open(vref.vfs_fsckdev, +					    O_RDWR)) >= 0) && (ioctl(devfd, +					    DKIOCGMEDIAINFO, &dkminfo) != +					    -1)) { +						lbs =  dkminfo.dki_lbsize; +						if (lbs != 0 && ISP2(lbs / +						    DEV_BSIZE) && +						    lbs != DEV_BSIZE) { +							fprintf(stderr, +							    gettext("The device" +							    " sector size is" +							    " not supported by" +							    " fsck\n")); +							(void) close(devfd); +							exit(1); +						} +					} + +					if (devfd >= 0) { +						(void) close(devfd); +					} +  					if ((ret = mygetvfsany(fd, &vget,  						&vref)) == -1 ||  						vget.vfs_fstype == NULL) { diff --git a/usr/src/cmd/fs.d/pcfs/mkfs/mkfs.c b/usr/src/cmd/fs.d/pcfs/mkfs/mkfs.c index a811306f74..f335a2eabc 100644 --- a/usr/src/cmd/fs.d/pcfs/mkfs/mkfs.c +++ b/usr/src/cmd/fs.d/pcfs/mkfs/mkfs.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -2190,6 +2190,7 @@ open_and_examine(char *dn, bpb_t *wbpb)  	char *actualdisk = NULL;  	char *suffix = NULL;  	int fd; +	struct dk_minfo dkminfo;  	if (Verbose)  		(void) printf(gettext("Opening destination device/file.\n")); @@ -2210,6 +2211,21 @@ open_and_examine(char *dn, bpb_t *wbpb)  	}  	/* +	 * Check the media sector size +	 */ +	if (ioctl(fd, DKIOCGMEDIAINFO, &dkminfo) != -1) { +		if (dkminfo.dki_lbsize != 0 && +		    ISP2(dkminfo.dki_lbsize / DEV_BSIZE) && +		    dkminfo.dki_lbsize != DEV_BSIZE) { +			(void) fprintf(stderr, +			    gettext("The device sector size %u is not " +			    "supported by pcfs!\n"), dkminfo.dki_lbsize); +			(void) close(fd); +			exit(1); +		} +	} + +	/*  	 * Find appropriate partition if we were requested to do so.  	 */  	if (suffix && !(seek_partn(fd, suffix, wbpb, &ignored))) { @@ -2240,6 +2256,7 @@ open_and_seek(char *dn, bpb_t *wbpb, off64_t *seekto)  	struct fd_char fdchar;  	struct dk_geom dg;  	struct stat di; +	struct dk_minfo	dkminfo;  	char *actualdisk = NULL;  	char *suffix = NULL;  	int fd; @@ -2308,6 +2325,21 @@ open_and_seek(char *dn, bpb_t *wbpb, off64_t *seekto)  	}  	/* +	 * Check the media sector size +	 */ +	if (ioctl(fd, DKIOCGMEDIAINFO, &dkminfo) != -1) { +		if (dkminfo.dki_lbsize != 0 && +		    ISP2(dkminfo.dki_lbsize / DEV_BSIZE) && +		    dkminfo.dki_lbsize != DEV_BSIZE) { +			(void) fprintf(stderr, +			    gettext("The device sector size %u is not " +			    "supported by pcfs!\n"), dkminfo.dki_lbsize); +			(void) close(fd); +			exit(1); +		} +	} + +	/*  	 * Find appropriate partition if we were requested to do so.  	 */  	if (suffix && !(seek_partn(fd, suffix, wbpb, seekto))) { diff --git a/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c b/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c index ee228a3c3a..afbc770565 100644 --- a/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c +++ b/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -31,8 +31,6 @@   * under license from the Regents of the University of California.   */ -#pragma ident	"%Z%%M%	%I%	%E% SMI" -  /*   * make file system for udfs (UDF - ISO13346)   * @@ -298,7 +296,7 @@ main(int32_t argc, int8_t *argv[])  	if ((temp_secsz = get_bsize()) != 0) {  		sectorsize = temp_secsz;  	} - +	  	/* Get old file system information */  	isfs = readvolseq(); @@ -1337,6 +1335,7 @@ get_bsize()  {  	struct dk_cinfo info;  	struct fd_char fd_char; +	struct dk_minfo dkminfo;  	if (ioctl(fso, DKIOCINFO, &info) < 0) {  		perror("mkfs DKIOCINFO "); @@ -1350,6 +1349,18 @@ get_bsize()  		case DKC_CDROM :  			return (2048);  		case DKC_SCSI_CCS : +			if (ioctl(fso, DKIOCGMEDIAINFO, &dkminfo) != -1) { +				if (dkminfo.dki_lbsize != 0 && +				    POWEROF2(dkminfo.dki_lbsize / DEV_BSIZE) && +				    dkminfo.dki_lbsize != DEV_BSIZE) { +					fprintf(stderr, +					    gettext("The device sector size " +					    "%u is not supported by udfs!\n"), +					    dkminfo.dki_lbsize); +					(void) close(fso); +					exit(1); +				} +			}  			/* FALLTHROUGH */  		case DKC_INTEL82072 :  			/* FALLTHROUGH */ diff --git a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c index de6f6bc3e6..5fe8d43b75 100644 --- a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c +++ b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c @@ -19,7 +19,7 @@   * CDDL HEADER END   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -632,6 +632,7 @@ main(int argc, char *argv[])  	struct statvfs64 fs;  	struct dk_geom dkg;  	struct dk_cinfo dkcinfo; +	struct dk_minfo dkminfo;  	char pbuf[sizeof (uint64_t) * 3 + 1];  	char *tmpbuf;  	int width, plen; @@ -1504,6 +1505,21 @@ retry_alternate_logic:  	}  	/* +	 * Check the media sector size +	 */ +	if (ioctl(fso, DKIOCGMEDIAINFO, &dkminfo) != -1) { +		if (dkminfo.dki_lbsize != 0 && +		    POWEROF2(dkminfo.dki_lbsize / DEV_BSIZE) && +		    dkminfo.dki_lbsize != DEV_BSIZE) { +			fprintf(stderr, +			    gettext("The device sector size %u is not " +			    "supported by ufs!\n"), dkminfo.dki_lbsize); +			(void) close(fso); +			exit(1); +		} +	} + +	/*  	 * seed random # generator (for ic_generation)  	 */  #ifdef MKFS_DEBUG diff --git a/usr/src/lib/libefi/common/rdwr_efi.c b/usr/src/lib/libefi/common/rdwr_efi.c index 3a335cfc94..31eb3d3f61 100644 --- a/usr/src/lib/libefi/common/rdwr_efi.c +++ b/usr/src/lib/libefi/common/rdwr_efi.c @@ -185,6 +185,7 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc)  	vptr->efi_last_lba = capacity - 1;  	vptr->efi_altern_lba = capacity -1;  	vptr->efi_last_u_lba = vptr->efi_last_lba - nblocks; +  	(void) uuid_generate((uchar_t *)&uuid);  	UUID_LE_CONVERT(vptr->efi_disk_uguid, uuid);  	return (0); @@ -437,7 +438,6 @@ efi_read(int fd, struct dk_gpt *vtoc)  			vtoc->efi_flags |= EFI_GPT_PRIMARY_CORRUPT;  			vtoc->efi_nparts =  			    LE_32(efi->efi_gpt_NumberOfPartitionEntries); -  			/*  			 * Partition tables are between backup GPT header  			 * table and ParitionEntryLBA (the starting LBA of @@ -446,7 +446,9 @@ efi_read(int fd, struct dk_gpt *vtoc)  			 * dk_ioc.dki_data, we try to get GUID partition  			 * entry array here.  			 */ -			dk_ioc.dki_data++; +			/* LINTED */ +			dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data +			    + disk_info.dki_lbsize);  			if (legacy_label)  				dk_ioc.dki_length = disk_info.dki_capacity - 1 -  				    dk_ioc.dki_lba; @@ -468,7 +470,9 @@ efi_read(int fd, struct dk_gpt *vtoc)  	} else if (rval == 0) {  		dk_ioc.dki_lba = LE_64(efi->efi_gpt_PartitionEntryLBA); -		dk_ioc.dki_data++; +		/* LINTED */ +		dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data +		    + disk_info.dki_lbsize);  		dk_ioc.dki_length = label_len - disk_info.dki_lbsize;  		rval = efi_ioctl(fd, DKIOCGETEFI, &dk_ioc); @@ -565,20 +569,32 @@ write_pmbr(int fd, struct dk_gpt *vtoc)  	struct mboot	mb;  	uchar_t		*cp;  	diskaddr_t	size_in_lba; +	uchar_t		*buf; +	int		len; + +	len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize; +	buf = calloc(len, 1);  	/*  	 * Preserve any boot code and disk signature if the first block is  	 * already an MBR.  	 */  	dk_ioc.dki_lba = 0; -	dk_ioc.dki_length = sizeof (mb); +	dk_ioc.dki_length = len;  	/* LINTED -- always longlong aligned */ -	dk_ioc.dki_data = (efi_gpt_t *)&mb; -	if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1 || -	    mb.signature != LE_16(MBB_MAGIC)) { +	dk_ioc.dki_data = (efi_gpt_t *)buf; +	if (efi_ioctl(fd, DKIOCGETEFI, &dk_ioc) == -1) { +		(void *) memcpy(&mb, buf, sizeof (mb));  		bzero(&mb, sizeof (mb));  		mb.signature = LE_16(MBB_MAGIC); +	} else { +		(void *) memcpy(&mb, buf, sizeof (mb)); +		if (mb.signature != LE_16(MBB_MAGIC)) { +			bzero(&mb, sizeof (mb)); +			mb.signature = LE_16(MBB_MAGIC); +		}  	} +  	bzero(&mb.parts, sizeof (mb.parts));  	cp = (uchar_t *)&mb.parts[0];  	/* bootable or not */ @@ -611,11 +627,14 @@ write_pmbr(int fd, struct dk_gpt *vtoc)  		*cp++ = 0xff;  		*cp++ = 0xff;  	} + +	(void *) memcpy(buf, &mb, sizeof (mb));  	/* LINTED -- always longlong aligned */ -	dk_ioc.dki_data = (efi_gpt_t *)&mb; +	dk_ioc.dki_data = (efi_gpt_t *)buf;  	dk_ioc.dki_lba = 0; -	dk_ioc.dki_length = sizeof (mb); +	dk_ioc.dki_length = len;  	if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) { +		free(buf);  		switch (errno) {  		case EIO:  			return (VT_EIO); @@ -625,6 +644,7 @@ write_pmbr(int fd, struct dk_gpt *vtoc)  			return (VT_ERROR);  		}  	} +	free(buf);  	return (0);  } @@ -873,7 +893,6 @@ efi_write(int fd, struct dk_gpt *vtoc)  	 * for backup GPT header.  	 */  	lba_backup_gpt_hdr = vtoc->efi_last_u_lba + 1 + nblocks; -  	if ((dk_ioc.dki_data = calloc(dk_ioc.dki_length, 1)) == NULL)  		return (VT_ERROR); @@ -894,7 +913,7 @@ efi_write(int fd, struct dk_gpt *vtoc)  	UUID_LE_CONVERT(efi->efi_gpt_DiskGUID, vtoc->efi_disk_uguid);  	/* LINTED -- always longlong aligned */ -	efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + sizeof (efi_gpt_t)); +	efi_parts = (efi_gpe_t *)((char *)dk_ioc.dki_data + vtoc->efi_lbasize);  	for (i = 0; i < vtoc->efi_nparts; i++) {  		for (j = 0; @@ -965,10 +984,14 @@ efi_write(int fd, struct dk_gpt *vtoc)  		free(dk_ioc.dki_data);  		return (0);  	} +  	/* write backup partition array */  	dk_ioc.dki_lba = vtoc->efi_last_u_lba + 1;  	dk_ioc.dki_length -= vtoc->efi_lbasize; -	dk_ioc.dki_data++; +	/* LINTED */ +	dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data + +	    vtoc->efi_lbasize); +  	if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {  		/*  		 * we wrote the primary label okay, so don't fail @@ -987,7 +1010,9 @@ efi_write(int fd, struct dk_gpt *vtoc)  	 */  	dk_ioc.dki_lba = lba_backup_gpt_hdr;  	dk_ioc.dki_length = vtoc->efi_lbasize; -	dk_ioc.dki_data--; +	/* LINTED */ +	dk_ioc.dki_data = (efi_gpt_t *)((char *)dk_ioc.dki_data - +	    vtoc->efi_lbasize);  	efi->efi_gpt_AlternateLBA = LE_64(1ULL);  	efi->efi_gpt_MyLBA = LE_64(lba_backup_gpt_hdr);  	efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1); diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c index 75559a9b94..343b1b965c 100644 --- a/usr/src/uts/common/io/cmlb.c +++ b/usr/src/uts/common/io/cmlb.c @@ -1287,6 +1287,9 @@ cmlb_check_update_blockcount(struct cmlb_lun *cl, void *tg_cookie)  	if ((capacity != 0) && (lbasize != 0)) {  		cl->cl_blockcount = capacity;  		cl->cl_tgt_blocksize = lbasize; +		if (!cl->cl_is_removable) { +			cl->cl_sys_blocksize = lbasize; +		}  		return (0);  	} else {  		return (EIO); @@ -1592,7 +1595,7 @@ cmlb_validate_geometry(struct cmlb_lun *cl, boolean_t forcerevalid, int flags,  		label_addr = (daddr_t)(cl->cl_solaris_offset + DK_LABEL_LOC); -		buffer_size = sizeof (struct dk_label); +		buffer_size = cl->cl_sys_blocksize;  		cmlb_dbg(CMLB_TRACE, cl, "cmlb_validate_geometry: "  		    "label_addr: 0x%x allocation size: 0x%x\n", @@ -2199,12 +2202,6 @@ cmlb_use_efi(struct cmlb_lun *cl, diskaddr_t capacity, int flags,  	ASSERT(mutex_owned(CMLB_MUTEX(cl))); -	if (cl->cl_tgt_blocksize != cl->cl_sys_blocksize) { -		rval = EINVAL; -		goto done_err1; -	} - -  	lbasize = cl->cl_sys_blocksize;  	cl->cl_reserved = -1; @@ -3637,7 +3634,7 @@ cmlb_dkio_partition(struct cmlb_lun *cl, caddr_t arg, int flag,  	}  	buffer = kmem_alloc(EFI_MIN_ARRAY_SIZE, KM_SLEEP); -	rval = DK_TG_READ(cl, buffer, 1, DEV_BSIZE, tg_cookie); +	rval = DK_TG_READ(cl, buffer, 1, cl->cl_sys_blocksize, tg_cookie);  	if (rval != 0)  		goto done_error; @@ -4048,9 +4045,9 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  	cl->cl_reserved = -1;  	mutex_exit(CMLB_MUTEX(cl)); -	gpt = kmem_alloc(sizeof (efi_gpt_t), KM_SLEEP); +	gpt = kmem_alloc(cl->cl_sys_blocksize, KM_SLEEP); -	if (DK_TG_READ(cl, gpt, 1, DEV_BSIZE, tg_cookie) != 0) { +	if (DK_TG_READ(cl, gpt, 1, cl->cl_sys_blocksize, tg_cookie) != 0) {  		goto done;  	} @@ -4059,7 +4056,8 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  	if (rval == 0) {  		/* clear primary */  		bzero(gpt, sizeof (efi_gpt_t)); -		if (rval = DK_TG_WRITE(cl, gpt, 1, EFI_LABEL_SIZE, tg_cookie)) { +		if (rval = DK_TG_WRITE(cl, gpt, 1, cl->cl_sys_blocksize, +		    tg_cookie)) {  			cmlb_dbg(CMLB_INFO,  cl,  			    "cmlb_clear_efi: clear primary label failed\n");  		} @@ -4070,8 +4068,8 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  		goto done;  	} -	if ((rval = DK_TG_READ(cl, gpt, cap - 1, EFI_LABEL_SIZE, tg_cookie)) -	    != 0) { +	if ((rval = DK_TG_READ(cl, gpt, cap - 1, cl->cl_sys_blocksize, +	    tg_cookie)) != 0) {  		goto done;  	}  	cmlb_swap_efi_gpt(gpt); @@ -4081,7 +4079,7 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  		cmlb_dbg(CMLB_TRACE,  cl,  		    "cmlb_clear_efi clear backup@%lu\n", cap - 1);  		bzero(gpt, sizeof (efi_gpt_t)); -		if ((rval = DK_TG_WRITE(cl,  gpt, cap - 1, EFI_LABEL_SIZE, +		if ((rval = DK_TG_WRITE(cl,  gpt, cap - 1, cl->cl_sys_blocksize,  		    tg_cookie))) {  			cmlb_dbg(CMLB_INFO,  cl,  			    "cmlb_clear_efi: clear backup label failed\n"); @@ -4092,7 +4090,7 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  		 * header of this file  		 */  		if ((rval = DK_TG_READ(cl, gpt, cap - 2, -		    EFI_LABEL_SIZE, tg_cookie)) != 0) { +		    cl->cl_sys_blocksize, tg_cookie)) != 0) {  			goto done;  		}  		cmlb_swap_efi_gpt(gpt); @@ -4104,7 +4102,7 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  			    cap - 2);  			bzero(gpt, sizeof (efi_gpt_t));  			if ((rval = DK_TG_WRITE(cl,  gpt, cap - 2, -			    EFI_LABEL_SIZE, tg_cookie))) { +			    cl->cl_sys_blocksize, tg_cookie))) {  				cmlb_dbg(CMLB_INFO,  cl,  				"cmlb_clear_efi: clear legacy backup label "  				"failed\n"); @@ -4113,7 +4111,7 @@ cmlb_clear_efi(struct cmlb_lun *cl, void *tg_cookie)  	}  done: -	kmem_free(gpt, sizeof (efi_gpt_t)); +	kmem_free(gpt, cl->cl_sys_blocksize);  }  /* @@ -4210,7 +4208,7 @@ cmlb_clear_vtoc(struct cmlb_lun *cl, void *tg_cookie)  	struct dk_label		*dkl;  	mutex_exit(CMLB_MUTEX(cl)); -	dkl = kmem_zalloc(sizeof (struct dk_label), KM_SLEEP); +	dkl = kmem_zalloc(cl->cl_sys_blocksize, KM_SLEEP);  	mutex_enter(CMLB_MUTEX(cl));  	/*  	 * cmlb_set_vtoc uses these fields in order to figure out @@ -4223,7 +4221,7 @@ cmlb_clear_vtoc(struct cmlb_lun *cl, void *tg_cookie)  	dkl->dkl_nsect  = cl->cl_g.dkg_nsect;  	mutex_exit(CMLB_MUTEX(cl));  	(void) cmlb_set_vtoc(cl, dkl, tg_cookie); -	kmem_free(dkl, sizeof (struct dk_label)); +	kmem_free(dkl, cl->cl_sys_blocksize);  	mutex_enter(CMLB_MUTEX(cl));  } @@ -4258,7 +4256,7 @@ cmlb_write_label(struct cmlb_lun *cl, void *tg_cookie)  	ASSERT(mutex_owned(CMLB_MUTEX(cl)));  	mutex_exit(CMLB_MUTEX(cl)); -	dkl = kmem_zalloc(sizeof (struct dk_label), KM_SLEEP); +	dkl = kmem_zalloc(cl->cl_sys_blocksize, KM_SLEEP);  	mutex_enter(CMLB_MUTEX(cl));  	bcopy(&cl->cl_vtoc, &dkl->dkl_vtoc, sizeof (struct dk_vtoc)); @@ -4303,7 +4301,7 @@ cmlb_write_label(struct cmlb_lun *cl, void *tg_cookie)  	rval = cmlb_set_vtoc(cl, dkl, tg_cookie);  exit: -	kmem_free(dkl, sizeof (struct dk_label)); +	kmem_free(dkl, cl->cl_sys_blocksize);  	mutex_enter(CMLB_MUTEX(cl));  	return (rval);  } @@ -4422,7 +4420,7 @@ cmlb_dkio_get_mboot(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie)  	/*  	 * Read the mboot block, located at absolute block 0 on the target.  	 */ -	buffer_size = sizeof (struct mboot); +	buffer_size = cl->cl_sys_blocksize;  	cmlb_dbg(CMLB_TRACE,  cl,  	    "cmlb_dkio_get_mboot: allocation size: 0x%x\n", buffer_size); @@ -4481,18 +4479,18 @@ cmlb_dkio_set_mboot(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie)  		return (EINVAL);  	} -	mboot = kmem_zalloc(sizeof (struct mboot), KM_SLEEP); +	mboot = kmem_zalloc(cl->cl_sys_blocksize, KM_SLEEP);  	if (ddi_copyin((const void *)arg, mboot, -	    sizeof (struct mboot), flag) != 0) { -		kmem_free(mboot, (size_t)(sizeof (struct mboot))); +	    cl->cl_sys_blocksize, flag) != 0) { +		kmem_free(mboot, cl->cl_sys_blocksize);  		return (EFAULT);  	}  	/* Is this really a master boot record? */  	magic = LE_16(mboot->signature);  	if (magic != MBB_MAGIC) { -		kmem_free(mboot, (size_t)(sizeof (struct mboot))); +		kmem_free(mboot, cl->cl_sys_blocksize);  		return (EINVAL);  	} @@ -4508,7 +4506,7 @@ cmlb_dkio_set_mboot(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie)  		rval = cmlb_update_fdisk_and_vtoc(cl, tg_cookie);  		if ((!cl->cl_f_geometry_is_valid) || (rval != 0)) {  			mutex_exit(CMLB_MUTEX(cl)); -			kmem_free(mboot, (size_t)(sizeof (struct mboot))); +			kmem_free(mboot, cl->cl_sys_blocksize);  			return (rval);  		}  	} @@ -4529,7 +4527,7 @@ cmlb_dkio_set_mboot(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie)  #endif  	cl->cl_msglog_flag |= CMLB_ALLOW_2TB_WARN;  	mutex_exit(CMLB_MUTEX(cl)); -	kmem_free(mboot, (size_t)(sizeof (struct mboot))); +	kmem_free(mboot, cl->cl_sys_blocksize);  	return (rval);  } @@ -5098,10 +5096,10 @@ fallback:	return (ddi_prop_op(dev, dip, prop_op, mod_flags,  	    (diskaddr_t *)&nblocks64, NULL, NULL, NULL, tg_cookie);  	/* -	 * Assume partition information is in DEV_BSIZE units, compute +	 * Assume partition information is in sys_blocksize units, compute  	 * divisor for size(9P) property representation.  	 */ -	dblk = lbasize / DEV_BSIZE; +	dblk = lbasize / cl->cl_sys_blocksize;  	/* Now let ddi_prop_op_nblocks_blksize() handle the request. */  	return (ddi_prop_op_nblocks_blksize(dev, dip, prop_op, mod_flags, diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c index f2cbc0df37..8cbc1310a3 100644 --- a/usr/src/uts/common/io/scsi/targets/sd.c +++ b/usr/src/uts/common/io/scsi/targets/sd.c @@ -1017,6 +1017,7 @@ static int sd_pm_idletime = 1;  #define	sd_free_rqs			ssd_free_rqs  #define	sd_dump_memory			ssd_dump_memory  #define	sd_get_media_info		ssd_get_media_info +#define	sd_get_media_info_ext		ssd_get_media_info_ext  #define	sd_dkio_ctrl_info		ssd_dkio_ctrl_info  #define	sd_nvpair_str_decode		ssd_nvpair_str_decode  #define	sd_strtok_r			ssd_strtok_r @@ -1093,6 +1094,7 @@ static int sd_pm_idletime = 1;  #define	sd_is_lsi			ssd_is_lsi  #define	sd_tg_rdwr			ssd_tg_rdwr  #define	sd_tg_getinfo			ssd_tg_getinfo +#define	sd_rmw_msg_print_handler	ssd_rmw_msg_print_handler  #endif	/* #if (defined(__fibre)) */ @@ -1463,7 +1465,7 @@ static int sd_send_scsi_DOORLOCK(sd_ssc_t *ssc, int flag, int path_flag);  static int sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp,  	uint32_t *lbap, int path_flag);  static int sd_send_scsi_READ_CAPACITY_16(sd_ssc_t *ssc, uint64_t *capp, -	uint32_t *lbap, int path_flag); +	uint32_t *lbap, uint32_t *psp, int path_flag);  static int sd_send_scsi_START_STOP_UNIT(sd_ssc_t *ssc, int flag,  	int path_flag);  static int sd_send_scsi_INQUIRY(sd_ssc_t *ssc, uchar_t *bufaddr, @@ -1510,6 +1512,7 @@ static void sd_panic_for_res_conflict(struct sd_lun *un);   * Disk Ioctl Function Prototypes   */  static int sd_get_media_info(dev_t dev, caddr_t arg, int flag); +static int sd_get_media_info_ext(dev_t dev, caddr_t arg, int flag);  static int sd_dkio_ctrl_info(dev_t dev, caddr_t arg, int flag);  static int sd_dkio_get_temp(dev_t dev, caddr_t arg, int flag); @@ -1610,6 +1613,11 @@ static int sd_tg_rdwr(dev_info_t *devi, uchar_t cmd, void *bufaddr,  static int sd_tg_getinfo(dev_info_t *devi, int cmd, void *arg, void *tg_cookie);  /* + * For printing RMW warning message timely + */ +static void sd_rmw_msg_print_handler(void *arg); + +/*   * Constants for failfast support:   *   * SD_FAILFAST_INACTIVE: Instance is currently in a normal state, with NO @@ -1781,13 +1789,19 @@ static sd_chain_t sd_iostart_chain[] = {  	sd_mapblockaddr_iostart,	/* Index: 3 */  	sd_core_iostart,		/* Index: 4 */ -	/* Chain for buf IO for removable-media targets (PM enabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets with RMW needed (PM enabled) +	 */  	sd_mapblockaddr_iostart,	/* Index: 5 */  	sd_mapblocksize_iostart,	/* Index: 6 */  	sd_pm_iostart,			/* Index: 7 */  	sd_core_iostart,		/* Index: 8 */ -	/* Chain for buf IO for removable-media targets (PM disabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets with RMW needed (PM disabled) +	 */  	sd_mapblockaddr_iostart,	/* Index: 9 */  	sd_mapblocksize_iostart,	/* Index: 10 */  	sd_core_iostart,		/* Index: 11 */ @@ -1817,6 +1831,26 @@ static sd_chain_t sd_iostart_chain[] = {  	/* Chain for "direct priority" USCSI commands (all targets) */  	sd_core_iostart,		/* Index: 25 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with RMW needed with checksumming (PM enabled) +	 */ +	sd_mapblockaddr_iostart,	/* Index: 26 */ +	sd_mapblocksize_iostart,	/* Index: 27 */ +	sd_checksum_iostart,		/* Index: 28 */ +	sd_pm_iostart,			/* Index: 29 */ +	sd_core_iostart,		/* Index: 30 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with RMW needed with checksumming (PM disabled) +	 */ +	sd_mapblockaddr_iostart,	/* Index: 31 */ +	sd_mapblocksize_iostart,	/* Index: 32 */ +	sd_checksum_iostart,		/* Index: 33 */ +	sd_core_iostart,		/* Index: 34 */ +  };  /* @@ -1825,7 +1859,9 @@ static sd_chain_t sd_iostart_chain[] = {   */  #define	SD_CHAIN_DISK_IOSTART			0  #define	SD_CHAIN_DISK_IOSTART_NO_PM		3 +#define	SD_CHAIN_MSS_DISK_IOSTART		5  #define	SD_CHAIN_RMMEDIA_IOSTART		5 +#define	SD_CHAIN_MSS_DISK_IOSTART_NO_PM		9  #define	SD_CHAIN_RMMEDIA_IOSTART_NO_PM		9  #define	SD_CHAIN_CHKSUM_IOSTART			12  #define	SD_CHAIN_CHKSUM_IOSTART_NO_PM		16 @@ -1833,6 +1869,8 @@ static sd_chain_t sd_iostart_chain[] = {  #define	SD_CHAIN_USCSI_CHKSUM_IOSTART		21  #define	SD_CHAIN_DIRECT_CMD_IOSTART		24  #define	SD_CHAIN_PRIORITY_CMD_IOSTART		25 +#define	SD_CHAIN_MSS_CHKSUM_IOSTART		26 +#define	SD_CHAIN_MSS_CHKSUM_IOSTART_NO_PM	31  /* @@ -1859,13 +1897,19 @@ static sd_chain_t sd_iodone_chain[] = {  	sd_buf_iodone,			/* Index: 3 */  	sd_mapblockaddr_iodone,		/* Index: 4 */ -	/* Chain for buf IO for removable-media targets (PM enabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets with RMW needed (PM enabled) +	 */  	sd_buf_iodone,			/* Index: 5 */  	sd_mapblockaddr_iodone,		/* Index: 6 */  	sd_mapblocksize_iodone,		/* Index: 7 */  	sd_pm_iodone,			/* Index: 8 */ -	/* Chain for buf IO for removable-media targets (PM disabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets with RMW needed (PM disabled) +	 */  	sd_buf_iodone,			/* Index: 9 */  	sd_mapblockaddr_iodone,		/* Index: 10 */  	sd_mapblocksize_iodone,		/* Index: 11 */ @@ -1895,6 +1939,25 @@ static sd_chain_t sd_iodone_chain[] = {  	/* Chain for "direct priority" USCSI commands (all targets) */  	sd_uscsi_iodone,		/* Index: 25 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM enabled) +	 */ +	sd_buf_iodone,			/* Index: 26 */ +	sd_mapblockaddr_iodone,		/* Index: 27 */ +	sd_mapblocksize_iodone,		/* Index: 28 */ +	sd_checksum_iodone,		/* Index: 29 */ +	sd_pm_iodone,			/* Index: 30 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM disabled) +	 */ +	sd_buf_iodone,			/* Index: 31 */ +	sd_mapblockaddr_iodone,		/* Index: 32 */ +	sd_mapblocksize_iodone,		/* Index: 33 */ +	sd_checksum_iodone,		/* Index: 34 */  }; @@ -1910,14 +1973,17 @@ static sd_chain_t sd_iodone_chain[] = {  #define	SD_CHAIN_DISK_IODONE			2  #define	SD_CHAIN_DISK_IODONE_NO_PM		4  #define	SD_CHAIN_RMMEDIA_IODONE			8 +#define	SD_CHAIN_MSS_DISK_IODONE		8  #define	SD_CHAIN_RMMEDIA_IODONE_NO_PM		11 +#define	SD_CHAIN_MSS_DISK_IODONE_NO_PM		11  #define	SD_CHAIN_CHKSUM_IODONE			15  #define	SD_CHAIN_CHKSUM_IODONE_NO_PM		18  #define	SD_CHAIN_USCSI_CMD_IODONE		20  #define	SD_CHAIN_USCSI_CHKSUM_IODONE		22  #define	SD_CHAIN_DIRECT_CMD_IODONE		24  #define	SD_CHAIN_PRIORITY_CMD_IODONE		25 - +#define	SD_CHAIN_MSS_CHKSUM_IODONE		30 +#define	SD_CHAIN_MSS_CHKSUM_IODONE_NO_PM	34 @@ -1940,13 +2006,19 @@ static sd_initpkt_t	sd_initpkt_map[] = {  	sd_initpkt_for_buf,		/* Index: 3 */  	sd_initpkt_for_buf,		/* Index: 4 */ -	/* Chain for buf IO for removable-media targets (PM enabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM enabled) +	 */  	sd_initpkt_for_buf,		/* Index: 5 */  	sd_initpkt_for_buf,		/* Index: 6 */  	sd_initpkt_for_buf,		/* Index: 7 */  	sd_initpkt_for_buf,		/* Index: 8 */ -	/* Chain for buf IO for removable-media targets (PM disabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM disabled) +	 */  	sd_initpkt_for_buf,		/* Index: 9 */  	sd_initpkt_for_buf,		/* Index: 10 */  	sd_initpkt_for_buf,		/* Index: 11 */ @@ -1977,6 +2049,24 @@ static sd_initpkt_t	sd_initpkt_map[] = {  	/* Chain for "direct priority" USCSI commands (all targets) */  	sd_initpkt_for_uscsi,		/* Index: 25 */ +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM enabled) +	 */ +	sd_initpkt_for_buf,		/* Index: 26 */ +	sd_initpkt_for_buf,		/* Index: 27 */ +	sd_initpkt_for_buf,		/* Index: 28 */ +	sd_initpkt_for_buf,		/* Index: 29 */ +	sd_initpkt_for_buf,		/* Index: 30 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM disabled) +	 */ +	sd_initpkt_for_buf,		/* Index: 31 */ +	sd_initpkt_for_buf,		/* Index: 32 */ +	sd_initpkt_for_buf,		/* Index: 33 */ +	sd_initpkt_for_buf,		/* Index: 34 */  }; @@ -1999,13 +2089,19 @@ static sd_destroypkt_t	sd_destroypkt_map[] = {  	sd_destroypkt_for_buf,		/* Index: 3 */  	sd_destroypkt_for_buf,		/* Index: 4 */ -	/* Chain for buf IO for removable-media targets (PM enabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM enabled) +	 */  	sd_destroypkt_for_buf,		/* Index: 5 */  	sd_destroypkt_for_buf,		/* Index: 6 */  	sd_destroypkt_for_buf,		/* Index: 7 */  	sd_destroypkt_for_buf,		/* Index: 8 */ -	/* Chain for buf IO for removable-media targets (PM disabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM disabled) +	 */  	sd_destroypkt_for_buf,		/* Index: 9 */  	sd_destroypkt_for_buf,		/* Index: 10 */  	sd_destroypkt_for_buf,		/* Index: 11 */ @@ -2036,6 +2132,24 @@ static sd_destroypkt_t	sd_destroypkt_map[] = {  	/* Chain for "direct priority" USCSI commands (all targets) */  	sd_destroypkt_for_uscsi,	/* Index: 25 */ +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM disabled) +	 */ +	sd_destroypkt_for_buf,		/* Index: 26 */ +	sd_destroypkt_for_buf,		/* Index: 27 */ +	sd_destroypkt_for_buf,		/* Index: 28 */ +	sd_destroypkt_for_buf,		/* Index: 29 */ +	sd_destroypkt_for_buf,		/* Index: 30 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM enabled) +	 */ +	sd_destroypkt_for_buf,		/* Index: 31 */ +	sd_destroypkt_for_buf,		/* Index: 32 */ +	sd_destroypkt_for_buf,		/* Index: 33 */ +	sd_destroypkt_for_buf,		/* Index: 34 */  }; @@ -2066,13 +2180,19 @@ static int sd_chain_type_map[] = {  	SD_CHAIN_BUFIO,			/* Index: 3 */  	SD_CHAIN_BUFIO,			/* Index: 4 */ -	/* Chain for buf IO for removable-media targets (PM enabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM enabled) +	 */  	SD_CHAIN_BUFIO,			/* Index: 5 */  	SD_CHAIN_BUFIO,			/* Index: 6 */  	SD_CHAIN_BUFIO,			/* Index: 7 */  	SD_CHAIN_BUFIO,			/* Index: 8 */ -	/* Chain for buf IO for removable-media targets (PM disabled) */ +	/* +	 * Chain for buf IO for removable-media or large sector size +	 * disk drive targets (PM disabled) +	 */  	SD_CHAIN_BUFIO,			/* Index: 9 */  	SD_CHAIN_BUFIO,			/* Index: 10 */  	SD_CHAIN_BUFIO,			/* Index: 11 */ @@ -2095,13 +2215,32 @@ static int sd_chain_type_map[] = {  	/* Chain for USCSI commands (checksum targets) */  	SD_CHAIN_USCSI,			/* Index: 21 */  	SD_CHAIN_USCSI,			/* Index: 22 */ -	SD_CHAIN_USCSI,			/* Index: 22 */ +	SD_CHAIN_USCSI,			/* Index: 23 */  	/* Chain for "direct" USCSI commands (all targets) */  	SD_CHAIN_DIRECT,		/* Index: 24 */  	/* Chain for "direct priority" USCSI commands (all targets) */  	SD_CHAIN_DIRECT_PRIORITY,	/* Index: 25 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM enabled) +	 */ +	SD_CHAIN_BUFIO,			/* Index: 26 */ +	SD_CHAIN_BUFIO,			/* Index: 27 */ +	SD_CHAIN_BUFIO,			/* Index: 28 */ +	SD_CHAIN_BUFIO,			/* Index: 29 */ +	SD_CHAIN_BUFIO,			/* Index: 30 */ + +	/* +	 * Chain for buf IO for large sector size disk drive targets +	 * with checksumming (PM disabled) +	 */ +	SD_CHAIN_BUFIO,			/* Index: 31 */ +	SD_CHAIN_BUFIO,			/* Index: 32 */ +	SD_CHAIN_BUFIO,			/* Index: 33 */ +	SD_CHAIN_BUFIO,			/* Index: 34 */  }; @@ -2147,6 +2286,9 @@ static struct sd_chain_index	sd_chain_index_map[] = {  	{ SD_CHAIN_USCSI_CHKSUM_IOSTART,	SD_CHAIN_USCSI_CHKSUM_IODONE },  	{ SD_CHAIN_DIRECT_CMD_IOSTART,		SD_CHAIN_DIRECT_CMD_IODONE },  	{ SD_CHAIN_PRIORITY_CMD_IOSTART,	SD_CHAIN_PRIORITY_CMD_IODONE }, +	{ SD_CHAIN_MSS_CHKSUM_IOSTART,		SD_CHAIN_MSS_CHKSUM_IODONE }, +	{ SD_CHAIN_MSS_CHKSUM_IOSTART_NO_PM, SD_CHAIN_MSS_CHKSUM_IODONE_NO_PM }, +  }; @@ -2158,9 +2300,13 @@ static struct sd_chain_index	sd_chain_index_map[] = {  #define	SD_CHAIN_INFO_DISK		0  #define	SD_CHAIN_INFO_DISK_NO_PM	1  #define	SD_CHAIN_INFO_RMMEDIA		2 +#define	SD_CHAIN_INFO_MSS_DISK		2  #define	SD_CHAIN_INFO_RMMEDIA_NO_PM	3 +#define	SD_CHAIN_INFO_MSS_DSK_NO_PM	3  #define	SD_CHAIN_INFO_CHKSUM		4  #define	SD_CHAIN_INFO_CHKSUM_NO_PM	5 +#define	SD_CHAIN_INFO_MSS_DISK_CHKSUM	10 +#define	SD_CHAIN_INFO_MSS_DISK_CHKSUM_NO_PM	11  /* un->un_uscsi_chain_type must be set to one of these */  #define	SD_CHAIN_INFO_USCSI_CMD		6 @@ -3967,6 +4113,16 @@ sd_set_properties(struct sd_lun *un, char *name, char *value)  		    "min throttle set to %d\n", un->un_min_throttle);  	} +	if (strcasecmp(name, "rmw-type") == 0) { +		if (ddi_strtol(value, &endptr, 0, &val) == 0) { +			un->un_f_rmw_type = val; +		} else { +			goto value_invalid; +		} +		SD_INFO(SD_LOG_ATTACH_DETACH, un, "sd_set_properties: " +		    "RMW type set to %d\n", un->un_f_rmw_type); +	} +  	/*  	 * Validate the throttle values.  	 * If any of the numbers are invalid, set everything to defaults. @@ -4996,7 +5152,10 @@ sd_update_block_info(struct sd_lun *un, uint32_t lbasize, uint64_t capacity)  {  	if (lbasize != 0) {  		un->un_tgt_blocksize = lbasize; -		un->un_f_tgt_blocksize_is_valid	= TRUE; +		un->un_f_tgt_blocksize_is_valid = TRUE; +		if (!un->un_f_has_removable_media) { +			un->un_sys_blocksize = lbasize; +		}  	}  	if (capacity != 0) { @@ -5290,7 +5449,7 @@ sd_get_devid(sd_ssc_t *ssc)  	/* Calculate the checksum */  	chksum = 0;  	ip = (uint_t *)dkdevid; -	for (i = 0; i < ((un->un_sys_blocksize - sizeof (int))/sizeof (int)); +	for (i = 0; i < ((DEV_BSIZE - sizeof (int)) / sizeof (int));  	    i++) {  		chksum ^= ip[i];  	} @@ -5386,6 +5545,7 @@ static int  sd_write_deviceid(sd_ssc_t *ssc)  {  	struct dk_devid		*dkdevid; +	uchar_t			*buf;  	diskaddr_t		blk;  	uint_t			*ip, chksum;  	int			status; @@ -5406,7 +5566,8 @@ sd_write_deviceid(sd_ssc_t *ssc)  	/* Allocate the buffer */ -	dkdevid = kmem_zalloc(un->un_sys_blocksize, KM_SLEEP); +	buf = kmem_zalloc(un->un_sys_blocksize, KM_SLEEP); +	dkdevid = (struct dk_devid *)buf;  	/* Fill in the revision */  	dkdevid->dkd_rev_hi = DK_DEVID_REV_MSB; @@ -5421,7 +5582,7 @@ sd_write_deviceid(sd_ssc_t *ssc)  	/* Calculate the checksum */  	chksum = 0;  	ip = (uint_t *)dkdevid; -	for (i = 0; i < ((un->un_sys_blocksize - sizeof (int))/sizeof (int)); +	for (i = 0; i < ((DEV_BSIZE - sizeof (int)) / sizeof (int));  	    i++) {  		chksum ^= ip[i];  	} @@ -5430,12 +5591,12 @@ sd_write_deviceid(sd_ssc_t *ssc)  	DKD_FORMCHKSUM(chksum, dkdevid);  	/* Write the reserved sector */ -	status = sd_send_scsi_WRITE(ssc, dkdevid, un->un_sys_blocksize, blk, +	status = sd_send_scsi_WRITE(ssc, buf, un->un_sys_blocksize, blk,  	    SD_PATH_DIRECT);  	if (status != 0)  		sd_ssc_assessment(ssc, SD_FMT_IGNORE); -	kmem_free(dkdevid, un->un_sys_blocksize); +	kmem_free(buf, un->un_sys_blocksize);  	mutex_enter(SD_MUTEX(un));  	return (status); @@ -5903,6 +6064,14 @@ sd_ddi_suspend(dev_info_t *devi)  		mutex_exit(&un->un_pm_mutex);  	} +	if (un->un_rmw_msg_timeid != NULL) { +		timeout_id_t temp_id = un->un_rmw_msg_timeid; +		un->un_rmw_msg_timeid = NULL; +		mutex_exit(SD_MUTEX(un)); +		(void) untimeout(temp_id); +		mutex_enter(SD_MUTEX(un)); +	} +  	if (un->un_retry_timeid != NULL) {  		timeout_id_t temp_id = un->un_retry_timeid;  		un->un_retry_timeid = NULL; @@ -6217,7 +6386,7 @@ sd_pm_idletimeout_handler(void *arg)  		} else {  			un->un_buf_chain_type = SD_CHAIN_INFO_DISK;  		} -		un->un_uscsi_chain_type  = SD_CHAIN_INFO_USCSI_CMD; +		un->un_uscsi_chain_type = SD_CHAIN_INFO_USCSI_CMD;  		SD_TRACE(SD_LOG_IO_PM, un,  		    "sd_pm_idletimeout_handler: idling device\n"); @@ -6839,6 +7008,7 @@ sd_unit_attach(dev_info_t *devi)  	struct	scsi_device	*devp;  	struct	sd_lun		*un;  	char			*variantp; +	char			name_str[48];  	int	reservation_flag = SD_TARGET_IS_UNRESERVED;  	int	instance;  	int	rval; @@ -7267,6 +7437,7 @@ sd_unit_attach(dev_info_t *devi)  	 * meaning a non-zero value must be entered to change the default.  	 */  	un->un_f_disksort_disabled = FALSE; +	un->un_f_rmw_type = SD_RMW_TYPE_DEFAULT;  	/*  	 * Retrieve the properties from the static driver table or the driver @@ -7906,6 +8077,24 @@ sd_unit_attach(dev_info_t *devi)  	un->un_f_write_cache_enabled = (wc_enabled != 0);  	mutex_exit(SD_MUTEX(un)); +	if (un->un_f_rmw_type != SD_RMW_TYPE_RETURN_ERROR && +	    un->un_tgt_blocksize != DEV_BSIZE) { +		if (!(un->un_wm_cache)) { +			(void) snprintf(name_str, sizeof (name_str), +			    "%s%d_cache", +			    ddi_driver_name(SD_DEVINFO(un)), +			    ddi_get_instance(SD_DEVINFO(un))); +			un->un_wm_cache = kmem_cache_create( +			    name_str, sizeof (struct sd_w_map), +			    8, sd_wm_cache_constructor, +			    sd_wm_cache_destructor, NULL, +			    (void *)un, NULL, 0); +			if (!(un->un_wm_cache)) { +				goto wm_cache_failed; +			} +		} +	} +  	/*  	 * Check the value of the NV_SUP bit and set  	 * un_f_suppress_cache_flush accordingly. @@ -7994,7 +8183,7 @@ sd_unit_attach(dev_info_t *devi)  	/*  	 * An error occurred during the attach; clean up & return failure.  	 */ - +wm_cache_failed:  devid_failed:  setup_pm_failed: @@ -8057,6 +8246,15 @@ spinup_failed:  		mutex_enter(SD_MUTEX(un));  	} +	/* Cancel rmw warning message timeouts */ +	if (un->un_rmw_msg_timeid != NULL) { +		timeout_id_t temp_id = un->un_rmw_msg_timeid; +		un->un_rmw_msg_timeid = NULL; +		mutex_exit(SD_MUTEX(un)); +		(void) untimeout(temp_id); +		mutex_enter(SD_MUTEX(un)); +	} +  	/* Cancel any pending retry timeouts */  	if (un->un_retry_timeid != NULL) {  		timeout_id_t temp_id = un->un_retry_timeid; @@ -8270,6 +8468,14 @@ sd_unit_detach(dev_info_t *devi)  		mutex_enter(SD_MUTEX(un));  	} +	if (un->un_rmw_msg_timeid != NULL) { +		timeout_id_t temp_id = un->un_rmw_msg_timeid; +		un->un_rmw_msg_timeid = NULL; +		mutex_exit(SD_MUTEX(un)); +		(void) untimeout(temp_id); +		mutex_enter(SD_MUTEX(un)); +	} +  	if (un->un_dcvb_timeid != NULL) {  		timeout_id_t temp_id = un->un_dcvb_timeid;  		un->un_dcvb_timeid = NULL; @@ -10288,7 +10494,9 @@ sd_ready_and_valid(sd_ssc_t *ssc, int part)  	 * a media is changed this routine will be called and the  	 * block size is a function of media rather than device.  	 */ -	if (un->un_f_non_devbsize_supported && NOT_DEVBSIZE(un)) { +	if ((un->un_f_rmw_type != SD_RMW_TYPE_RETURN_ERROR || +	    un->un_f_non_devbsize_supported) && +	    un->un_tgt_blocksize != DEV_BSIZE) {  		if (!(un->un_wm_cache)) {  			(void) snprintf(name_str, sizeof (name_str),  			    "%s%d_cache", @@ -10518,17 +10726,20 @@ sdread(dev_t dev, struct uio *uio, cred_t *cred_p)  	/*  	 * Read requests are restricted to multiples of the system block size.  	 */ -	secmask = un->un_sys_blocksize - 1; +	if (un->un_f_rmw_type == SD_RMW_TYPE_RETURN_ERROR) +		secmask = un->un_tgt_blocksize - 1; +	else +		secmask = DEV_BSIZE - 1;  	if (uio->uio_loffset & ((offset_t)(secmask))) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdread: file offset not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else if (uio->uio_iov->iov_len & (secmask)) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdread: transfer length not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else {  		err = physio(sdstrategy, NULL, dev, B_READ, sdmin, uio); @@ -10604,17 +10815,20 @@ sdwrite(dev_t dev, struct uio *uio, cred_t *cred_p)  	/*  	 * Write requests are restricted to multiples of the system block size.  	 */ -	secmask = un->un_sys_blocksize - 1; +	if (un->un_f_rmw_type == SD_RMW_TYPE_RETURN_ERROR) +		secmask = un->un_tgt_blocksize - 1; +	else +		secmask = DEV_BSIZE - 1;  	if (uio->uio_loffset & ((offset_t)(secmask))) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdwrite: file offset not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else if (uio->uio_iov->iov_len & (secmask)) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdwrite: transfer length not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else {  		err = physio(sdstrategy, NULL, dev, B_WRITE, sdmin, uio); @@ -10690,17 +10904,20 @@ sdaread(dev_t dev, struct aio_req *aio, cred_t *cred_p)  	/*  	 * Read requests are restricted to multiples of the system block size.  	 */ -	secmask = un->un_sys_blocksize - 1; +	if (un->un_f_rmw_type == SD_RMW_TYPE_RETURN_ERROR) +		secmask = un->un_tgt_blocksize - 1; +	else +		secmask = DEV_BSIZE - 1;  	if (uio->uio_loffset & ((offset_t)(secmask))) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdaread: file offset not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else if (uio->uio_iov->iov_len & (secmask)) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdaread: transfer length not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else {  		err = aphysio(sdstrategy, anocancel, dev, B_READ, sdmin, aio); @@ -10776,17 +10993,20 @@ sdawrite(dev_t dev, struct aio_req *aio, cred_t *cred_p)  	/*  	 * Write requests are restricted to multiples of the system block size.  	 */ -	secmask = un->un_sys_blocksize - 1; +	if (un->un_f_rmw_type == SD_RMW_TYPE_RETURN_ERROR) +		secmask = un->un_tgt_blocksize - 1; +	else +		secmask = DEV_BSIZE - 1;  	if (uio->uio_loffset & ((offset_t)(secmask))) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdawrite: file offset not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else if (uio->uio_iov->iov_len & (secmask)) {  		SD_ERROR(SD_LOG_READ_WRITE, un,  		    "sdawrite: transfer length not modulo %d\n", -		    un->un_sys_blocksize); +		    secmask + 1);  		err = EINVAL;  	} else {  		err = aphysio(sdstrategy, anocancel, dev, B_WRITE, sdmin, aio); @@ -11012,6 +11232,7 @@ sdstrategy(struct buf *bp)  		biodone(bp);  		return (0);  	} +  	/* As was done in the past, fail new cmds. if state is dumping. */  	if (un->un_state == SD_STATE_DUMPING) {  		bioerror(bp, ENXIO); @@ -11150,6 +11371,27 @@ sd_xbuf_init(struct sd_lun *un, struct buf *bp, struct sd_xbuf *xp,  		/* FALLTHRU */  	case SD_CHAIN_BUFIO:  		index = un->un_buf_chain_type; +		if ((!un->un_f_has_removable_media) && +		    (un->un_tgt_blocksize != 0) && +		    (un->un_tgt_blocksize != DEV_BSIZE)) { +			int secmask = 0, blknomask = 0; +			blknomask = +			    (un->un_tgt_blocksize / DEV_BSIZE) - 1; +			secmask = un->un_tgt_blocksize - 1; + +			if ((bp->b_lblkno & (blknomask)) || +			    (bp->b_bcount & (secmask))) { +				if (un->un_f_rmw_type != +				    SD_RMW_TYPE_RETURN_ERROR) { +					if (un->un_f_pm_is_enabled == FALSE) +						index = +						    SD_CHAIN_INFO_MSS_DSK_NO_PM; +					else +						index = +						    SD_CHAIN_INFO_MSS_DISK; +				} +			} +		}  		break;  	case SD_CHAIN_USCSI:  		index = un->un_uscsi_chain_type; @@ -12039,6 +12281,20 @@ sd_uscsi_iodone(int index, struct sd_lun *un, struct buf *bp)   *		request would exceed partition range.  Converts   *		partition-relative block address to absolute.   * + *              Upon exit of this function: + *              1.I/O is aligned + *                 xp->xb_blkno represents the absolute sector address + *              2.I/O is misaligned + *                 xp->xb_blkno represents the absolute logical block address + *                 based on DEV_BSIZE. The logical block address will be + *                 converted to physical sector address in sd_mapblocksize_\ + *                 iostart. + *              3.I/O is misaligned but is aligned in "overrun" buf + *                 xp->xb_blkno represents the absolute logical block address + *                 based on DEV_BSIZE. The logical block address will be + *                 converted to physical sector address in sd_mapblocksize_\ + *                 iostart. But no RMW will be issued in this case. + *   *     Context: Can sleep   *   *      Issues: This follows what the old code did, in terms of accessing @@ -12060,6 +12316,8 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp)  	int	partition;  	diskaddr_t	partition_offset;  	struct sd_xbuf *xp; +	int secmask = 0, blknomask = 0; +	ushort_t is_aligned = TRUE;  	ASSERT(un != NULL);  	ASSERT(bp != NULL); @@ -12116,6 +12374,57 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp)  	(void) cmlb_partinfo(un->un_cmlbhandle, partition,  	    &nblocks, &partition_offset, NULL, NULL, (void *)SD_PATH_DIRECT); +	blknomask = (un->un_tgt_blocksize / DEV_BSIZE) - 1; +	secmask = un->un_tgt_blocksize - 1; + +	if ((bp->b_lblkno & (blknomask)) || (bp->b_bcount & (secmask))) { +		is_aligned = FALSE; +	} + +	if (!(NOT_DEVBSIZE(un))) { +		/* +		 * If I/O is aligned, no need to involve RMW(Read Modify Write) +		 * Convert the logical block number to target's physical sector +		 * number. +		 */ +		if (is_aligned) { +			xp->xb_blkno = SD_SYS2TGTBLOCK(un, xp->xb_blkno); +		} else { +			switch (un->un_f_rmw_type) { +			case SD_RMW_TYPE_RETURN_ERROR: +				bp->b_flags |= B_ERROR; +				goto error_exit; + +			case SD_RMW_TYPE_DEFAULT: +				mutex_enter(SD_MUTEX(un)); +				if (un->un_rmw_msg_timeid == NULL) { +					scsi_log(SD_DEVINFO(un), sd_label, +					    CE_WARN, "I/O request is not " +					    "aligned with %d disk sector size. " +					    "It is handled through Read Modify " +					    "Write but the performance is " +					    "very low.\n", +					    un->un_tgt_blocksize); +					un->un_rmw_msg_timeid = +					    timeout(sd_rmw_msg_print_handler, +					    un, SD_RMW_MSG_PRINT_TIMEOUT); +				} else { +					un->un_rmw_incre_count ++; +				} +				mutex_exit(SD_MUTEX(un)); +				break; + +			case SD_RMW_TYPE_NO_WARNING: +			default: +				break; +			} + +			nblocks = SD_TGT2SYSBLOCK(un, nblocks); +			partition_offset = SD_TGT2SYSBLOCK(un, +			    partition_offset); +		} +	} +  	/*  	 * blocknum is the starting block number of the request. At this  	 * point it is still relative to the start of the minor device. @@ -12136,7 +12445,7 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp)  	 * a multiple of the system block size.  	 */  	if ((blocknum < 0) || (blocknum >= nblocks) || -	    ((bp->b_bcount & (un->un_sys_blocksize - 1)) != 0)) { +	    ((bp->b_bcount & (DEV_BSIZE - 1)) != 0)) {  		bp->b_flags |= B_ERROR;  		goto error_exit;  	} @@ -12145,11 +12454,18 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp)  	 * If the requsted # blocks exceeds the available # blocks, that  	 * is an overrun of the partition.  	 */ -	requested_nblocks = SD_BYTES2SYSBLOCKS(un, bp->b_bcount); +	if ((!NOT_DEVBSIZE(un)) && is_aligned) { +		requested_nblocks = SD_BYTES2TGTBLOCKS(un, bp->b_bcount); +	} else { +		requested_nblocks = SD_BYTES2SYSBLOCKS(bp->b_bcount); +	} +  	available_nblocks = (size_t)(nblocks - blocknum);  	ASSERT(nblocks >= blocknum);  	if (requested_nblocks > available_nblocks) { +		size_t resid; +  		/*  		 * Allocate an "overrun" buf to allow the request to proceed  		 * for the amount of space available in the partition. The @@ -12158,8 +12474,14 @@ sd_mapblockaddr_iostart(int index, struct sd_lun *un, struct buf *bp)  		 * replaces the original buf here, and the original buf  		 * is saved inside the overrun buf, for later use.  		 */ -		size_t resid = SD_SYSBLOCKS2BYTES(un, -		    (offset_t)(requested_nblocks - available_nblocks)); +		if ((!NOT_DEVBSIZE(un)) && is_aligned) { +			resid = SD_TGTBLOCKS2BYTES(un, +			    (offset_t)(requested_nblocks - available_nblocks)); +		} else { +			resid = SD_SYSBLOCKS2BYTES( +			    (offset_t)(requested_nblocks - available_nblocks)); +		} +  		size_t count = bp->b_bcount - resid;  		/*  		 * Note: count is an unsigned entity thus it'll NEVER @@ -12318,7 +12640,7 @@ sd_mapblocksize_iostart(int index, struct sd_lun *un, struct buf *bp)  	 * un->un_sys_blocksize as its block size or if bcount == 0.  	 * In this case there is no layer-private data block allocated.  	 */ -	if ((un->un_tgt_blocksize == un->un_sys_blocksize) || +	if ((un->un_tgt_blocksize == DEV_BSIZE) ||  	    (bp->b_bcount == 0)) {  		goto done;  	} @@ -12333,7 +12655,7 @@ sd_mapblocksize_iostart(int index, struct sd_lun *un, struct buf *bp)  	SD_INFO(SD_LOG_IO_RMMEDIA, un, "sd_mapblocksize_iostart: "  	    "tgt_blocksize:0x%x sys_blocksize: 0x%x\n", -	    un->un_tgt_blocksize, un->un_sys_blocksize); +	    un->un_tgt_blocksize, DEV_BSIZE);  	SD_INFO(SD_LOG_IO_RMMEDIA, un, "sd_mapblocksize_iostart: "  	    "request start block:0x%x\n", xp->xb_blkno);  	SD_INFO(SD_LOG_IO_RMMEDIA, un, "sd_mapblocksize_iostart: " @@ -12376,7 +12698,7 @@ sd_mapblocksize_iostart(int index, struct sd_lun *un, struct buf *bp)  	 * Note that end_block is actually the block that follows the last  	 * block of the request, but that's what is needed for the computation.  	 */ -	first_byte  = SD_SYSBLOCKS2BYTES(un, (offset_t)xp->xb_blkno); +	first_byte  = SD_SYSBLOCKS2BYTES((offset_t)xp->xb_blkno);  	start_block = xp->xb_blkno = first_byte / un->un_tgt_blocksize;  	end_block   = (first_byte + bp->b_bcount + un->un_tgt_blocksize - 1) /  	    un->un_tgt_blocksize; @@ -12519,7 +12841,7 @@ sd_mapblocksize_iodone(int index, struct sd_lun *un, struct buf *bp)  	 * There is no shadow buf or layer-private data if the target is  	 * using un->un_sys_blocksize as its block size or if bcount == 0.  	 */ -	if ((un->un_tgt_blocksize == un->un_sys_blocksize) || +	if ((un->un_tgt_blocksize == DEV_BSIZE) ||  	    (bp->b_bcount == 0)) {  		goto exit;  	} @@ -15550,6 +15872,48 @@ sd_start_retry_command(void *arg)  	    "sd_start_retry_command: exit\n");  } +/* + *    Function: sd_rmw_msg_print_handler + * + * Description: If RMW mode is enabled and warning message is triggered + *              print I/O count during a fixed interval. + * + *   Arguments: arg - pointer to associated softstate for the device. + * + *     Context: timeout(9F) thread context. May not sleep. + */ +static void +sd_rmw_msg_print_handler(void *arg) +{ +	struct sd_lun *un = arg; + +	ASSERT(un != NULL); +	ASSERT(!mutex_owned(SD_MUTEX(un))); + +	SD_TRACE(SD_LOG_IO_CORE | SD_LOG_ERROR, un, +	    "sd_rmw_msg_print_handler: entry\n"); + +	mutex_enter(SD_MUTEX(un)); + +	if (un->un_rmw_incre_count > 0) { +		scsi_log(SD_DEVINFO(un), sd_label, CE_WARN, +		    "%"PRIu64" I/O requests are not aligned with %d disk " +		    "sector size in %ld seconds. They are handled through " +		    "Read Modify Write but the performance is very low!\n", +		    un->un_rmw_incre_count, un->un_tgt_blocksize, +		    drv_hztousec(SD_RMW_MSG_PRINT_TIMEOUT) / 1000000); +		un->un_rmw_incre_count = 0; +		un->un_rmw_msg_timeid = timeout(sd_rmw_msg_print_handler, +		    un, SD_RMW_MSG_PRINT_TIMEOUT); +	} else { +		un->un_rmw_msg_timeid = NULL; +	} + +	mutex_exit(SD_MUTEX(un)); + +	SD_TRACE(SD_LOG_IO_CORE | SD_LOG_ERROR, un, +	    "sd_rmw_msg_print_handler: exit\n"); +}  /*   *    Function: sd_start_direct_priority_command @@ -19336,6 +19700,7 @@ sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp, uint32_t *lbap,  	uint32_t		*capacity_buf;  	uint64_t		capacity;  	uint32_t		lbasize; +	uint32_t		pbsize;  	int			status;  	struct sd_lun		*un; @@ -19418,7 +19783,7 @@ sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp, uint32_t *lbap,  		if (capacity == 0xffffffff) {  			sd_ssc_assessment(ssc, SD_FMT_IGNORE);  			status = sd_send_scsi_READ_CAPACITY_16(ssc, &capacity, -			    &lbasize, path_flag); +			    &lbasize, &pbsize, path_flag);  			if (status != 0) {  				return (status);  			} @@ -19467,10 +19832,11 @@ sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp, uint32_t *lbap,  	 * on the logical unit.  The actual logical block count will be  	 * this value plus one.  	 * -	 * Currently the capacity is saved in terms of un->un_sys_blocksize, -	 * so scale the capacity value to reflect this. +	 * Currently, for removable media, the capacity is saved in terms +	 * of un->un_sys_blocksize, so scale the capacity value to reflect this.  	 */ -	capacity = (capacity + 1) * (lbasize / un->un_sys_blocksize); +	if (un->un_f_has_removable_media) +		capacity = (capacity + 1) * (lbasize / un->un_sys_blocksize);  	/*  	 * Copy the values from the READ CAPACITY command into the space @@ -19504,15 +19870,19 @@ sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp, uint32_t *lbap,   *		determine the device capacity in number of blocks and the   *		device native block size.  If this function returns a failure,   *		then the values in *capp and *lbap are undefined. - *		This routine should always be called by - *		sd_send_scsi_READ_CAPACITY which will appy any device - *		specific adjustments to capacity and lbasize. + *		This routine should be called by sd_send_scsi_READ_CAPACITY + *              which will apply any device specific adjustments to capacity + *              and lbasize. One exception is it is also called by + *              sd_get_media_info_ext. In that function, there is no need to + *              adjust the capacity and lbasize.   *   *   Arguments: ssc   - ssc contains ptr to soft state struct for the target   *		capp - ptr to unsigned 64-bit variable to receive the   *			capacity value from the command.   *		lbap - ptr to unsigned 32-bit varaible to receive the   *			block size value from the command + *              psp  - ptr to unsigned 32-bit variable to receive the + *                      physical block size value from the command   *		path_flag - SD_PATH_DIRECT to use the USCSI "direct" chain and   *			the normal command waitq, or SD_PATH_DIRECT_PRIORITY   *			to use the USCSI "direct" chain and bypass the normal @@ -19533,7 +19903,7 @@ sd_send_scsi_READ_CAPACITY(sd_ssc_t *ssc, uint64_t *capp, uint32_t *lbap,  static int  sd_send_scsi_READ_CAPACITY_16(sd_ssc_t *ssc, uint64_t *capp, -	uint32_t *lbap, int path_flag) +	uint32_t *lbap, uint32_t *psp, int path_flag)  {  	struct	scsi_extended_sense	sense_buf;  	struct	uscsi_cmd	ucmd_buf; @@ -19541,6 +19911,8 @@ sd_send_scsi_READ_CAPACITY_16(sd_ssc_t *ssc, uint64_t *capp,  	uint64_t		*capacity16_buf;  	uint64_t		capacity;  	uint32_t		lbasize; +	uint32_t		pbsize; +	uint32_t		lbpb_exp;  	int			status;  	struct sd_lun		*un; @@ -19617,9 +19989,13 @@ sd_send_scsi_READ_CAPACITY_16(sd_ssc_t *ssc, uint64_t *capp,  		 *  bytes 8-11: Block length in bytes  		 *		(MSB in byte:8 & LSB in byte:11)  		 * +		 *  byte 13: LOGICAL BLOCKS PER PHYSICAL BLOCK EXPONENT  		 */  		capacity = BE_64(capacity16_buf[0]);  		lbasize = BE_32(*(uint32_t *)&capacity16_buf[1]); +		lbpb_exp = (BE_64(capacity16_buf[1]) >> 40) & 0x0f; + +		pbsize = lbasize << lbpb_exp;  		/*  		 * Done with capacity16_buf @@ -19666,9 +20042,11 @@ sd_send_scsi_READ_CAPACITY_16(sd_ssc_t *ssc, uint64_t *capp,  	*capp = capacity;  	*lbap = lbasize; +	*psp = pbsize;  	SD_TRACE(SD_LOG_IO, un, "sd_send_scsi_READ_CAPACITY_16: " -	    "capacity:0x%llx  lbasize:0x%x\n", capacity, lbasize); +	    "capacity:0x%llx  lbasize:0x%x, pbsize: 0x%x\n", +	    capacity, lbasize, pbsize);  	return (0);  } @@ -21443,6 +21821,7 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p)  		case DKIOCHOTPLUGGABLE:  		case DKIOCINFO:  		case DKIOCGMEDIAINFO: +		case DKIOCGMEDIAINFOEXT:  		case MHIOCENFAILFAST:  		case MHIOCSTATUS:  		case MHIOCTKOWN: @@ -21509,6 +21888,11 @@ skip_ready_valid:  		err = sd_get_media_info(dev, (caddr_t)arg, flag);  		break; +	case DKIOCGMEDIAINFOEXT: +		SD_TRACE(SD_LOG_IOCTL, un, "DKIOCGMEDIAINFOEXT\n"); +		err = sd_get_media_info_ext(dev, (caddr_t)arg, flag); +		break; +  	case DKIOCGGEOM:  	case DKIOCGVTOC:  	case DKIOCGEXTVTOC: @@ -22609,6 +22993,205 @@ no_assessment:  	return (rval);  } +/* + *    Function: sd_get_media_info_ext + * + * Description: This routine is the driver entry point for handling ioctl + *		requests for the media type or command set profile used by the + *		drive to operate on the media (DKIOCGMEDIAINFOEXT). The + *		difference this ioctl and DKIOCGMEDIAINFO is the return value + *		of this ioctl contains both logical block size and physical + *		block size. + * + * + *   Arguments: dev	- the device number + *		arg	- pointer to user provided dk_minfo_ext structure + *			  specifying the media type, logical block size, + *			  physical block size and disk capacity. + *		flag	- this argument is a pass through to ddi_copyxxx() + *			  directly from the mode argument of ioctl(). + * + * Return Code: 0 + *		EACCESS + *		EFAULT + *		ENXIO + *		EIO + */ + +static int +sd_get_media_info_ext(dev_t dev, caddr_t arg, int flag) +{ +	struct sd_lun		*un = NULL; +	struct uscsi_cmd	com; +	struct scsi_inquiry	*sinq; +	struct dk_minfo_ext	media_info_ext; +	u_longlong_t		media_capacity; +	uint64_t		capacity; +	uint_t			lbasize; +	uint_t			pbsize; +	uchar_t			*out_data; +	uchar_t			*rqbuf; +	int			rval = 0; +	int			rtn; +	sd_ssc_t		*ssc; + +	if ((un = ddi_get_soft_state(sd_state, SDUNIT(dev))) == NULL || +	    (un->un_state == SD_STATE_OFFLINE)) { +		return (ENXIO); +	} + +	SD_TRACE(SD_LOG_IOCTL_DKIO, un, "sd_get_media_info_ext: entry\n"); + +	out_data = kmem_zalloc(SD_PROFILE_HEADER_LEN, KM_SLEEP); +	rqbuf = kmem_zalloc(SENSE_LENGTH, KM_SLEEP); +	ssc = sd_ssc_init(un); + +	/* Issue a TUR to determine if the drive is ready with media present */ +	rval = sd_send_scsi_TEST_UNIT_READY(ssc, SD_CHECK_FOR_MEDIA); +	if (rval == ENXIO) { +		goto done; +	} else if (rval != 0) { +		sd_ssc_assessment(ssc, SD_FMT_IGNORE); +	} + +	/* Now get configuration data */ +	if (ISCD(un)) { +		media_info_ext.dki_media_type = DK_CDROM; + +		/* Allow SCMD_GET_CONFIGURATION to MMC devices only */ +		if (un->un_f_mmc_cap == TRUE) { +			rtn = sd_send_scsi_GET_CONFIGURATION(ssc, &com, rqbuf, +			    SENSE_LENGTH, out_data, SD_PROFILE_HEADER_LEN, +			    SD_PATH_STANDARD); + +			if (rtn) { +				/* +				 * We ignore all failures for CD and need to +				 * put the assessment before processing code +				 * to avoid missing assessment for FMA. +				 */ +				sd_ssc_assessment(ssc, SD_FMT_IGNORE); +				/* +				 * Failed for other than an illegal request +				 * or command not supported +				 */ +				if ((com.uscsi_status == STATUS_CHECK) && +				    (com.uscsi_rqstatus == STATUS_GOOD)) { +					if ((rqbuf[2] != KEY_ILLEGAL_REQUEST) || +					    (rqbuf[12] != 0x20)) { +						rval = EIO; +						goto no_assessment; +					} +				} +			} else { +				/* +				 * The GET CONFIGURATION command succeeded +				 * so set the media type according to the +				 * returned data +				 */ +				media_info_ext.dki_media_type = out_data[6]; +				media_info_ext.dki_media_type <<= 8; +				media_info_ext.dki_media_type |= out_data[7]; +			} +		} +	} else { +		/* +		 * The profile list is not available, so we attempt to identify +		 * the media type based on the inquiry data +		 */ +		sinq = un->un_sd->sd_inq; +		if ((sinq->inq_dtype == DTYPE_DIRECT) || +		    (sinq->inq_dtype == DTYPE_OPTICAL)) { +			/* This is a direct access device  or optical disk */ +			media_info_ext.dki_media_type = DK_FIXED_DISK; + +			if ((bcmp(sinq->inq_vid, "IOMEGA", 6) == 0) || +			    (bcmp(sinq->inq_vid, "iomega", 6) == 0)) { +				if ((bcmp(sinq->inq_pid, "ZIP", 3) == 0)) { +					media_info_ext.dki_media_type = DK_ZIP; +				} else if ( +				    (bcmp(sinq->inq_pid, "jaz", 3) == 0)) { +					media_info_ext.dki_media_type = DK_JAZ; +				} +			} +		} else { +			/* +			 * Not a CD, direct access or optical disk so return +			 * unknown media +			 */ +			media_info_ext.dki_media_type = DK_UNKNOWN; +		} +	} + +	/* +	 * Now read the capacity so we can provide the lbasize, +	 * pbsize and capacity. +	 */ +	rval = sd_send_scsi_READ_CAPACITY_16(ssc, &capacity, &lbasize, &pbsize, +	    SD_PATH_DIRECT); + +	if (rval != 0) { +		rval = sd_send_scsi_READ_CAPACITY(ssc, &capacity, &lbasize, +		    SD_PATH_DIRECT); + +		switch (rval) { +		case 0: +			pbsize = lbasize; +			media_capacity = capacity; +			/* +			 * sd_send_scsi_READ_CAPACITY() reports capacity in +			 * un->un_sys_blocksize chunks. So we need to convert +			 * it into cap.lbsize chunks. +			 */ +			if (un->un_f_has_removable_media) { +				media_capacity *= un->un_sys_blocksize; +				media_capacity /= lbasize; +			} +			break; +		case EACCES: +			rval = EACCES; +			goto done; +		default: +			rval = EIO; +			goto done; +		} +	} else { +		media_capacity = capacity; +	} + +	/* +	 * If lun is expanded dynamically, update the un structure. +	 */ +	mutex_enter(SD_MUTEX(un)); +	if ((un->un_f_blockcount_is_valid == TRUE) && +	    (un->un_f_tgt_blocksize_is_valid == TRUE) && +	    (capacity > un->un_blockcount)) { +		sd_update_block_info(un, lbasize, capacity); +	} +	mutex_exit(SD_MUTEX(un)); + +	media_info_ext.dki_lbsize = lbasize; +	media_info_ext.dki_capacity = media_capacity; +	media_info_ext.dki_pbsize = pbsize; + +	if (ddi_copyout(&media_info_ext, arg, sizeof (struct dk_minfo_ext), +	    flag)) { +		rval = EFAULT; +		goto no_assessment; +	} +done: +	if (rval != 0) { +		if (rval == EIO) +			sd_ssc_assessment(ssc, SD_FMT_STATUS_CHECK); +		else +			sd_ssc_assessment(ssc, SD_FMT_IGNORE); +	} +no_assessment: +	sd_ssc_fini(ssc); +	kmem_free(out_data, SD_PROFILE_HEADER_LEN); +	kmem_free(rqbuf, SENSE_LENGTH); +	return (rval); +}  /*   *    Function: sd_check_media @@ -24700,17 +25283,51 @@ sddump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	partition = SDPART(dev);  	SD_INFO(SD_LOG_DUMP, un, "sddump: partition = %d\n", partition); +	if (!(NOT_DEVBSIZE(un))) { +		int secmask = 0; +		int blknomask = 0; + +		blknomask = (un->un_tgt_blocksize / DEV_BSIZE) - 1; +		secmask = un->un_tgt_blocksize - 1; + +		if (blkno & blknomask) { +			SD_TRACE(SD_LOG_DUMP, un, +			    "sddump: dump start block not modulo %d\n", +			    un->un_tgt_blocksize); +			return (EINVAL); +		} + +		if ((nblk * DEV_BSIZE) & secmask) { +			SD_TRACE(SD_LOG_DUMP, un, +			    "sddump: dump length not modulo %d\n", +			    un->un_tgt_blocksize); +			return (EINVAL); +		} + +	} +  	/* Validate blocks to dump at against partition size. */  	(void) cmlb_partinfo(un->un_cmlbhandle, partition,  	    &nblks, &start_block, NULL, NULL, (void *)SD_PATH_DIRECT); -	if ((blkno + nblk) > nblks) { -		SD_TRACE(SD_LOG_DUMP, un, -		    "sddump: dump range larger than partition: " -		    "blkno = 0x%x, nblk = 0x%x, dkl_nblk = 0x%x\n", -		    blkno, nblk, nblks); -		return (EINVAL); +	if (NOT_DEVBSIZE(un)) { +		if ((blkno + nblk) > nblks) { +			SD_TRACE(SD_LOG_DUMP, un, +			    "sddump: dump range larger than partition: " +			    "blkno = 0x%x, nblk = 0x%x, dkl_nblk = 0x%x\n", +			    blkno, nblk, nblks); +			return (EINVAL); +		} +	} else { +		if (((blkno / (un->un_tgt_blocksize / DEV_BSIZE)) + +		    (nblk / (un->un_tgt_blocksize / DEV_BSIZE))) > nblks) { +			SD_TRACE(SD_LOG_DUMP, un, +			    "sddump: dump range larger than partition: " +			    "blkno = 0x%x, nblk = 0x%x, dkl_nblk = 0x%x\n", +			    blkno, nblk, nblks); +			return (EINVAL); +		}  	}  	mutex_enter(&un->un_pm_mutex); @@ -24813,7 +25430,12 @@ sddump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	 * Convert the partition-relative block number to a  	 * disk physical block number.  	 */ -	blkno += start_block; +	if (NOT_DEVBSIZE(un)) { +		blkno += start_block; +	} else { +		blkno = blkno / (un->un_tgt_blocksize / DEV_BSIZE); +		blkno += start_block; +	}  	SD_INFO(SD_LOG_DUMP, un, "sddump: disk blkno = 0x%x\n", blkno); @@ -24901,6 +25523,10 @@ sddump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	dma_resid = wr_bp->b_bcount;  	oblkno = blkno; +	if (!(NOT_DEVBSIZE(un))) { +		nblk = nblk / (un->un_tgt_blocksize / DEV_BSIZE); +	} +  	while (dma_resid != 0) {  	for (i = 0; i < SD_NDUMP_RETRIES; i++) { @@ -29894,7 +30520,7 @@ sd_tg_rdwr(dev_info_t *devi, uchar_t cmd, void *bufaddr,  		 * sys_blocksize != tgt_blocksize, need to re-adjust  		 * blkno and save the index to beginning of dk_label  		 */ -		first_byte  = SD_SYSBLOCKS2BYTES(un, start_block); +		first_byte  = SD_SYSBLOCKS2BYTES(start_block);  		real_addr = first_byte / un->un_tgt_blocksize;  		end_block = (first_byte + reqlength + diff --git a/usr/src/uts/common/os/dumpsubr.c b/usr/src/uts/common/os/dumpsubr.c index 201d6d1bfd..0753cc19da 100644 --- a/usr/src/uts/common/os/dumpsubr.c +++ b/usr/src/uts/common/os/dumpsubr.c @@ -20,7 +20,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -255,12 +255,12 @@ dumpinit(vnode_t *vp, char *name, int justchecking)  		if (VOP_OPEN(&cdev_vp, FREAD | FWRITE, kcred, NULL) == 0) {  			size_t blk_size;  			struct dk_cinfo dki; -			struct extvtoc vtoc; +			struct dk_minfo minf; -			if (VOP_IOCTL(cdev_vp, DKIOCGEXTVTOC, (intptr_t)&vtoc, -			    FKIOCTL, kcred, NULL, NULL) == 0 && -			    vtoc.v_sectorsz != 0) -				blk_size = vtoc.v_sectorsz; +			if (VOP_IOCTL(cdev_vp, DKIOCGMEDIAINFO, +			    (intptr_t)&minf, FKIOCTL, kcred, NULL, NULL) +			    == 0 && minf.dki_lbsize != 0) +				blk_size = minf.dki_lbsize;  			else  				blk_size = DEV_BSIZE; diff --git a/usr/src/uts/common/sys/dkio.h b/usr/src/uts/common/sys/dkio.h index 18f49e513a..caf7d7976d 100644 --- a/usr/src/uts/common/sys/dkio.h +++ b/usr/src/uts/common/sys/dkio.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -301,6 +301,11 @@ enum dkio_state { DKIO_NONE, DKIO_EJECTED, DKIO_INSERTED, DKIO_DEV_GONE };  #define	DKIOCGTEMPERATURE	(DKIOC|45)	/* get temperature */  /* + * ioctl to get the media info including physical block size + */ +#define	DKIOCGMEDIAINFOEXT	(DKIOC|48) + +/*   * Used for providing the temperature.   */ @@ -324,6 +329,17 @@ struct dk_minfo {  };  /* + * Used for Media info or the current profile info + * including physical block size if supported. + */ +struct dk_minfo_ext { +	uint_t		dki_media_type;	/* Media type or profile info */ +	uint_t		dki_lbsize;	/* Logical blocksize of media */ +	diskaddr_t	dki_capacity;	/* Capacity as # of dki_lbsize blks */ +	uint_t		dki_pbsize;	/* Physical blocksize of media */ +}; + +/*   * Media types or profiles known   */  #define	DK_UNKNOWN		0x00	/* Media inserted - type unknown */ diff --git a/usr/src/uts/common/sys/dklabel.h b/usr/src/uts/common/sys/dklabel.h index 01baa7157c..457c1ecadc 100644 --- a/usr/src/uts/common/sys/dklabel.h +++ b/usr/src/uts/common/sys/dklabel.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -207,7 +207,7 @@ struct dk_label {  	uint16_t	dkl_ncyl;	/* # of data cylinders */  	uint16_t	dkl_acyl;	/* # of alternate cylinders */  	uint16_t	dkl_nhead;	/* # of heads in this partition */ -	uint16_t	dkl_nsect;	/* # of 512 byte sectors per track */ +	uint16_t	dkl_nsect;	/* # of sectors per track */  	uint16_t	dkl_obs3;	/* obsolete */  	uint16_t	dkl_obs4;	/* obsolete */  	struct dk_map32	dkl_map[NDKMAP]; /* logical partition headers */ diff --git a/usr/src/uts/common/sys/scsi/targets/sddef.h b/usr/src/uts/common/sys/scsi/targets/sddef.h index c5bbc59ef1..90129e40c3 100644 --- a/usr/src/uts/common/sys/scsi/targets/sddef.h +++ b/usr/src/uts/common/sys/scsi/targets/sddef.h @@ -438,7 +438,8 @@ struct sd_lun {  						/* SYNC CACHE needs to be */  						/* sent in sdclose */  	    un_f_devid_transport_defined :1,	/* devid defined by transport */ -	    un_f_reserved		:12; +	    un_f_rmw_type		 :2,	/* RMW type */ +	    un_f_reserved		:10;  	/* Ptr to table of strings for ASC/ASCQ error message printing */  	struct scsi_asq_key_strings	*un_additional_codes; @@ -477,6 +478,8 @@ struct sd_lun {  	struct kmem_cache *un_wm_cache;	/* fast alloc in non-512 write case */  	uint_t		un_rmw_count;	/* count of read-modify-writes */  	struct sd_w_map	*un_wm;		/* head of sd_w_map chain */ +	uint64_t	un_rmw_incre_count;	/* count I/O */ +	timeout_id_t	un_rmw_msg_timeid;	/* for RMW message control */  	/* For timeout callback to issue a START STOP UNIT command */  	timeout_id_t	un_startstop_timeid; @@ -560,12 +563,12 @@ struct sd_lun {  	(blockcount * (un)->un_tgt_blocksize)  /* Convert a byte count to a number of system blocks */ -#define	SD_BYTES2SYSBLOCKS(un, bytecount)				\ -	((bytecount + (un->un_sys_blocksize - 1))/un->un_sys_blocksize) +#define	SD_BYTES2SYSBLOCKS(bytecount)				\ +	((bytecount + (DEV_BSIZE - 1))/DEV_BSIZE)  /* Convert a system block count to a number of bytes */ -#define	SD_SYSBLOCKS2BYTES(un, blockcount)				\ -	(blockcount * (un)->un_sys_blocksize) +#define	SD_SYSBLOCKS2BYTES(blockcount)				\ +	(blockcount * DEV_BSIZE)  /*   * Calculate the number of bytes needed to hold the requested number of bytes @@ -579,13 +582,19 @@ struct sd_lun {   * to the system block location.   */  #define	SD_TGTBYTEOFFSET(un, sysblk, tgtblk)				\ -	(SD_SYSBLOCKS2BYTES(un, sysblk) - SD_TGTBLOCKS2BYTES(un, tgtblk)) +	(SD_SYSBLOCKS2BYTES(sysblk) - SD_TGTBLOCKS2BYTES(un, tgtblk))  /*   * Calculate the target block location from the system block location   */  #define	SD_SYS2TGTBLOCK(un, blockcnt)					\ -	((blockcnt * un->un_sys_blocksize) / un->un_tgt_blocksize) +	(blockcnt / ((un)->un_tgt_blocksize / DEV_BSIZE)) + +/* + * Calculate the target block location from the system block location + */ +#define	SD_TGT2SYSBLOCK(un, blockcnt)					\ +	(blockcnt * ((un)->un_tgt_blocksize / DEV_BSIZE))  /*   * SD_DEFAULT_MAX_XFER_SIZE is the default value to bound the max xfer @@ -768,6 +777,12 @@ _NOTE(MUTEX_PROTECTS_DATA(sd_lun::un_fi_mutex,  #define	SD_WTYPE_RMW	0x002	/* Write requires read-modify-write */  #define	SD_WM_BUSY		0x100	/* write-map is busy */ +/* + * RMW type + */ +#define	SD_RMW_TYPE_DEFAULT	0	/* do rmw with warning message */ +#define	SD_RMW_TYPE_NO_WARNING	1	/* do rmw without warning message */ +#define	SD_RMW_TYPE_RETURN_ERROR	2	/* rmw disabled */  /* Device error kstats */  struct sd_errstats { @@ -1678,6 +1693,11 @@ struct sd_fm_internal {  #define	SD_RESTART_TIMEOUT		(drv_usectohz((clock_t)100000))  /* + * 10s misaligned I/O warning message interval + */ +#define	SD_RMW_MSG_PRINT_TIMEOUT	(drv_usectohz((clock_t)10000000)) + +/*   * 100 msec. is what we'll wait for certain retries for fibre channel   * targets, 0 msec for parallel SCSI.   */ diff --git a/usr/src/uts/common/xen/io/xdb.c b/usr/src/uts/common/xen/io/xdb.c index 16fd5aff9d..06551ebe85 100644 --- a/usr/src/uts/common/xen/io/xdb.c +++ b/usr/src/uts/common/xen/io/xdb.c @@ -1202,6 +1202,7 @@ xdb_open_device(xdb_t *vdp)  {  	dev_info_t *dip = vdp->xs_dip;  	uint64_t devsize; +	int blksize;  	char *nodepath;  	ASSERT(MUTEX_HELD(&vdp->xs_cbmutex)); @@ -1252,7 +1253,17 @@ xdb_open_device(xdb_t *vdp)  		kmem_free(nodepath, MAXPATHLEN);  		return (DDI_FAILURE);  	} -	vdp->xs_sectors = devsize / XB_BSIZE; + +	blksize = ldi_prop_get_int64(vdp->xs_ldi_hdl, +	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, +	    "blksize", DEV_BSIZE); +	if (blksize == DEV_BSIZE) +		blksize = ldi_prop_get_int(vdp->xs_ldi_hdl, +		    LDI_DEV_T_ANY | DDI_PROP_DONTPASS | +		    DDI_PROP_NOTPROM, "device-blksize", DEV_BSIZE); + +	vdp->xs_sec_size = blksize; +	vdp->xs_sectors = devsize / blksize;  	/* check if the underlying device is a CD/DVD disc */  	if (ldi_prop_get_int(vdp->xs_ldi_hdl, LDI_DEV_T_ANY | DDI_PROP_DONTPASS, @@ -1388,13 +1399,12 @@ trans_retry:  	/* If feature-barrier isn't present in xenstore, add it.  */  	fb_exists = xenbus_exists(xsname, XBP_FB); -	/* hard-coded 512-byte sector size */ -	ssize = DEV_BSIZE; +	ssize = (vdp->xs_sec_size == 0) ? DEV_BSIZE : vdp->xs_sec_size;  	sectors = vdp->xs_sectors;  	if (((!fb_exists &&  	    (err = xenbus_printf(xbt, xsname, XBP_FB, "%d", 1)))) ||  	    (err = xenbus_printf(xbt, xsname, XBP_INFO, "%u", dinfo)) || -	    (err = xenbus_printf(xbt, xsname, "sector-size", "%u", ssize)) || +	    (err = xenbus_printf(xbt, xsname, XBP_SECTOR_SIZE, "%u", ssize)) ||  	    (err = xenbus_printf(xbt, xsname,  	    XBP_SECTORS, "%"PRIu64, sectors)) ||  	    (err = xenbus_printf(xbt, xsname, "instance", "%d", instance)) || diff --git a/usr/src/uts/common/xen/io/xdb.h b/usr/src/uts/common/xen/io/xdb.h index f8046e8219..2173ca6ad9 100644 --- a/usr/src/uts/common/xen/io/xdb.h +++ b/usr/src/uts/common/xen/io/xdb.h @@ -113,6 +113,8 @@ struct xdb {  	uint32_t	xs_type;  	/* # of total sectors */  	uint64_t	xs_sectors; +	/* sector size if existed */ +	uint_t		xs_sec_size;  	/* blkif I/O request ring buffer */  	xendev_ring_t	*xs_ring;  	/* handle to access the ring buffer */ diff --git a/usr/src/uts/common/xen/io/xdf.c b/usr/src/uts/common/xen/io/xdf.c index 109421797d..ef50b2bec7 100644 --- a/usr/src/uts/common/xen/io/xdf.c +++ b/usr/src/uts/common/xen/io/xdf.c @@ -478,7 +478,6 @@ vreq_setup(xdf_t *vdp, v_req_t *vreq)  		if (!ALIGNED_XFER(bp)) {  			if (bp->b_flags & (B_PAGEIO | B_PHYS))  				bp_mapin(bp); -  			rc = ddi_dma_mem_alloc(vreq->v_memdmahdl,  			    roundup(bp->b_bcount, XB_BSIZE), &xc_acc_attr,  			    DDI_DMA_STREAMING, xdf_dmacallback, (caddr_t)vdp, @@ -1638,11 +1637,13 @@ xdf_get_flush_block(xdf_t *vdp)  	/*  	 * Get a DEV_BSIZE aligned bufer  	 */ -	vdp->xdf_flush_mem = kmem_alloc(DEV_BSIZE * 2, KM_SLEEP); +	vdp->xdf_flush_mem = kmem_alloc(vdp->xdf_xdev_secsize * 2, KM_SLEEP);  	vdp->xdf_cache_flush_block = -	    (char *)P2ROUNDUP((uintptr_t)(vdp->xdf_flush_mem), DEV_BSIZE); +	    (char *)P2ROUNDUP((uintptr_t)(vdp->xdf_flush_mem), +	    (int)vdp->xdf_xdev_secsize); +  	if (xdf_lb_rdwr(vdp->xdf_dip, TG_READ, vdp->xdf_cache_flush_block, -	    xdf_flush_block, DEV_BSIZE, NULL) != 0) +	    xdf_flush_block, vdp->xdf_xdev_secsize, NULL) != 0)  		return (DDI_FAILURE);  	return (DDI_SUCCESS);  } @@ -1746,7 +1747,7 @@ xdf_synthetic_pgeom(dev_info_t *dip, cmlb_geom_t *geomp)  	geomp->g_acyl = 0;  	geomp->g_nhead = XDF_NHEADS;  	geomp->g_nsect = XDF_NSECTS; -	geomp->g_secsize = XB_BSIZE; +	geomp->g_secsize = vdp->xdf_xdev_secsize;  	geomp->g_capacity = vdp->xdf_xdev_nblocks;  	geomp->g_intrlv = 0;  	geomp->g_rpm = 7200; @@ -1764,6 +1765,7 @@ xdf_setstate_connected(xdf_t *vdp)  	dev_info_t	*dip = vdp->xdf_dip;  	cmlb_geom_t	pgeom;  	diskaddr_t	nblocks = 0; +	uint_t		secsize = 0;  	char		*oename, *xsname, *str;  	uint_t		dinfo; @@ -1793,6 +1795,7 @@ xdf_setstate_connected(xdf_t *vdp)  	 */  	if (xenbus_gather(XBT_NULL, oename,  	    XBP_SECTORS, "%"SCNu64, &nblocks, +	    XBP_SECTOR_SIZE, "%u", &secsize,  	    XBP_INFO, "%u", &dinfo,  	    NULL) != 0) {  		cmn_err(CE_WARN, "xdf@%s: xdf_setstate_connected: " @@ -1808,7 +1811,10 @@ xdf_setstate_connected(xdf_t *vdp)  		dinfo |= VDISK_CDROM;  	strfree(str); +	if (secsize == 0 || !(ISP2(secsize / DEV_BSIZE))) +		secsize = DEV_BSIZE;  	vdp->xdf_xdev_nblocks = nblocks; +	vdp->xdf_xdev_secsize = secsize;  #ifdef _ILP32  	if (vdp->xdf_xdev_nblocks > DK_MAX_BLOCKS) {  		cmn_err(CE_WARN, "xdf@%s: xdf_setstate_connected: " @@ -2373,6 +2379,14 @@ xdf_lb_getattribute(dev_info_t *dip, tg_attribute_t *tgattributep)  int  xdf_lb_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)  { +	int instance; +	xdf_t   *vdp; + +	instance = ddi_get_instance(dip); + +	if ((vdp = ddi_get_soft_state(xdf_ssp, instance)) == NULL) +		return (ENXIO); +  	switch (cmd) {  	case TG_GETPHYGEOM:  		return (xdf_lb_getpgeom(dip, (cmlb_geom_t *)arg)); @@ -2381,7 +2395,9 @@ xdf_lb_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)  	case TG_GETCAPACITY:  		return (xdf_lb_getcap(dip, (diskaddr_t *)arg));  	case TG_GETBLOCKSIZE: -		*(uint32_t *)arg = XB_BSIZE; +		mutex_enter(&vdp->xdf_cb_lk); +		*(uint32_t *)arg = vdp->xdf_xdev_secsize; +		mutex_exit(&vdp->xdf_cb_lk);  		return (0);  	case TG_GETATTR:  		return (xdf_lb_getattribute(dip, (tg_attribute_t *)arg)); @@ -2404,7 +2420,8 @@ xdf_lb_rdwr(dev_info_t *dip, uchar_t cmd, void *bufp,  	/* We don't allow IO from the oe_change callback thread */  	ASSERT(curthread != vdp->xdf_oe_change_thread); -	if ((start + (reqlen >> DEV_BSHIFT)) > vdp->xdf_pgeom.g_capacity) +	if ((start + ((reqlen / (vdp->xdf_xdev_secsize / DEV_BSIZE)) +	    >> DEV_BSHIFT)) > vdp->xdf_pgeom.g_capacity)  		return (EINVAL);  	bp = getrbuf(KM_SLEEP); @@ -2412,9 +2429,10 @@ xdf_lb_rdwr(dev_info_t *dip, uchar_t cmd, void *bufp,  		bp->b_flags = B_BUSY | B_READ;  	else  		bp->b_flags = B_BUSY | B_WRITE; +  	bp->b_un.b_addr = bufp;  	bp->b_bcount = reqlen; -	bp->b_blkno = start; +	bp->b_blkno = start * (vdp->xdf_xdev_secsize / DEV_BSIZE);  	bp->b_edev = DDI_DEV_T_NONE; /* don't have dev_t */  	mutex_enter(&vdp->xdf_dev_lk); @@ -2582,7 +2600,7 @@ xdf_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,  	case DKIOCGMEDIAINFO: {  		struct dk_minfo media_info; -		media_info.dki_lbsize = DEV_BSIZE; +		media_info.dki_lbsize = vdp->xdf_xdev_secsize;  		media_info.dki_capacity = vdp->xdf_pgeom.g_capacity;  		if (XD_IS_CD(vdp))  			media_info.dki_media_type = DK_CDROM; @@ -2664,7 +2682,7 @@ xdf_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,  		    !xdf_barrier_flush_disable) {  			rv = xdf_lb_rdwr(vdp->xdf_dip, TG_WRITE,  			    vdp->xdf_cache_flush_block, xdf_flush_block, -			    DEV_BSIZE, (void *)dev); +			    vdp->xdf_xdev_secsize, (void *)dev);  		} else {  			return (ENOTTY);  		} @@ -2686,6 +2704,7 @@ xdf_strategy(struct buf *bp)  	xdf_t	*vdp;  	minor_t minor;  	diskaddr_t p_blkct, p_blkst; +	daddr_t blkno;  	ulong_t nblks;  	int part; @@ -2726,16 +2745,24 @@ xdf_strategy(struct buf *bp)  		mutex_enter(&vdp->xdf_dev_lk);  	} +	/* +	 * Adjust the real blkno and bcount according to the underline +	 * physical sector size. +	 */ +	blkno = bp->b_blkno / (vdp->xdf_xdev_secsize / XB_BSIZE); +  	/* check for a starting block beyond the disk or partition limit */ -	if (bp->b_blkno > p_blkct) { +	if (blkno > p_blkct) {  		DPRINTF(IO_DBG, ("xdf@%s: block %lld exceeds VBD size %"PRIu64, -		    vdp->xdf_addr, (longlong_t)bp->b_blkno, (uint64_t)p_blkct)); +		    vdp->xdf_addr, (longlong_t)blkno, (uint64_t)p_blkct)); +		mutex_exit(&vdp->xdf_dev_lk);  		xdf_io_err(bp, EINVAL, 0);  		return (0);  	}  	/* Legacy: don't set error flag at this case */ -	if (bp->b_blkno == p_blkct) { +	if (blkno == p_blkct) { +		mutex_exit(&vdp->xdf_dev_lk);  		bp->b_resid = bp->b_bcount;  		biodone(bp);  		return (0); @@ -2747,14 +2774,29 @@ xdf_strategy(struct buf *bp)  	bp->av_back = bp->av_forw = NULL;  	/* Adjust for partial transfer, this will result in an error later */ -	nblks = bp->b_bcount >> XB_BSHIFT; -	if ((bp->b_blkno + nblks) > p_blkct) { -		bp->b_resid = ((bp->b_blkno + nblks) - p_blkct) << XB_BSHIFT; +	if (vdp->xdf_xdev_secsize != 0 && +	    vdp->xdf_xdev_secsize != XB_BSIZE) { +		nblks = bp->b_bcount / vdp->xdf_xdev_secsize; +	} else { +		nblks = bp->b_bcount >> XB_BSHIFT; +	} + +	if ((blkno + nblks) > p_blkct) { +		if (vdp->xdf_xdev_secsize != 0 && +		    vdp->xdf_xdev_secsize != XB_BSIZE) { +			bp->b_resid = +			    ((blkno + nblks) - p_blkct) * +			    vdp->xdf_xdev_secsize; +		} else { +			bp->b_resid = +			    ((blkno + nblks) - p_blkct) << +			    XB_BSHIFT; +		}  		bp->b_bcount -= bp->b_resid;  	}  	DPRINTF(IO_DBG, ("xdf@%s: strategy blk %lld len %lu\n", -	    vdp->xdf_addr, (longlong_t)bp->b_blkno, (ulong_t)bp->b_bcount)); +	    vdp->xdf_addr, (longlong_t)blkno, (ulong_t)bp->b_bcount));  	/* Fix up the buf struct */  	bp->b_flags |= B_BUSY; @@ -2792,6 +2834,9 @@ xdf_read(dev_t dev, struct uio *uiop, cred_t *credp)  	    NULL, NULL, NULL, NULL))  		return (ENXIO); +	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp)) +		return (ENOSPC); +  	if (U_INVAL(uiop))  		return (EINVAL); @@ -2822,7 +2867,7 @@ xdf_write(dev_t dev, struct uio *uiop, cred_t *credp)  	    NULL, NULL, NULL, NULL))  		return (ENXIO); -	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt)) +	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))  		return (ENOSPC);  	if (U_INVAL(uiop)) @@ -2853,7 +2898,7 @@ xdf_aread(dev_t dev, struct aio_req *aiop, cred_t *credp)  	    NULL, NULL, NULL, NULL))  		return (ENXIO); -	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt)) +	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))  		return (ENOSPC);  	if (U_INVAL(uiop)) @@ -2884,7 +2929,7 @@ xdf_awrite(dev_t dev, struct aio_req *aiop, cred_t *credp)  	    NULL, NULL, NULL, NULL))  		return (ENXIO); -	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt)) +	if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))  		return (ENOSPC);  	if (U_INVAL(uiop)) @@ -2921,9 +2966,11 @@ xdf_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	    NULL, NULL, NULL))  		return (ENXIO); -	if ((blkno + nblk) > p_blkcnt) { +	if ((blkno + nblk) > +	    (p_blkcnt * (vdp->xdf_xdev_secsize / XB_BSIZE))) {  		cmn_err(CE_WARN, "xdf@%s: block %ld exceeds VBD size %"PRIu64, -		    vdp->xdf_addr, blkno + nblk, (uint64_t)p_blkcnt); +		    vdp->xdf_addr, (daddr_t)((blkno + nblk) / +		    (vdp->xdf_xdev_secsize / XB_BSIZE)), (uint64_t)p_blkcnt);  		return (EINVAL);  	} @@ -3451,7 +3498,7 @@ xdf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)  	mutex_destroy(&vdp->xdf_cb_lk);  	mutex_destroy(&vdp->xdf_dev_lk);  	if (vdp->xdf_cache_flush_block != NULL) -		kmem_free(vdp->xdf_flush_mem, 2 * DEV_BSIZE); +		kmem_free(vdp->xdf_flush_mem, 2 * vdp->xdf_xdev_secsize);  	ddi_soft_state_free(xdf_ssp, instance);  	return (DDI_SUCCESS);  } diff --git a/usr/src/uts/common/xen/io/xdf.h b/usr/src/uts/common/xen/io/xdf.h index a3319f70a3..f2a2a82dd5 100644 --- a/usr/src/uts/common/xen/io/xdf.h +++ b/usr/src/uts/common/xen/io/xdf.h @@ -48,7 +48,7 @@ extern "C" {  #define	XB_BSIZE	DEV_BSIZE  #define	XB_BMASK	(XB_BSIZE - 1)  #define	XB_BSHIFT	9 -#define	XB_DTOB(bn)	((bn) << XB_BSHIFT) +#define	XB_DTOB(bn, vdp)	((bn) * (vdp)->xdf_xdev_secsize)  #define	XB_MAX_SEGLEN	(8 * XB_BSIZE)  #define	XB_SEGOFFSET	(XB_MAX_SEGLEN - 1) @@ -222,6 +222,7 @@ typedef struct xdf {  	kcondvar_t	xdf_dev_cv; /* cv used in I/O path */  	uint_t		xdf_dinfo; /* disk info from backend xenstore */  	diskaddr_t	xdf_xdev_nblocks; /* total size in block */ +	uint_t		xdf_xdev_secsize; /* disk blksize from backend */  	cmlb_geom_t	xdf_pgeom;  	boolean_t	xdf_pgeom_set;  	boolean_t	xdf_pgeom_fixed; diff --git a/usr/src/uts/common/xen/sys/xendev.h b/usr/src/uts/common/xen/sys/xendev.h index 8e5921dc3f..dad4ad222f 100644 --- a/usr/src/uts/common/xen/sys/xendev.h +++ b/usr/src/uts/common/xen/sys/xendev.h @@ -52,6 +52,7 @@ extern "C" {  /*   * Xenbus property interfaces, initialized by backend disk driver   */ +#define	XBP_SECTOR_SIZE	"sector-size"		/* backend prop: uint */  #define	XBP_SECTORS	"sectors"		/* backend prop: uint64 */  #define	XBP_INFO	"info"			/* backend prop: uint */  #define	XBP_FB		"feature-barrier"	/* backend prop: boolean int */ diff --git a/usr/src/uts/sun4v/io/vdc.c b/usr/src/uts/sun4v/io/vdc.c index 6c5d37b940..b7729adeed 100644 --- a/usr/src/uts/sun4v/io/vdc.c +++ b/usr/src/uts/sun4v/io/vdc.c @@ -150,6 +150,7 @@ static void	vdc_store_label_vtoc(vdc_t *, struct dk_geom *,  static void	vdc_store_label_unk(vdc_t *vdc);  static boolean_t vdc_is_opened(vdc_t *vdc);  static void	vdc_update_size(vdc_t *vdc, size_t, size_t, size_t); +static int	vdc_update_vio_bsize(vdc_t *vdc, uint32_t);  /* handshake with vds */  static int		vdc_init_ver_negotiation(vdc_t *vdc, vio_ver_t ver); @@ -621,8 +622,10 @@ vdc_do_attach(dev_info_t *dip)  	vdc->state	= VDC_STATE_INIT;  	vdc->lifecycle	= VDC_LC_ATTACHING;  	vdc->session_id = 0; -	vdc->block_size = DEV_BSIZE; -	vdc->max_xfer_sz = maxphys / DEV_BSIZE; +	vdc->vdisk_bsize = DEV_BSIZE; +	vdc->vio_bmask = 0; +	vdc->vio_bshift = 0; +	vdc->max_xfer_sz = maxphys / vdc->vdisk_bsize;  	/*  	 * We assume, for now, that the vDisk server will export 'read' @@ -943,7 +946,7 @@ vdc_set_err_kstats(vdc_t *vdc)  	stp = (vd_err_stats_t *)vdc->err_stats->ks_data;  	ASSERT(stp != NULL); -	stp->vd_capacity.value.ui64 = vdc->vdisk_size * vdc->block_size; +	stp->vd_capacity.value.ui64 = vdc->vdisk_size * vdc->vdisk_bsize;  	(void) strcpy(stp->vd_vid.value.c, "SUN");  	(void) strcpy(stp->vd_pid.value.c, "VDSK"); @@ -1124,7 +1127,7 @@ vdc_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,  		    name, valuep, lengthp));  	}  	nblocks = vdc->slice[VDCPART(dev)].nblocks; -	blksize = vdc->block_size; +	blksize = vdc->vdisk_bsize;  	mutex_exit(&vdc->lock);  	return (ddi_prop_op_nblocks_blksize(dev, dip, prop_op, mod_flags, @@ -1382,6 +1385,7 @@ vdc_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	size_t	nbytes = nblk * DEV_BSIZE;  	int	instance = VDCUNIT(dev);  	vdc_t	*vdc = NULL; +	diskaddr_t vio_blkno;  	if ((vdc = ddi_get_soft_state(vdc_state, instance)) == NULL) {  		cmn_err(CE_NOTE, "[%d] Couldn't get state structure", instance); @@ -1390,8 +1394,16 @@ vdc_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  	DMSG(vdc, 2, "[%d] dump %ld bytes at block 0x%lx : addr=0x%p\n",  	    instance, nbytes, blkno, (void *)addr); + +	/* convert logical block to vio block */ +	if ((blkno & vdc->vio_bmask) != 0) { +		DMSG(vdc, 0, "Misaligned block number (%lu)\n", blkno); +		return (EINVAL); +	} +	vio_blkno = blkno >> vdc->vio_bshift; +  	rv = vdc_send_request(vdc, VD_OP_BWRITE, addr, nbytes, -	    VDCPART(dev), blkno, CB_STRATEGY, 0, VIO_write_dir); +	    VDCPART(dev), vio_blkno, CB_STRATEGY, 0, VIO_write_dir);  	if (rv) {  		DMSG(vdc, 0, "Failed to do a disk dump (err=%d)\n", rv);  		return (rv); @@ -1422,6 +1434,7 @@ vdc_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)  static int  vdc_strategy(struct buf *buf)  { +	diskaddr_t vio_blkno;  	int	rv = -1;  	vdc_t	*vdc = NULL;  	int	instance = VDCUNIT(buf->b_edev); @@ -1448,8 +1461,21 @@ vdc_strategy(struct buf *buf)  		slice = VDCPART(buf->b_edev);  	} +	/* +	 * In the buf structure, b_lblkno represents a logical block number +	 * using a block size of 512 bytes. For the VIO request, this block +	 * number has to be converted to be represented with the block size +	 * used by the VIO protocol. +	 */ +	if ((buf->b_lblkno & vdc->vio_bmask) != 0) { +		bioerror(buf, EINVAL); +		biodone(buf); +		return (0); +	} +	vio_blkno = buf->b_lblkno >> vdc->vio_bshift; +  	rv = vdc_send_request(vdc, op, (caddr_t)buf->b_un.b_addr, -	    buf->b_bcount, slice, buf->b_lblkno, +	    buf->b_bcount, slice, vio_blkno,  	    CB_STRATEGY, buf, (op == VD_OP_BREAD) ? VIO_read_dir :  	    VIO_write_dir); @@ -1494,8 +1520,8 @@ vdc_min(struct buf *bufp)  	vdc = ddi_get_soft_state(vdc_state, instance);  	VERIFY(vdc != NULL); -	if (bufp->b_bcount > (vdc->max_xfer_sz * vdc->block_size)) { -		bufp->b_bcount = vdc->max_xfer_sz * vdc->block_size; +	if (bufp->b_bcount > (vdc->max_xfer_sz * vdc->vdisk_bsize)) { +		bufp->b_bcount = vdc->max_xfer_sz * vdc->vdisk_bsize;  	}  } @@ -1670,7 +1696,7 @@ vdc_init_attr_negotiation(vdc_t *vdc)  	pkt.tag.vio_sid = vdc->session_id;  	/* fill in payload */  	pkt.max_xfer_sz = vdc->max_xfer_sz; -	pkt.vdisk_block_size = vdc->block_size; +	pkt.vdisk_block_size = vdc->vdisk_bsize;  	pkt.xfer_mode = VIO_DRING_MODE_V1_0;  	pkt.operations = 0;	/* server will set bits of valid operations */  	pkt.vdisk_type = 0;	/* server will set to valid device type */ @@ -2605,13 +2631,13 @@ vdc_init_descriptor_ring(vdc_t *vdc)  		 * as we do not have the capability to split requests over  		 * multiple DRing entries.  		 */ -		if ((vdc->max_xfer_sz * vdc->block_size) < maxphys) { +		if ((vdc->max_xfer_sz * vdc->vdisk_bsize) < maxphys) {  			DMSG(vdc, 0, "[%d] using minimum DRing size\n",  			    vdc->instance);  			vdc->dring_max_cookies = maxphys / PAGESIZE;  		} else {  			vdc->dring_max_cookies = -			    (vdc->max_xfer_sz * vdc->block_size) / PAGESIZE; +			    (vdc->max_xfer_sz * vdc->vdisk_bsize) / PAGESIZE;  		}  		vdc->dring_entry_size = (sizeof (vd_dring_entry_t) +  		    (sizeof (ldc_mem_cookie_t) * @@ -4864,6 +4890,17 @@ vdc_handle_attr_msg(vdc_t *vdc, vd_attr_msg_t *attr_msg)  			    vdc->instance);  			attr_msg->vdisk_size = 0;  		} + +		/* update the VIO block size */ +		if (attr_msg->vdisk_block_size > 0 && +		    vdc_update_vio_bsize(vdc, +		    attr_msg->vdisk_block_size) != 0) { +			DMSG(vdc, 0, "[%d] Invalid block size (%u) from vds", +			    vdc->instance, attr_msg->vdisk_block_size); +			status = EINVAL; +			break; +		} +  		/* update disk, block and transfer sizes */  		vdc_update_size(vdc, attr_msg->vdisk_size,  		    attr_msg->vdisk_block_size, attr_msg->max_xfer_sz); @@ -4877,7 +4914,7 @@ vdc_handle_attr_msg(vdc_t *vdc, vd_attr_msg_t *attr_msg)  		DMSG(vdc, 0, "[%d] max_xfer_sz: sent %lx acked %lx\n",  		    vdc->instance, vdc->max_xfer_sz, attr_msg->max_xfer_sz);  		DMSG(vdc, 0, "[%d] vdisk_block_size: sent %lx acked %x\n", -		    vdc->instance, vdc->block_size, +		    vdc->instance, vdc->vdisk_bsize,  		    attr_msg->vdisk_block_size);  		if ((attr_msg->xfer_mode != VIO_DRING_MODE_V1_0) || @@ -5266,7 +5303,7 @@ vdc_dkio_partition(vdc_t *vdc, caddr_t arg, int flag)  		return (EFAULT);  	} -	VD_EFI_DEV_SET(edev, vdc, vd_process_efi_ioctl); +	VDC_EFI_DEV_SET(edev, vdc, vd_process_efi_ioctl);  	if ((rv = vd_efi_alloc_and_read(&edev, &gpt, &gpe)) != 0) {  		return (rv); @@ -5307,7 +5344,7 @@ vdc_dkio_partition(vdc_t *vdc, caddr_t arg, int flag)   *	flag	- ioctl flags   */  static int -vdc_dioctl_rwcmd(dev_t dev, caddr_t arg, int flag) +vdc_dioctl_rwcmd(vdc_t *vdc, caddr_t arg, int flag)  {  	struct dadkio_rwcmd32 rwcmd32;  	struct dadkio_rwcmd rwcmd; @@ -5351,7 +5388,7 @@ vdc_dioctl_rwcmd(dev_t dev, caddr_t arg, int flag)  	bzero((caddr_t)&auio, sizeof (struct uio));  	auio.uio_iov    = &aiov;  	auio.uio_iovcnt = 1; -	auio.uio_loffset = rwcmd.blkaddr * DEV_BSIZE; +	auio.uio_loffset = rwcmd.blkaddr * vdc->vdisk_bsize;  	auio.uio_resid  = rwcmd.buflen;  	auio.uio_segflg = flag & FKIOCTL ? UIO_SYSSPACE : UIO_USERSPACE; @@ -5363,7 +5400,8 @@ vdc_dioctl_rwcmd(dev_t dev, caddr_t arg, int flag)  	 */  	buf->b_private = (void *)VD_SLICE_NONE; -	status = physio(vdc_strategy, buf, dev, rw, vdc_min, &auio); +	status = physio(vdc_strategy, buf, VD_MAKE_DEV(vdc->instance, 0), +	    rw, vdc_min, &auio);  	biofini(buf);  	kmem_free(buf, sizeof (buf_t)); @@ -6639,14 +6677,23 @@ vdc_check_capacity(vdc_t *vdc)  	if ((rv = vdc_get_capacity(vdc, &dsk_size, &blk_size)) != 0)  		return (rv); -	if (dsk_size == VD_SIZE_UNKNOWN || dsk_size == 0) +	if (dsk_size == VD_SIZE_UNKNOWN || dsk_size == 0 || blk_size == 0)  		return (EINVAL);  	mutex_enter(&vdc->lock); -	vdc_update_size(vdc, dsk_size, blk_size, vdc->max_xfer_sz); +	/* +	 * First try to update the VIO block size (which is the same as the +	 * vdisk block size). If this returns an error then that means that +	 * we can not use that block size so basically the vdisk is unusable +	 * and we return an error. +	 */ +	rv = vdc_update_vio_bsize(vdc, blk_size); +	if (rv == 0) +		vdc_update_size(vdc, dsk_size, blk_size, vdc->max_xfer_sz); +  	mutex_exit(&vdc->lock); -	return (0); +	return (rv);  }  /* @@ -6969,7 +7016,7 @@ vd_process_ioctl(dev_t dev, int cmd, caddr_t arg, int mode, int *rvalp)  	case DIOCTL_RWCMD:  	{ -		return (vdc_dioctl_rwcmd(dev, arg, mode)); +		return (vdc_dioctl_rwcmd(vdc, arg, mode));  	}  	case DKIOCGAPART: @@ -7604,7 +7651,7 @@ vdc_create_fake_geometry(vdc_t *vdc)  	(void) strcpy(vdc->cinfo->dki_cname, VDC_DRIVER_NAME);  	(void) strcpy(vdc->cinfo->dki_dname, VDC_DRIVER_NAME); -	/* max_xfer_sz is #blocks so we don't need to divide by DEV_BSIZE */ +	/* max_xfer_sz is #blocks so we don't need to divide by vdisk_bsize */  	vdc->cinfo->dki_maxtransfer = vdc->max_xfer_sz;  	/* @@ -7660,7 +7707,7 @@ vdc_create_fake_geometry(vdc_t *vdc)  	}  	vdc->minfo->dki_capacity = vdc->vdisk_size; -	vdc->minfo->dki_lbsize = vdc->block_size; +	vdc->minfo->dki_lbsize = vdc->vdisk_bsize;  }  static ushort_t @@ -7692,7 +7739,7 @@ vdc_update_size(vdc_t *vdc, size_t dsk_size, size_t blk_size, size_t xfr_size)  	 * update anything.  	 */  	if (dsk_size == VD_SIZE_UNKNOWN || dsk_size == 0 || -	    (blk_size == vdc->block_size && dsk_size == vdc->vdisk_size && +	    (blk_size == vdc->vdisk_bsize && dsk_size == vdc->vdisk_size &&  	    xfr_size == vdc->max_xfer_sz))  		return; @@ -7706,13 +7753,11 @@ vdc_update_size(vdc_t *vdc, size_t dsk_size, size_t blk_size, size_t xfr_size)  	if ((xfr_size * blk_size) > (PAGESIZE * DEV_BSIZE)) {  		DMSG(vdc, 0, "[%d] vds block transfer size too big;"  		    " using max supported by vdc", vdc->instance); -		xfr_size = maxphys / DEV_BSIZE; -		dsk_size = (dsk_size * blk_size) / DEV_BSIZE; -		blk_size = DEV_BSIZE; +		xfr_size = maxphys / blk_size;  	}  	vdc->max_xfer_sz = xfr_size; -	vdc->block_size = blk_size; +	vdc->vdisk_bsize = blk_size;  	vdc->vdisk_size = dsk_size;  	stp = (vd_err_stats_t *)vdc->err_stats->ks_data; @@ -7723,6 +7768,50 @@ vdc_update_size(vdc_t *vdc, size_t dsk_size, size_t blk_size, size_t xfr_size)  }  /* + * Update information about the VIO block size. The VIO block size is the + * same as the vdisk block size which is stored in vdc->vdisk_bsize so we + * do not store that information again. + * + * However, buf structures will always use a logical block size of 512 bytes + * (DEV_BSIZE) and we will need to convert logical block numbers to VIO block + * numbers for each read or write operation using vdc_strategy(). To speed up + * this conversion, we expect the VIO block size to be a power of 2 and a + * multiple 512 bytes (DEV_BSIZE), and we cache some useful information. + * + * The function return EINVAL if the new VIO block size (blk_size) is not a + * power of 2 or not a multiple of 512 bytes, otherwise it returns 0. + */ +static int +vdc_update_vio_bsize(vdc_t *vdc, uint32_t blk_size) +{ +	uint32_t ratio, n; +	int nshift = 0; + +	vdc->vio_bmask = 0; +	vdc->vio_bshift = 0; + +	ASSERT(blk_size > 0); + +	if ((blk_size % DEV_BSIZE) != 0) +		return (EINVAL); + +	ratio = blk_size / DEV_BSIZE; + +	for (n = ratio; n > 1; n >>= 1) { +		if ((n & 0x1) != 0) { +			/* blk_size is not a power of 2 */ +			return (EINVAL); +		} +		nshift++; +	} + +	vdc->vio_bshift = nshift; +	vdc->vio_bmask = ratio - 1; + +	return (0); +} + +/*   * Function:   *	vdc_validate_geometry   * @@ -7747,7 +7836,7 @@ vdc_validate_geometry(vdc_t *vdc)  	buf_t	*buf;	/* BREAD requests need to be in a buf_t structure */  	dev_t	dev;  	int	rv, rval; -	struct dk_label label; +	struct dk_label *label;  	struct dk_geom geom;  	struct extvtoc vtoc;  	efi_gpt_t *gpt; @@ -7786,7 +7875,7 @@ vdc_validate_geometry(vdc_t *vdc)  			return (EIO);  		} -		VD_EFI_DEV_SET(edev, vdc, vd_process_efi_ioctl); +		VDC_EFI_DEV_SET(edev, vdc, vd_process_efi_ioctl);  		rv = vd_efi_alloc_and_read(&edev, &gpt, &gpe); @@ -7870,14 +7959,15 @@ vdc_validate_geometry(vdc_t *vdc)  	/*  	 * Read disk label from start of disk  	 */ +	label = kmem_alloc(vdc->vdisk_bsize, KM_SLEEP);  	buf = kmem_alloc(sizeof (buf_t), KM_SLEEP);  	bioinit(buf); -	buf->b_un.b_addr = (caddr_t)&label; -	buf->b_bcount = DK_LABEL_SIZE; +	buf->b_un.b_addr = (caddr_t)label; +	buf->b_bcount = vdc->vdisk_bsize;  	buf->b_flags = B_BUSY | B_READ;  	buf->b_dev = cmpdev(dev); -	rv = vdc_send_request(vdc, VD_OP_BREAD, (caddr_t)&label, -	    DK_LABEL_SIZE, VD_SLICE_NONE, 0, CB_STRATEGY, buf, VIO_read_dir); +	rv = vdc_send_request(vdc, VD_OP_BREAD, (caddr_t)label, +	    vdc->vdisk_bsize, VD_SLICE_NONE, 0, CB_STRATEGY, buf, VIO_read_dir);  	if (rv) {  		DMSG(vdc, 1, "[%d] Failed to read disk block 0\n",  		    vdc->instance); @@ -7892,15 +7982,17 @@ vdc_validate_geometry(vdc_t *vdc)  	biofini(buf);  	kmem_free(buf, sizeof (buf_t)); -	if (rv != 0 || label.dkl_magic != DKL_MAGIC || -	    label.dkl_cksum != vdc_lbl2cksum(&label)) { +	if (rv != 0 || label->dkl_magic != DKL_MAGIC || +	    label->dkl_cksum != vdc_lbl2cksum(label)) {  		DMSG(vdc, 1, "[%d] Got VTOC with invalid label\n",  		    vdc->instance); +		kmem_free(label, vdc->vdisk_bsize);  		mutex_enter(&vdc->lock);  		vdc_store_label_unk(vdc);  		return (EINVAL);  	} +	kmem_free(label, vdc->vdisk_bsize);  	mutex_enter(&vdc->lock);  	vdc_store_label_vtoc(vdc, &geom, &vtoc);  	return (0); @@ -8108,7 +8200,7 @@ vdc_store_label_vtoc(vdc_t *vdc, struct dk_geom *geom, struct extvtoc *vtoc)  	int i;  	ASSERT(MUTEX_HELD(&vdc->lock)); -	ASSERT(vdc->block_size == vtoc->v_sectorsz); +	ASSERT(vdc->vdisk_bsize == vtoc->v_sectorsz);  	vdc->vdisk_label = VD_DISK_LABEL_VTOC;  	bcopy(vtoc, vdc->vtoc, sizeof (struct extvtoc)); diff --git a/usr/src/uts/sun4v/io/vds.c b/usr/src/uts/sun4v/io/vds.c index 548fc0f048..45f4122465 100644 --- a/usr/src/uts/sun4v/io/vds.c +++ b/usr/src/uts/sun4v/io/vds.c @@ -119,6 +119,10 @@  #define	VD_EFI_LBA_GPT		1	/* LBA of the GPT */  #define	VD_EFI_LBA_GPE		2	/* LBA of the GPE */ +#define	VD_EFI_DEV_SET(dev, vdsk, ioctl)	\ +	VDSK_EFI_DEV_SET(dev, vdsk, ioctl,	\ +	    (vdsk)->vdisk_bsize, (vdsk)->vdisk_size) +  /*   * Flags defining the behavior for flushing asynchronous writes used to   * performed some write I/O requests. @@ -451,13 +455,14 @@ typedef struct vd {  	int			open_flags;	/* open flags */  	uint_t			nslices;	/* number of slices we export */  	size_t			vdisk_size;	/* number of blocks in vdisk */ -	size_t			vdisk_block_size; /* size of each vdisk block */ +	size_t			vdisk_bsize;	/* blk size of the vdisk */  	vd_disk_type_t		vdisk_type;	/* slice or entire disk */  	vd_disk_label_t		vdisk_label;	/* EFI or VTOC label */  	vd_media_t		vdisk_media;	/* media type of backing dev. */  	boolean_t		is_atapi_dev;	/* Is this an IDE CD-ROM dev? */  	ushort_t		max_xfer_sz;	/* max xfer size in DEV_BSIZE */ -	size_t			block_size;	/* blk size of actual device */ +	size_t			backend_bsize;	/* blk size of backend device */ +	int			vio_bshift;	/* shift for blk convertion */  	boolean_t		volume;		/* is vDisk backed by volume */  	boolean_t		zvol;		/* is vDisk backed by a zvol */  	boolean_t		file;		/* is vDisk backed by a file? */ @@ -506,21 +511,20 @@ typedef struct vd {   * followed by a GPT (efi_gpt_t) and a GPE (efi_gpe_t).   *   */ -#define	VD_LABEL_VTOC_SIZE					\ -	P2ROUNDUP(sizeof (struct dk_label), DEV_BSIZE) +#define	VD_LABEL_VTOC_SIZE(lba)					\ +	P2ROUNDUP(sizeof (struct dk_label), (lba)) -#define	VD_LABEL_EFI_SIZE					\ -	P2ROUNDUP(DEV_BSIZE + sizeof (efi_gpt_t) + 		\ -	    sizeof (efi_gpe_t) * VD_MAXPART, DEV_BSIZE) +#define	VD_LABEL_EFI_SIZE(lba)					\ +	P2ROUNDUP(2 * (lba) + sizeof (efi_gpe_t) * VD_MAXPART,	\ +	    (lba))  #define	VD_LABEL_VTOC(vd)	\  		((struct dk_label *)(void *)((vd)->flabel)) -#define	VD_LABEL_EFI_GPT(vd)	\ -		((efi_gpt_t *)(void *)((vd)->flabel + DEV_BSIZE)) -#define	VD_LABEL_EFI_GPE(vd)	\ -		((efi_gpe_t *)(void *)((vd)->flabel + DEV_BSIZE + \ -		sizeof (efi_gpt_t))) +#define	VD_LABEL_EFI_GPT(vd, lba)	\ +		((efi_gpt_t *)(void *)((vd)->flabel + (lba))) +#define	VD_LABEL_EFI_GPE(vd, lba)	\ +		((efi_gpe_t *)(void *)((vd)->flabel + 2 * (lba)))  typedef struct vds_operation { @@ -757,6 +761,7 @@ vd_dskimg_io_params(vd_t *vd, int slice, size_t *blkp, size_t *lenp)  	ASSERT(vd->file || VD_DSKIMG(vd));  	ASSERT(len > 0); +	ASSERT(vd->vdisk_bsize == DEV_BSIZE);  	/*  	 * If a file is exported as a slice then we don't care about the vtoc. @@ -797,7 +802,6 @@ vd_dskimg_io_params(vd_t *vd, int slice, size_t *blkp, size_t *lenp)  			ASSERT(vd->vtoc.v_sectorsz == DEV_BSIZE);  		} else {  			ASSERT(vd->vdisk_label == VD_DISK_LABEL_EFI); -			ASSERT(vd->vdisk_block_size == DEV_BSIZE);  		}  		if (blk >= vd->slices[slice].nblocks) { @@ -875,6 +879,7 @@ vd_dskimg_rw(vd_t *vd, int slice, int operation, caddr_t data, size_t offset,  	ASSERT(vd->file || VD_DSKIMG(vd));  	ASSERT(len > 0); +	ASSERT(vd->vdisk_bsize == DEV_BSIZE);  	if ((status = vd_dskimg_io_params(vd, slice, &offset, &len)) != 0)  		return ((status == ENODATA)? 0: -1); @@ -941,13 +946,14 @@ vd_dskimg_rw(vd_t *vd, int slice, int operation, caddr_t data, size_t offset,   *   * Parameters:   *	disk_size	- the disk size in bytes + *	bsize		- the disk block size in bytes   *	label		- the returned default label.   *   * Return Code:   *	none.   */  static void -vd_build_default_label(size_t disk_size, struct dk_label *label) +vd_build_default_label(size_t disk_size, size_t bsize, struct dk_label *label)  {  	size_t size;  	char unit; @@ -1005,7 +1011,7 @@ vd_build_default_label(size_t disk_size, struct dk_label *label)  	}  	label->dkl_pcyl = disk_size / -	    (label->dkl_nsect * label->dkl_nhead * DEV_BSIZE); +	    (label->dkl_nsect * label->dkl_nhead * bsize);  	if (label->dkl_pcyl == 0)  		label->dkl_pcyl = 1; @@ -1027,7 +1033,7 @@ vd_build_default_label(size_t disk_size, struct dk_label *label)  	    label->dkl_nhead, label->dkl_nsect);  	PR0("provided disk size: %ld bytes\n", (uint64_t)  	    (label->dkl_pcyl * label->dkl_nhead * -	    label->dkl_nsect * DEV_BSIZE)); +	    label->dkl_nsect * bsize));  	vd_get_readable_size(disk_size, &size, &unit); @@ -1230,6 +1236,8 @@ vd_dskimg_read_devid(vd_t *vd, ddi_devid_t *devid)  	uint_t chksum;  	int status, sz; +	ASSERT(vd->vdisk_bsize == DEV_BSIZE); +  	if ((status = vd_dskimg_get_devid_block(vd, &blk)) != 0)  		return (status); @@ -1304,6 +1312,8 @@ vd_dskimg_write_devid(vd_t *vd, ddi_devid_t devid)  	size_t blk;  	int status; +	ASSERT(vd->vdisk_bsize == DEV_BSIZE); +  	if (devid == NULL) {  		/* nothing to write */  		return (0); @@ -1371,12 +1381,12 @@ vd_do_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t blk, size_t len)  	ASSERT(!vd->file);  	ASSERT(!vd->volume); -	ASSERT(vd->vdisk_block_size > 0); +	ASSERT(vd->vdisk_bsize > 0);  	max_sectors = vd->max_xfer_sz; -	nblk = (len / vd->vdisk_block_size); +	nblk = (len / vd->vdisk_bsize); -	if (len % vd->vdisk_block_size != 0) +	if (len % vd->vdisk_bsize != 0)  		return (EINVAL);  	/* @@ -1414,7 +1424,7 @@ vd_do_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t blk, size_t len)  		}  		ucmd.uscsi_cdb = (caddr_t)&cdb;  		ucmd.uscsi_bufaddr = data; -		ucmd.uscsi_buflen = nsectors * vd->block_size; +		ucmd.uscsi_buflen = nsectors * vd->backend_bsize;  		ucmd.uscsi_timeout = vd_scsi_rdwr_timeout;  		/*  		 * Set flags so that the command is isolated from normal @@ -1459,7 +1469,7 @@ vd_do_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t blk, size_t len)  		blk += nsectors;  		nblk -= nsectors; -		data += nsectors * vd->vdisk_block_size; /* SECSIZE */ +		data += nsectors * vd->vdisk_bsize;  	}  	return (status); @@ -1498,7 +1508,7 @@ vd_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t vblk, size_t vlen)  	size_t	plen;	/* length of data to be read from physical device */  	char	*buf;	/* buffer area to fit physical device's block size */ -	if (vd->block_size == 0) { +	if (vd->backend_bsize == 0) {  		/*  		 * The block size was not available during the attach,  		 * try to update it now. @@ -1514,10 +1524,10 @@ vd_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t vblk, size_t vlen)  	 * and adjust the block to be read from and the amount of data to  	 * read to correspond with the device's block size.  	 */ -	if (vd->vdisk_block_size == vd->block_size) +	if (vd->vdisk_bsize == vd->backend_bsize)  		return (vd_do_scsi_rdwr(vd, operation, data, vblk, vlen)); -	if (vd->vdisk_block_size > vd->block_size) +	if (vd->vdisk_bsize > vd->backend_bsize)  		return (EINVAL);  	/* @@ -1540,23 +1550,23 @@ vd_scsi_rdwr(vd_t *vd, int operation, caddr_t data, size_t vblk, size_t vlen)  	 *             v                 v  	 *  --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-   virtual disk:  	 *    |  |  |  |XX|XX|XX|XX|XX|XX|  |  |  |  |  |  } block size is -	 *  --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-  vd->vdisk_block_size +	 *  --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-   vd->vdisk_bsize  	 *          :  :                 :  :  	 *         >:==:< delta          :  :  	 *          :  :                 :  :  	 *  --+-----+-----+-----+-----+-----+-----+-----+--   physical disk:  	 *    |     |YY:YY|YYYYY|YYYYY|YY:YY|     |     |   } block size is -	 *  --+-----+-----+-----+-----+-----+-----+-----+--   vd->block_size +	 *  --+-----+-----+-----+-----+-----+-----+-----+--   vd->backend_bsize  	 *          ^                       ^  	 *          |<--------------------->|  	 *          |         plen  	 *         pblk   	 */  	/* END CSTYLED */ -	pblk = (vblk * vd->vdisk_block_size) / vd->block_size; -	delta = (vblk * vd->vdisk_block_size) - (pblk * vd->block_size); -	pnblk = ((delta + vlen - 1) / vd->block_size) + 1; -	plen = pnblk * vd->block_size; +	pblk = (vblk * vd->vdisk_bsize) / vd->backend_bsize; +	delta = (vblk * vd->vdisk_bsize) - (pblk * vd->backend_bsize); +	pnblk = ((delta + vlen - 1) / vd->backend_bsize) + 1; +	plen = pnblk * vd->backend_bsize;  	PR2("vblk %lx:pblk %lx: vlen %ld:plen %ld", vblk, pblk, vlen, plen); @@ -1591,7 +1601,7 @@ static ssize_t  vd_slice_flabel_read(vd_t *vd, caddr_t data, size_t offset, size_t length)  {  	size_t n = 0; -	uint_t limit = vd->flabel_limit * DEV_BSIZE; +	uint_t limit = vd->flabel_limit * vd->vdisk_bsize;  	ASSERT(vd->vdisk_type == VD_DISK_TYPE_SLICE);  	ASSERT(vd->flabel != NULL); @@ -1646,7 +1656,7 @@ vd_slice_flabel_read(vd_t *vd, caddr_t data, size_t offset, size_t length)  static ssize_t  vd_slice_flabel_write(vd_t *vd, caddr_t data, size_t offset, size_t length)  { -	uint_t limit = vd->flabel_limit * DEV_BSIZE; +	uint_t limit = vd->flabel_limit * vd->vdisk_bsize;  	struct dk_label *label;  	struct dk_geom geom;  	struct extvtoc vtoc; @@ -1663,7 +1673,7 @@ vd_slice_flabel_write(vd_t *vd, caddr_t data, size_t offset, size_t length)  	 * write was successful, but note that nothing is actually overwritten.  	 */  	if (vd->vdisk_label == VD_DISK_LABEL_VTOC && -	    offset == 0 && length == DEV_BSIZE) { +	    offset == 0 && length == vd->vdisk_bsize) {  		label = (void *)data;  		/* check that this is a valid label */ @@ -1721,7 +1731,7 @@ vd_slice_flabel_write(vd_t *vd, caddr_t data, size_t offset, size_t length)   *			  Return the starting block relative to the vdisk   *			  backend for the remaining operation.   *	lengthp		- pointer to the number of bytes to read or write. - *			  This should be a multiple of DEV_BSIZE. Return the + *			  This should be a multiple of vdisk_bsize. Return the   *			  remaining number of bytes to read or write.   *   * Return Code: @@ -1739,6 +1749,7 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  	size_t ablk, asize, aoff, alen;  	ssize_t n;  	int sec, status; +	size_t bsize = vd->vdisk_bsize;  	ASSERT(vd->vdisk_type == VD_DISK_TYPE_SLICE);  	ASSERT(slice != 0); @@ -1759,23 +1770,23 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  		return (EIO);  	} -	if (length % DEV_BSIZE != 0) +	if (length % bsize != 0)  		return (EINVAL);  	/* handle any I/O with the fake label */  	if (operation == VD_OP_BWRITE) -		n = vd_slice_flabel_write(vd, data, blk * DEV_BSIZE, length); +		n = vd_slice_flabel_write(vd, data, blk * bsize, length);  	else -		n = vd_slice_flabel_read(vd, data, blk * DEV_BSIZE, length); +		n = vd_slice_flabel_read(vd, data, blk * bsize, length);  	if (n == -1)  		return (EINVAL); -	ASSERT(n % DEV_BSIZE == 0); +	ASSERT(n % bsize == 0);  	/* adjust I/O arguments */  	data += n; -	blk += n / DEV_BSIZE; +	blk += n / bsize;  	length -= n;  	/* check if there's something else to process */ @@ -1791,7 +1802,7 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  	}  	if (vd->vdisk_label == VD_DISK_LABEL_EFI) { -		asize = EFI_MIN_RESV_SIZE + 33; +		asize = EFI_MIN_RESV_SIZE + (EFI_MIN_ARRAY_SIZE / bsize) + 1;  		ablk = vd->vdisk_size - asize;  	} else {  		ASSERT(vd->vdisk_label == VD_DISK_LABEL_VTOC); @@ -1802,7 +1813,7 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  		asize = vd->dk_geom.dkg_acyl * csize;  	} -	alen = length / DEV_BSIZE; +	alen = length / bsize;  	aoff = blk;  	/* if we have reached the last block then the I/O is completed */ @@ -1834,10 +1845,10 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  		alen = ablk + asize - aoff;  	} -	alen *= DEV_BSIZE; +	alen *= bsize;  	if (operation == VD_OP_BREAD) { -		bzero(data + (aoff - blk) * DEV_BSIZE, alen); +		bzero(data + (aoff - blk) * bsize, alen);  		if (vd->vdisk_label == VD_DISK_LABEL_VTOC) {  			/* check if we read backup labels */ @@ -1848,9 +1859,9 @@ vd_slice_fake_rdwr(vd_t *vd, int slice, int operation, caddr_t *datap,  			for (sec = 1; (sec < 5 * 2 + 1); sec += 2) {  				if (ablk + sec >= blk && -				    ablk + sec < blk + (length / DEV_BSIZE)) { +				    ablk + sec < blk + (length / bsize)) {  					bcopy(label, data + -					    (ablk + sec - blk) * DEV_BSIZE, +					    (ablk + sec - blk) * bsize,  					    sizeof (struct dk_label));  				}  			} @@ -1899,6 +1910,8 @@ vd_bio_task(void *arg)  	ssize_t resid;  	int status; +	ASSERT(vd->vdisk_bsize == DEV_BSIZE); +  	if (vd->zvol) {  		status = ldi_strategy(vd->ldi_handle[0], buf); @@ -2162,6 +2175,9 @@ vd_start_bio(vd_task_t *task)  			buf->b_flags |= B_WRITE;  		} +		/* convert VIO block number to buf block number */ +		buf->b_lblkno = offset << vd->vio_bshift; +  		request->status = ldi_strategy(vd->ldi_handle[slice], buf);  	} @@ -3101,7 +3117,8 @@ vd_do_slice_ioctl(vd_t *vd, int cmd, void *ioctl_arg)  		switch (cmd) {  		case DKIOCGETEFI:  			len = vd_slice_flabel_read(vd, -			    (caddr_t)dk_ioc->dki_data, lba * DEV_BSIZE, len); +			    (caddr_t)dk_ioc->dki_data, +			    lba * vd->vdisk_bsize, len);  			ASSERT(len > 0); @@ -3237,7 +3254,8 @@ vd_dskimg_validate_geometry(vd_t *vd)  		}  		vd->vdisk_label = VD_DISK_LABEL_UNK; -		vd_build_default_label(vd->dskimg_size, &label); +		vd_build_default_label(vd->dskimg_size, vd->vdisk_bsize, +		    &label);  		status = EINVAL;  	} else {  		vd->vdisk_label = VD_DISK_LABEL_VTOC; @@ -3835,7 +3853,7 @@ vd_get_capacity(vd_task_t *task)  	request->status = 0; -	vd_cap.vdisk_block_size = vd->vdisk_block_size; +	vd_cap.vdisk_block_size = vd->vdisk_bsize;  	vd_cap.vdisk_size = vd->vdisk_size;  	if ((rv = ldc_mem_copy(vd->ldc_handle, (char *)&vd_cap, 0, &nbytes, @@ -4480,7 +4498,7 @@ vd_process_attr_msg(vd_t *vd, vio_msg_t *msg, size_t msglen)  		 * Must first get the maximum transfer size in bytes.  		 */  		size_t	max_xfer_bytes = attr_msg->vdisk_block_size ? -		    attr_msg->vdisk_block_size*attr_msg->max_xfer_sz : +		    attr_msg->vdisk_block_size * attr_msg->max_xfer_sz :  		    attr_msg->max_xfer_sz;  		size_t	max_inband_msglen =  		    sizeof (vd_dring_inband_msg_t) + @@ -4506,7 +4524,7 @@ vd_process_attr_msg(vd_t *vd, vio_msg_t *msg, size_t msglen)  	}  	/* Return the device's block size and max transfer size to the client */ -	attr_msg->vdisk_block_size	= vd->vdisk_block_size; +	attr_msg->vdisk_block_size	= vd->vdisk_bsize;  	attr_msg->max_xfer_sz		= vd->max_xfer_sz;  	attr_msg->vdisk_size = vd->vdisk_size; @@ -5442,7 +5460,7 @@ vd_dskimg_is_iso_image(vd_t *vd)  	 * Standard Identifier and is set to CD001 for a CD-ROM compliant  	 * to the ISO 9660 standard.  	 */ -	sec = (ISO_VOLDESC_SEC * ISO_SECTOR_SIZE) / vd->vdisk_block_size; +	sec = (ISO_VOLDESC_SEC * ISO_SECTOR_SIZE) / vd->vdisk_bsize;  	rv = vd_dskimg_rw(vd, VD_SLICE_NONE, VD_OP_BREAD, (caddr_t)iso_buf,  	    sec, ISO_SECTOR_SIZE); @@ -5507,16 +5525,13 @@ vd_setup_full_disk(vd_t *vd)  	ASSERT(vd->vdisk_type == VD_DISK_TYPE_DISK); -	vd->vdisk_block_size = DEV_BSIZE; -  	/* set the disk size, block size and the media type of the disk */  	status = vd_backend_check_size(vd);  	if (status != 0) {  		if (!vd->scsi) {  			/* unexpected failure */ -			PRN("ldi_ioctl(DKIOCGMEDIAINFO) returned errno %d", -			    status); +			PRN("Failed to check backend size (errno %d)", status);  			return (status);  		} @@ -5526,7 +5541,8 @@ vd_setup_full_disk(vd_t *vd)  		 * size of the disk and the block size.  		 */  		vd->vdisk_size = VD_SIZE_UNKNOWN; -		vd->block_size = 0; +		vd->vdisk_bsize = 0; +		vd->backend_bsize = 0;  		vd->vdisk_media = VD_MEDIA_FIXED;  	} @@ -5697,7 +5713,7 @@ vd_setup_partition_vtoc(vd_t *vd)  		vd->vtoc.v_part[VD_ENTIRE_DISK_SLICE].p_size =  		    vd->dk_geom.dkg_ncyl * csize; -		vd_get_readable_size(vd->vdisk_size * vd->vdisk_block_size, +		vd_get_readable_size(vd->vdisk_size * vd->vdisk_bsize,  		    &size, &unit);  		/* @@ -5723,7 +5739,7 @@ vd_setup_partition_vtoc(vd_t *vd)  		/* create a fake label from the vtoc and geometry */  		vd->flabel_limit = (uint_t)csize; -		vd->flabel_size = VD_LABEL_VTOC_SIZE; +		vd->flabel_size = VD_LABEL_VTOC_SIZE(vd->vdisk_bsize);  		vd->flabel = kmem_zalloc(vd->flabel_size, KM_SLEEP);  		vd_vtocgeom_to_label(&vd->vtoc, &vd->dk_geom,  		    VD_LABEL_VTOC(vd)); @@ -5741,7 +5757,7 @@ vd_setup_partition_vtoc(vd_t *vd)   * as a slice without the addition of any metadata.   *   * So when exporting the disk as an EFI disk, we fake a disk with the following - * layout: + * layout: (assuming the block size is 512 bytes)   *   *                  flabel        +--- flabel_limit   *                 <------>       v @@ -5776,9 +5792,8 @@ vd_setup_partition_vtoc(vd_t *vd)   * - blocks 34+N+1 to P define a fake reserved partition and backup label, it   *   returns 0   * - * Note: if the backend size is not a multiple of the vdisk block size - * (DEV_BSIZE = 512 byte) then the very end of the backend will not map to - * any block of the virtual disk. + * Note: if the backend size is not a multiple of the vdisk block size then + * the very end of the backend will not map to any block of the virtual disk.   */  static int  vd_setup_partition_efi(vd_t *vd) @@ -5788,23 +5803,35 @@ vd_setup_partition_efi(vd_t *vd)  	struct uuid uuid = EFI_USR;  	struct uuid efi_reserved = EFI_RESERVED;  	uint32_t crc; -	uint64_t s0_start, s0_end; +	uint64_t s0_start, s0_end, first_u_lba; +	size_t bsize; -	vd->flabel_limit = 34; -	vd->flabel_size = VD_LABEL_EFI_SIZE; +	ASSERT(vd->vdisk_bsize > 0); + +	bsize = vd->vdisk_bsize; +	/* +	 * The minimum size for the label is 16K (EFI_MIN_ARRAY_SIZE) +	 * for GPEs plus one block for the GPT and one for PMBR. +	 */ +	first_u_lba = (EFI_MIN_ARRAY_SIZE / bsize) + 2; +	vd->flabel_limit = (uint_t)first_u_lba; +	vd->flabel_size = VD_LABEL_EFI_SIZE(bsize);  	vd->flabel = kmem_zalloc(vd->flabel_size, KM_SLEEP); -	gpt = VD_LABEL_EFI_GPT(vd); -	gpe = VD_LABEL_EFI_GPE(vd); +	gpt = VD_LABEL_EFI_GPT(vd, bsize); +	gpe = VD_LABEL_EFI_GPE(vd, bsize); -	/* adjust the vdisk_size, we emulate the first 34 blocks */ -	vd->vdisk_size += 34; -	s0_start = 34; +	/* +	 * Adjust the vdisk_size, we emulate the first few blocks +	 * for the disk label. +	 */ +	vd->vdisk_size += first_u_lba; +	s0_start = first_u_lba;  	s0_end = vd->vdisk_size - 1;  	gpt->efi_gpt_Signature = LE_64(EFI_SIGNATURE);  	gpt->efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT);  	gpt->efi_gpt_HeaderSize = LE_32(sizeof (efi_gpt_t)); -	gpt->efi_gpt_FirstUsableLBA = LE_64(34ULL); +	gpt->efi_gpt_FirstUsableLBA = LE_64(first_u_lba);  	gpt->efi_gpt_PartitionEntryLBA = LE_64(2ULL);  	gpt->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (efi_gpe_t)); @@ -5834,7 +5861,8 @@ vd_setup_partition_efi(vd_t *vd)  	gpt->efi_gpt_LastUsableLBA = LE_64(vd->vdisk_size - 1);  	/* adjust the vdisk size for the backup GPT and GPE */ -	vd->vdisk_size += 33; +	vd->vdisk_size += (EFI_MIN_ARRAY_SIZE / bsize) + 1; +	gpt->efi_gpt_AlternateLBA = LE_64(vd->vdisk_size - 1);  	CRC32(crc, gpe, sizeof (efi_gpe_t) * VD_MAXPART, -1U, crc32_table);  	gpt->efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc); @@ -5854,7 +5882,6 @@ static int  vd_setup_backend_vnode(vd_t *vd)  {  	int 		rval, status; -	vattr_t		vattr;  	dev_t		dev;  	char		*file_path = vd->device_path;  	ldi_handle_t	lhandle; @@ -5874,20 +5901,6 @@ vd_setup_backend_vnode(vd_t *vd)  	 */  	vd->file = B_TRUE; -	vattr.va_mask = AT_SIZE; -	if ((status = VOP_GETATTR(vd->file_vnode, &vattr, 0, kcred, NULL)) -	    != 0) { -		PRN("VOP_GETATTR(%s) = errno %d", file_path, status); -		return (EIO); -	} - -	vd->dskimg_size = vattr.va_size; - -	if (vd->file_vnode->v_flag & VNOMAP) { -		PRN("File %s cannot be mapped", file_path); -		return (EIO); -	} -  	vd->max_xfer_sz = maxphys / DEV_BSIZE; /* default transfer size */  	/* @@ -5938,10 +5951,6 @@ vd_setup_slice_image(vd_t *vd)  	struct dk_label label;  	int status; -	/* sector size = block size = DEV_BSIZE */ -	vd->block_size = DEV_BSIZE; -	vd->vdisk_block_size = DEV_BSIZE; -	vd->vdisk_size = vd->dskimg_size / DEV_BSIZE;  	vd->vdisk_media = VD_MEDIA_FIXED;  	vd->vdisk_label = (vd_slice_label == VD_DISK_LABEL_UNK)?  	    vd_file_slice_label : vd_slice_label; @@ -5956,7 +5965,8 @@ vd_setup_slice_image(vd_t *vd)  		 * adjust the vtoc so that it defines a single-slice  		 * disk.  		 */ -		vd_build_default_label(vd->dskimg_size, &label); +		vd_build_default_label(vd->dskimg_size, vd->vdisk_bsize, +		    &label);  		vd_label_to_vtocgeom(&label, &vd->vtoc, &vd->dk_geom);  		status = vd_setup_partition_vtoc(vd);  	} @@ -5970,6 +5980,12 @@ vd_setup_disk_image(vd_t *vd)  	int status;  	char *backend_path = vd->device_path; +	if ((status = vd_backend_check_size(vd)) != 0) { +		PRN("Fail to check size of %s (errno %d)", +		    backend_path, status); +		return (EIO); +	} +  	/* size should be at least sizeof(dk_label) */  	if (vd->dskimg_size < sizeof (struct dk_label)) {  		PRN("Size of file has to be at least %ld bytes", @@ -5977,11 +5993,6 @@ vd_setup_disk_image(vd_t *vd)  		return (EIO);  	} -	/* sector size = block size = DEV_BSIZE */ -	vd->block_size = DEV_BSIZE; -	vd->vdisk_block_size = DEV_BSIZE; -	vd->vdisk_size = vd->dskimg_size / DEV_BSIZE; -  	/*  	 * Find and validate the geometry of a disk image.  	 */ @@ -5997,7 +6008,7 @@ vd_setup_disk_image(vd_t *vd)  		 * of the ISO image (images for both drive types are stored  		 * in the ISO-9600 format). CDs can store up to just under 1Gb  		 */ -		if ((vd->vdisk_size * vd->vdisk_block_size) > ONE_GIGABYTE) +		if ((vd->vdisk_size * vd->vdisk_bsize) > ONE_GIGABYTE)  			vd->vdisk_media = VD_MEDIA_DVD;  		else  			vd->vdisk_media = VD_MEDIA_CD; @@ -6179,14 +6190,6 @@ vd_setup_backend_ldi(vd_t *vd)  	if (vd->vdisk_type == VD_DISK_TYPE_DISK) {  		if (vd->volume) { -			/* get size of backing device */ -			if (ldi_get_size(vd->ldi_handle[0], &vd->dskimg_size) != -			    DDI_SUCCESS) { -				PRN("ldi_get_size() failed for %s", -				    device_path); -				return (EIO); -			} -  			/* setup disk image */  			return (vd_setup_disk_image(vd));  		} @@ -6220,14 +6223,6 @@ vd_setup_single_slice_disk(vd_t *vd)  	char *device_path = vd->device_path;  	struct vtoc vtoc; -	/* Get size of backing device */ -	if (ldi_get_size(vd->ldi_handle[0], &vd->vdisk_size) != DDI_SUCCESS) { -		PRN("ldi_get_size() failed for %s", device_path); -		return (EIO); -	} -	vd->vdisk_size = lbtodb(vd->vdisk_size);	/* convert to blocks */ -	vd->block_size = DEV_BSIZE; -	vd->vdisk_block_size = DEV_BSIZE;  	vd->vdisk_media = VD_MEDIA_FIXED;  	if (vd->volume) { @@ -6241,6 +6236,12 @@ vd_setup_single_slice_disk(vd_t *vd)  	vd->vdisk_type  = VD_DISK_TYPE_SLICE;  	vd->nslices	= 1; +	/* Get size of backing device */ +	if ((status = vd_backend_check_size(vd)) != 0) { +		PRN("Fail to check size of %s (errno %d)", device_path, status); +		return (EIO); +	} +  	/*  	 * When exporting a slice or a device as a single slice disk, we don't  	 * care about any partitioning exposed by the backend. The goal is just @@ -6251,7 +6252,7 @@ vd_setup_single_slice_disk(vd_t *vd)  	 * variable.  	 */  	if (vd_slice_label == VD_DISK_LABEL_EFI || -	    vd->vdisk_size >= ONE_TERABYTE / DEV_BSIZE) { +	    vd->vdisk_size >= ONE_TERABYTE / vd->vdisk_bsize) {  		vd->vdisk_label = VD_DISK_LABEL_EFI;  	} else {  		status = ldi_ioctl(vd->ldi_handle[0], DKIOCGEXTVTOC, @@ -6281,8 +6282,8 @@ vd_setup_single_slice_disk(vd_t *vd)  		} else if (vd_slice_label == VD_DISK_LABEL_VTOC) {  			vd->vdisk_label = VD_DISK_LABEL_VTOC; -			vd_build_default_label(vd->vdisk_size * DEV_BSIZE, -			    &label); +			vd_build_default_label(vd->vdisk_size * vd->vdisk_bsize, +			    vd->vdisk_bsize, &label);  			vd_label_to_vtocgeom(&label, &vd->vtoc, &vd->dk_geom);  		} else { @@ -6302,13 +6303,50 @@ vd_setup_single_slice_disk(vd_t *vd)  	return (status);  } +/* + * This function is invoked when setting up the vdisk backend and to process + * the VD_OP_GET_CAPACITY operation. It checks the backend size and set the + * following attributes of the vd structure: + * + * - vdisk_bsize: block size for the virtual disk used by the VIO protocol. Its + *   value is 512 bytes (DEV_BSIZE) when the backend is a file, a volume or a + *   CD/DVD. When the backend is a disk or a disk slice then it has the value + *   of the logical block size of that disk (as returned by the DKIOCGMEDIAINFO + *   ioctl). This block size is expected to be a power of 2 and a multiple of + *   512. + * + * - vdisk_size: size of the virtual disk expressed as a number of vdisk_bsize + *   blocks. + * + * vdisk_size and vdisk_bsize are sent to the vdisk client during the connection + * handshake and in the result of a VD_OP_GET_CAPACITY operation. + * + * - backend_bsize: block size of the backend device. backend_bsize has the same + *   value as vdisk_bsize except when the backend is a CD/DVD. In that case, + *   vdisk_bsize is set to 512 (DEV_BSIZE) while backend_bsize is set to the + *   effective logical block size of the CD/DVD (usually 2048). + * + * - dskimg_size: size of the backend when the backend is a disk image. This + *   attribute is set only when the backend is a file or a volume, otherwise it + *   is unused. + * + * - vio_bshift: number of bit to shift to convert a VIO block number (which + *   uses a block size of vdisk_bsize) to a buf(9s) block number (which uses a + *   block size of 512 bytes) i.e. we have vdisk_bsize = 512 x 2 ^ vio_bshift + * + * - vdisk_media: media of the virtual disk. This function only sets this + *   attribute for physical disk and CD/DVD. For other backend types, this + *   attribute is set in the setup function of the backend. + */  static int  vd_backend_check_size(vd_t *vd)  { -	size_t backend_size, old_size, new_size; +	size_t backend_size, backend_bsize, vdisk_bsize; +	size_t old_size, new_size;  	struct dk_minfo minfo;  	vattr_t vattr; -	int rval, rv; +	int rval, rv, media, nshift = 0; +	uint32_t n;  	if (vd->file) { @@ -6320,20 +6358,23 @@ vd_backend_check_size(vd_t *vd)  			return (rv);  		}  		backend_size = vattr.va_size; +		backend_bsize = DEV_BSIZE; +		vdisk_bsize = DEV_BSIZE; -	} else if (vd->volume || vd->vdisk_type == VD_DISK_TYPE_SLICE) { +	} else if (vd->volume) { -		/* physical slice or volume (slice or full disk) */ +		/* volume (slice or full disk) */  		rv = ldi_get_size(vd->ldi_handle[0], &backend_size);  		if (rv != DDI_SUCCESS) {  			PR0("ldi_get_size() failed for %s", vd->device_path);  			return (EIO);  		} +		backend_bsize = DEV_BSIZE; +		vdisk_bsize = DEV_BSIZE;  	} else { -		/* physical disk */ -		ASSERT(vd->vdisk_type == VD_DISK_TYPE_DISK); +		/* physical disk or slice */  		rv = ldi_ioctl(vd->ldi_handle[0], DKIOCGMEDIAINFO,  		    (intptr_t)&minfo, (vd->open_flags | FKIOCTL),  		    kcred, &rval); @@ -6342,17 +6383,58 @@ vd_backend_check_size(vd_t *vd)  			    vd->device_path, rv);  			return (rv);  		} -		backend_size = minfo.dki_capacity * minfo.dki_lbsize; + +		if (vd->vdisk_type == VD_DISK_TYPE_SLICE) { +			rv = ldi_get_size(vd->ldi_handle[0], &backend_size); +			if (rv != DDI_SUCCESS) { +				PR0("ldi_get_size() failed for %s", +				    vd->device_path); +				return (EIO); +			} +		} else { +			ASSERT(vd->vdisk_type == VD_DISK_TYPE_DISK); +			backend_size = minfo.dki_capacity * minfo.dki_lbsize; +		} + +		backend_bsize = minfo.dki_lbsize; +		media = DK_MEDIATYPE2VD_MEDIATYPE(minfo.dki_media_type); + +		/* +		 * If the device is a CD or a DVD then we force the vdisk block +		 * size to 512 bytes (DEV_BSIZE). In that case, vdisk_bsize can +		 * be different from backend_size. +		 */ +		if (media == VD_MEDIA_CD || media == VD_MEDIA_DVD) +			vdisk_bsize = DEV_BSIZE; +		else +			vdisk_bsize = backend_bsize;  	} +	/* check vdisk block size */ +	if (vdisk_bsize == 0 || vdisk_bsize % DEV_BSIZE != 0) +		return (EINVAL); +  	old_size = vd->vdisk_size; -	new_size = backend_size / DEV_BSIZE; +	new_size = backend_size / vdisk_bsize;  	/* check if size has changed */ -	if (old_size != VD_SIZE_UNKNOWN && old_size == new_size) +	if (old_size != VD_SIZE_UNKNOWN && old_size == new_size && +	    vd->vdisk_bsize == vdisk_bsize)  		return (0); +	/* cache info for blk conversion */ +	for (n = vdisk_bsize / DEV_BSIZE; n > 1; n >>= 1) { +		if ((n & 0x1) != 0) { +			/* blk_size is not a power of 2 */ +			return (EINVAL); +		} +		nshift++; +	} + +	vd->vio_bshift = nshift;  	vd->vdisk_size = new_size; +	vd->vdisk_bsize = vdisk_bsize; +	vd->backend_bsize = backend_bsize;  	if (vd->file || vd->volume)  		vd->dskimg_size = backend_size; @@ -6384,9 +6466,7 @@ vd_backend_check_size(vd_t *vd)  	} else if (!vd->file && !vd->volume) {  		/* physical disk */  		ASSERT(vd->vdisk_type == VD_DISK_TYPE_DISK); -		vd->block_size = minfo.dki_lbsize; -		vd->vdisk_media = -		    DK_MEDIATYPE2VD_MEDIATYPE(minfo.dki_media_type); +		vd->vdisk_media = media;  	}  	return (0); diff --git a/usr/src/uts/sun4v/sys/vdc.h b/usr/src/uts/sun4v/sys/vdc.h index 63b76b9d27..eecaf9a30b 100644 --- a/usr/src/uts/sun4v/sys/vdc.h +++ b/usr/src/uts/sun4v/sys/vdc.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -98,6 +98,10 @@ extern "C" {   */  #define	VD_MAKE_DEV(instance, minor)	((instance << VDCUNIT_SHIFT) | minor) +#define	VDC_EFI_DEV_SET(dev, vdsk, ioctl)	\ +	VDSK_EFI_DEV_SET(dev, vdsk, ioctl,	\ +	    (vdsk)->vdisk_bsize, (vdsk)->vdisk_size) +  /*   * variables controlling how long to wait before timing out and how many   * retries to attempt before giving up when communicating with vds. @@ -302,7 +306,9 @@ typedef struct vdc {  	uint32_t	vdisk_media;	/* physical media type of vDisk */  	uint64_t	vdisk_size;	/* device size in blocks */  	uint64_t	max_xfer_sz;	/* maximum block size of a descriptor */ -	uint64_t	block_size;	/* device block size used */ +	uint64_t	vdisk_bsize;	/* blk size for the virtual disk */ +	uint32_t	vio_bmask;	/* mask to check vio blk alignment */ +	int		vio_bshift;	/* shift for vio blk conversion */  	uint64_t	operations;	/* bitmask of ops. server supports */  	struct dk_cinfo	*cinfo;		/* structure to store DKIOCINFO data */  	struct dk_minfo	*minfo;		/* structure for DKIOCGMEDIAINFO data */ diff --git a/usr/src/uts/sun4v/sys/vdsk_common.h b/usr/src/uts/sun4v/sys/vdsk_common.h index 62b45c2df4..0464964847 100644 --- a/usr/src/uts/sun4v/sys/vdsk_common.h +++ b/usr/src/uts/sun4v/sys/vdsk_common.h @@ -20,7 +20,7 @@   */  /* - * Copyright 2008 Sun Microsystems, Inc.  All rights reserved. + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.   * Use is subject to license terms.   */ @@ -521,11 +521,11 @@ typedef	struct vd_efi_dev {  	vd_efi_ioctl_func vdisk_ioctl;	/* vdisk ioctl function */  } vd_efi_dev_t; -#define	VD_EFI_DEV_SET(efi_dev, vdsk, ioctl)		\ -	(efi_dev).vdisk = vdsk;				\ -	(efi_dev).vdisk_ioctl = ioctl;			\ -	(efi_dev).block_size = (vdsk)->block_size;	\ -	(efi_dev).disk_size = (vdsk)->vdisk_size; +#define	VDSK_EFI_DEV_SET(efi_dev, vdsk, ioctl, bsize, dsize)	\ +	(efi_dev).vdisk = vdsk;					\ +	(efi_dev).vdisk_ioctl = ioctl;				\ +	(efi_dev).block_size = bsize;				\ +	(efi_dev).disk_size = dsize;  int vd_efi_alloc_and_read(vd_efi_dev_t *dev, efi_gpt_t **gpt, efi_gpe_t **gpe); | 
