Index: src/sys/arch/sparc/stand/common/promdev.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/stand/common/promdev.c,v retrieving revision 1.29 diff -p -r1.29 promdev.c *** src/sys/arch/sparc/stand/common/promdev.c 3 Feb 2019 11:58:38 -0000 1.29 --- src/sys/arch/sparc/stand/common/promdev.c 30 Sep 2022 14:45:13 -0000 *************** *** 30,35 **** --- 30,37 ---- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #define DEBUG_PROM 1 + #define NOTDEF_DEBUG 1 /* * Note: the `#ifndef BOOTXX' in here serve to queeze the code size *************** static char *oldmon_mapin(u_long, int, i *** 78,83 **** --- 80,90 ---- #ifndef BOOTXX static char *mygetpropstring(int, char *); static int getdevtype(int, char *); + void israidlabel(char* buf); + + static daddr_t doffset = 0; + static int raidchecked = 0; + #endif extern struct fs_ops file_system_nfs[]; *************** char prom_bootdevice[MAX_PROM_PATH]; *** 103,110 **** static int saveecho; #ifndef BOOTXX ! static daddr_t doffset = 0; #endif void putchar(int c) --- 110,177 ---- static int saveecho; #ifndef BOOTXX ! void ! israidlabel(char *buf) ! { ! char *partition; ! int part = 0; ! struct disklabel *dlp; ! ! /* Check the disklabel to see if the boot partition is type RAID. ! * ! * For machines with prom_version() == PROM_OLDMON, we ! * only handle boot from RAID for the first disk partition. ! */ ! if (prom_version() != PROM_OLDMON) { ! if ((partition = strchr(prom_bootdevice, ':')) != NULL && ! *++partition >= 'a' && ! *partition <= 'a' + MAXPARTITIONS) ! part = *partition - 'a'; ! } ! ! #ifdef DEBUG_PROM ! printf("israidlabel: Checking disklabel for RAID partition (%c)\n", ! 'a' + part); ! #endif ! ! #ifdef NOTDEF_DEBUG ! { ! int x = 0; ! char *p = (char *) buf; ! ! printf("Disklabel sector (%d):\n", LABELSECTOR); ! printf("00000000 "); ! while (x < DEV_BSIZE) { ! if (*p >= 0x00 && *p < 0x10) ! printf("0%x ", *p & 0xff); ! else ! printf("%x ", *p & 0xff); ! x++; ! if (x && !(x % 8)) ! printf(" "); ! if (x && !(x % 16)) { ! if(x < 0x100) ! printf("\n000000%x ", x); ! else ! printf("\n00000%x ", x); ! } ! p++; ! } ! printf("\n"); ! } #endif + /* Check for NetBSD disk label. */ + dlp = (struct disklabel *) (buf + LABELOFFSET); + if (dlp->d_magic == DISKMAGIC && !dkcksum(dlp) && + dlp->d_partitions[part].p_fstype == FS_RAID) { + #ifdef DEBUG_PROM + printf("israidlabel: found RAID partition, " + "adjusting offset to %ld\n", RF_PROTECTED_SECTORS); + #endif + doffset = RF_PROTECTED_SECTORS; + } + } + #endif /* BOOTXX */ void putchar(int c) *************** devopen(struct open_file *f, const char *** 127,147 **** { int error = 0, fd = 0; struct promdata *pd; - #ifndef BOOTXX - char *partition; - int part = 0; - char rawpart[MAX_PROM_PATH]; - struct promdata *disk_pd; - char buf[DEV_BSIZE]; - struct disklabel *dlp; - size_t read; - #endif pd = (struct promdata *)alloc(sizeof *pd); f->f_devdata = (void *)pd; switch (prom_version()) { case PROM_OLDMON: error = oldmon_iopen(pd); #ifndef BOOTXX pd->xmit = oldmon_xmit; --- 194,208 ---- { int error = 0, fd = 0; struct promdata *pd; pd = (struct promdata *)alloc(sizeof *pd); f->f_devdata = (void *)pd; switch (prom_version()) { case PROM_OLDMON: + #ifdef DEBUG_PROM + printf("devopen: PROM_OLDMON\n"); + #endif error = oldmon_iopen(pd); #ifndef BOOTXX pd->xmit = oldmon_xmit; *************** devopen(struct open_file *f, const char *** 168,173 **** --- 229,237 ---- pd->fd = fd; switch (prom_version()) { case PROM_OBP_V0: + #ifdef DEBUG_PROM + printf("devopen: PROM_OBP_V0\n"); + #endif #ifndef BOOTXX pd->xmit = obp_v0_xmit; pd->recv = obp_v0_recv; *************** devopen(struct open_file *f, const char *** 177,182 **** --- 241,249 ---- case PROM_OBP_V2: case PROM_OBP_V3: case PROM_OPENFIRM: + #ifdef DEBUG_PROM + printf("devopen: PROM_OBP_V2+\n"); + #endif #ifndef BOOTXX pd->xmit = obp_v2_xmit; pd->recv = obp_v2_recv; *************** devopen(struct open_file *f, const char *** 207,292 **** prom_bootdevice); return (error); } ! } else { memcpy(file_system, file_system_ufs, sizeof(struct fs_ops) * nfsys); ! #ifdef NOTDEF_DEBUG ! printf("devopen: Checking disklabel for RAID partition\n"); ! #endif ! ! /* ! * Don't check disklabel on floppy boot since ! * reopening it could cause Data Access Exception later. ! */ ! if (bootdev_isfloppy(prom_bootdevice)) ! return 0; ! ! /* ! * We need to read from the raw partition (i.e. the ! * beginning of the disk in order to check the NetBSD ! * disklabel to see if the boot partition is type RAID. ! * ! * For machines with prom_version() == PROM_OLDMON, we ! * only handle boot from RAID for the first disk partition. ! */ ! disk_pd = (struct promdata *)alloc(sizeof *disk_pd); ! memcpy(disk_pd, pd, sizeof(struct promdata)); ! if (prom_version() != PROM_OLDMON) { ! strcpy(rawpart, prom_bootdevice); ! if ((partition = strchr(rawpart, ':')) != NULL && ! *++partition >= 'a' && ! *partition <= 'a' + MAXPARTITIONS) { ! part = *partition - 'a'; ! *partition = RAW_PART + 'a'; ! } else ! strcat(rawpart, ":c"); ! if ((disk_pd->fd = prom_open(rawpart)) == 0) ! return 0; ! } ! error = f->f_dev->dv_strategy(disk_pd, F_READ, LABELSECTOR, ! DEV_BSIZE, &buf, &read); ! if (prom_version() != PROM_OLDMON) ! prom_close(disk_pd->fd); ! if (error || (read != DEV_BSIZE)) ! return 0; ! #ifdef NOTDEF_DEBUG ! { ! int x = 0; ! char *p = (char *) buf; ! ! printf(" Sector %d:\n", LABELSECTOR); ! printf("00000000 "); ! while (x < DEV_BSIZE) { ! if (*p >= 0x00 && *p < 0x10) ! printf("0%x ", *p & 0xff); ! else ! printf("%x ", *p & 0xff); ! x++; ! if (x && !(x % 8)) ! printf(" "); ! if (x && !(x % 16)) { ! if(x < 0x100) ! printf("\n000000%x ", x); ! else ! printf("\n00000%x ", x); ! } ! p++; ! } ! printf("\n"); ! } ! #endif ! /* Check for NetBSD disk label. */ ! dlp = (struct disklabel *) (buf + LABELOFFSET); ! if (dlp->d_magic == DISKMAGIC && !dkcksum(dlp) && ! dlp->d_partitions[part].p_fstype == FS_RAID) { ! #ifdef NOTDEF_DEBUG ! printf("devopen: found RAID partition, " ! "adjusting offset to %d\n", RF_PROTECTED_SECTORS); ! #endif ! doffset = RF_PROTECTED_SECTORS; ! } ! } #endif /* BOOTXX */ return (0); } --- 274,286 ---- prom_bootdevice); return (error); } ! } else memcpy(file_system, file_system_ufs, sizeof(struct fs_ops) * nfsys); ! /* Don't check disklabel for RAID on floppy boot */ ! if (bootdev_isfloppy(prom_bootdevice)) ! raidchecked = 1; #endif /* BOOTXX */ return (0); } *************** obp_v0_strategy(void *devdata, int flag, *** 299,309 **** int n, error = 0; struct promdata *pd = (struct promdata *)devdata; int fd = pd->fd; - #ifndef BOOTXX ! dblk += doffset; #endif #ifdef DEBUG_PROM printf("promstrategy: size=%zd dblk=%d\n", size, (int)dblk); #endif --- 293,304 ---- int n, error = 0; struct promdata *pd = (struct promdata *)devdata; int fd = pd->fd; #ifndef BOOTXX ! char labelbuf[DEV_BSIZE]; #endif + #ifdef DEBUG_PROM + if (dblk < 3000) printf("promstrategy: size=%zd dblk=%d\n", size, (int)dblk); #endif *************** obp_v0_strategy(void *devdata, int flag, *** 317,322 **** --- 312,324 ---- printf("promstrategy: non-block device not supported\n"); error = EINVAL; } + + if (!raidchecked && flag == F_READ) { + prom_bread(fd, btodb(DEV_BSIZE), LABELSECTOR, &labelbuf[0]); + israidlabel(&labelbuf[0]); + raidchecked = 1; + } + dblk += doffset; #endif n = (flag == F_READ) *************** obp_v0_strategy(void *devdata, int flag, *** 326,331 **** --- 328,334 ---- *rsize = dbtob(n); #ifdef DEBUG_PROM + if (dblk < 3000) printf("rsize = %zx\n", *rsize); #endif return (error); *************** obp_v2_strategy(void *devdata, int flag, *** 338,352 **** int error = 0; struct promdata *pd = (struct promdata *)devdata; int fd = pd->fd; - #ifndef BOOTXX ! dblk += doffset; #endif #ifdef DEBUG_PROM printf("promstrategy: size=%zd dblk=%d\n", size, (int)dblk); #endif ! #ifndef BOOTXX /* We know it's a block device, so save some space */ if (pd->devtype == DT_BLOCK) #endif prom_seek(fd, dbtob(dblk)); --- 341,365 ---- int error = 0; struct promdata *pd = (struct promdata *)devdata; int fd = pd->fd; #ifndef BOOTXX ! char labelbuf[DEV_BSIZE]; #endif + #ifdef DEBUG_PROM + if (dblk < 3000) printf("promstrategy: size=%zd dblk=%d\n", size, (int)dblk); #endif ! #ifndef BOOTXX ! if (!raidchecked && flag == F_READ) { ! prom_seek(fd, dbtob(LABELSECTOR)); ! prom_read(fd, &labelbuf[0], DEV_BSIZE); ! israidlabel(&labelbuf[0]); ! raidchecked = 1; ! } ! dblk += doffset; ! ! /* We know it's a block device, so save some space */ if (pd->devtype == DT_BLOCK) #endif prom_seek(fd, dbtob(dblk)); *************** obp_v2_strategy(void *devdata, int flag, *** 356,361 **** --- 369,375 ---- : prom_write(fd, buf, size); #ifdef DEBUG_PROM + if (dblk < 3000) printf("rsize = %zx\n", *rsize); #endif return (error); *************** oldmon_strategy(void *devdata, int flag, *** 374,379 **** --- 388,396 ---- char *dmabuf; int si_flag; size_t xcnt; + #ifndef BOOTXX + char labelbuf[DEV_BSIZE]; + #endif si = pd->si; ops = si->si_boottab; *************** oldmon_strategy(void *devdata, int flag, *** 382,392 **** dblk += doffset; #endif #ifdef DEBUG_PROM printf("prom_strategy: size=%zd dblk=%d\n", size, (int)dblk); #endif dmabuf = dvma_mapin(buf, size); ! si->si_bn = dblk; si->si_ma = dmabuf; si->si_cc = size; --- 399,424 ---- dblk += doffset; #endif #ifdef DEBUG_PROM + if (dblk < 3000) printf("prom_strategy: size=%zd dblk=%d\n", size, (int)dblk); #endif + + #ifndef BOOTXX + if (!raidchecked && flag == F_READ) { + dmabuf = dvma_mapin(&labelbuf[0], DEV_BSIZE); + si->si_bn = LABELSECTOR; + si->si_cc = DEV_BSIZE; + si_flag = SAIO_F_READ; + xcnt = (*ops->b_strategy)(si, si_flag); + dvma_mapout(dmabuf, DEV_BSIZE); + israidlabel(&labelbuf[0]); + raidchecked = 1; + } + dblk += doffset; + #endif dmabuf = dvma_mapin(buf, size); ! si->si_bn = dblk; si->si_ma = dmabuf; si->si_cc = size; *************** oldmon_strategy(void *devdata, int flag, *** 396,401 **** --- 428,434 ---- dvma_mapout(dmabuf, size); #ifdef DEBUG_PROM + if (dblk < 3000) printf("disk_strategy: xcnt = %zx\n", xcnt); #endif