summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authoryu, larry liu - Sun Microsystems - Beijing China <Larry.Liu@Sun.COM>2009-06-17 19:20:05 +0800
committeryu, larry liu - Sun Microsystems - Beijing China <Larry.Liu@Sun.COM>2009-06-17 19:20:05 +0800
commit65908c77dfc02644236ba18bffe67b5ed6f23135 (patch)
tree90d89cc047a404c32e2537573bee1d8566a562e3 /usr/src
parent6ccacea7930c58faadb6224d30e24c5658b67c81 (diff)
downloadillumos-gate-65908c77dfc02644236ba18bffe67b5ed6f23135.tar.gz
PSARC 2008/769 Multiple disk sector size support.
6710930 Solaris needs to support large sector size hard drive disk
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/diskscan/diskscan.c39
-rw-r--r--usr/src/cmd/fdisk/fdisk.c80
-rw-r--r--usr/src/cmd/fmthard/fmthard.c125
-rw-r--r--usr/src/cmd/format/analyze.c17
-rw-r--r--usr/src/cmd/format/auto_sense.c366
-rw-r--r--usr/src/cmd/format/ctlr_ata.c9
-rw-r--r--usr/src/cmd/format/ctlr_scsi.c71
-rw-r--r--usr/src/cmd/format/defect.c31
-rw-r--r--usr/src/cmd/format/defect.h28
-rw-r--r--usr/src/cmd/format/disk_generic.c6
-rw-r--r--usr/src/cmd/format/global.h3
-rw-r--r--usr/src/cmd/format/hardware_structs.h4
-rw-r--r--usr/src/cmd/format/io.c17
-rw-r--r--usr/src/cmd/format/label.c33
-rw-r--r--usr/src/cmd/format/main.c7
-rw-r--r--usr/src/cmd/format/menu_analyze.c6
-rw-r--r--usr/src/cmd/format/menu_command.c526
-rw-r--r--usr/src/cmd/format/menu_defect.c43
-rw-r--r--usr/src/cmd/format/menu_fdisk.c107
-rw-r--r--usr/src/cmd/format/misc.c12
-rw-r--r--usr/src/cmd/format/prompts.c13
-rw-r--r--usr/src/cmd/format/startup.c19
-rw-r--r--usr/src/cmd/fs.d/fsck.c38
-rw-r--r--usr/src/cmd/fs.d/pcfs/mkfs/mkfs.c34
-rw-r--r--usr/src/cmd/fs.d/udfs/mkfs/mkfs.c19
-rw-r--r--usr/src/cmd/fs.d/ufs/mkfs/mkfs.c18
-rw-r--r--usr/src/lib/libefi/common/rdwr_efi.c51
-rw-r--r--usr/src/uts/common/io/cmlb.c58
-rw-r--r--usr/src/uts/common/io/scsi/targets/sd.c744
-rw-r--r--usr/src/uts/common/os/dumpsubr.c12
-rw-r--r--usr/src/uts/common/sys/dkio.h18
-rw-r--r--usr/src/uts/common/sys/dklabel.h4
-rw-r--r--usr/src/uts/common/sys/scsi/targets/sddef.h34
-rw-r--r--usr/src/uts/common/xen/io/xdb.c18
-rw-r--r--usr/src/uts/common/xen/io/xdb.h2
-rw-r--r--usr/src/uts/common/xen/io/xdf.c93
-rw-r--r--usr/src/uts/common/xen/io/xdf.h3
-rw-r--r--usr/src/uts/common/xen/sys/xendev.h1
-rw-r--r--usr/src/uts/sun4v/io/vdc.c164
-rw-r--r--usr/src/uts/sun4v/io/vds.c338
-rw-r--r--usr/src/uts/sun4v/sys/vdc.h10
-rw-r--r--usr/src/uts/sun4v/sys/vdsk_common.h12
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);