2691 cmlb_dbg(CMLB_INFO, cl, "fdisk moved 0x%x 0x%lx",
2692 solaris_offset, solaris_size);
2693 bzero(&cl->cl_g, sizeof (struct dk_geom));
2694 bzero(&cl->cl_vtoc, sizeof (struct dk_vtoc));
2695 bzero(&cl->cl_map, NDKMAP * (sizeof (struct dk_map)));
2696 cl->cl_f_geometry_is_valid = B_FALSE;
2697 }
2698 cl->cl_solaris_offset = solaris_offset;
2699 cl->cl_solaris_size = solaris_size;
2700 kmem_free(bufp, blocksize);
2701 return (rval);
2702
2703 #else /* #elif defined(_FIRMWARE_NEEDS_FDISK) */
2704 #error "fdisk table presence undetermined for this platform."
2705 #endif /* #if defined(_NO_FDISK_PRESENT) */
2706 }
2707
2708 static void
2709 cmlb_swap_efi_gpt(efi_gpt_t *e)
2710 {
2711 _NOTE(ASSUMING_PROTECTED(*e))
2712 e->efi_gpt_Signature = LE_64(e->efi_gpt_Signature);
2713 e->efi_gpt_Revision = LE_32(e->efi_gpt_Revision);
2714 e->efi_gpt_HeaderSize = LE_32(e->efi_gpt_HeaderSize);
2715 e->efi_gpt_HeaderCRC32 = LE_32(e->efi_gpt_HeaderCRC32);
2716 e->efi_gpt_MyLBA = LE_64(e->efi_gpt_MyLBA);
2717 e->efi_gpt_AlternateLBA = LE_64(e->efi_gpt_AlternateLBA);
2718 e->efi_gpt_FirstUsableLBA = LE_64(e->efi_gpt_FirstUsableLBA);
2719 e->efi_gpt_LastUsableLBA = LE_64(e->efi_gpt_LastUsableLBA);
2720 UUID_LE_CONVERT(e->efi_gpt_DiskGUID, e->efi_gpt_DiskGUID);
2721 e->efi_gpt_PartitionEntryLBA = LE_64(e->efi_gpt_PartitionEntryLBA);
2722 e->efi_gpt_NumberOfPartitionEntries =
2723 LE_32(e->efi_gpt_NumberOfPartitionEntries);
2724 e->efi_gpt_SizeOfPartitionEntry =
2725 LE_32(e->efi_gpt_SizeOfPartitionEntry);
2726 e->efi_gpt_PartitionEntryArrayCRC32 =
2727 LE_32(e->efi_gpt_PartitionEntryArrayCRC32);
2728 }
2729
2730 static void
2731 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2732 {
2733 int i;
2734
2735 _NOTE(ASSUMING_PROTECTED(*p))
2736 for (i = 0; i < nparts; i++) {
2737 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2738 p[i].efi_gpe_PartitionTypeGUID);
2739 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2740 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2741 /* PartitionAttrs */
2742 }
2743 }
2744
2745 static int
2746 cmlb_validate_efi(efi_gpt_t *labp)
2747 {
2748 if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2749 return (EINVAL);
2750 /* at least 96 bytes in this version of the spec. */
2751 if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2752 labp->efi_gpt_HeaderSize)
2753 return (EINVAL);
2754 /* this should be 128 bytes */
2755 if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
3839 * ENXIO
3840 * EIO
3841 */
3842 static int
3843 cmlb_dkio_set_partition(struct cmlb_lun *cl, caddr_t arg, int flag)
3844 {
3845 struct dk_map dk_map[NDKMAP];
3846 struct dk_map *lp;
3847 int rval = 0;
3848 int size;
3849 int i;
3850 #if defined(_SUNOS_VTOC_16)
3851 struct dkl_partition *vp;
3852 #endif
3853
3854 /*
3855 * Set the map for all logical partitions. We lock
3856 * the priority just to make sure an interrupt doesn't
3857 * come in while the map is half updated.
3858 */
3859 _NOTE(DATA_READABLE_WITHOUT_LOCK(cmlb_lun::cl_solaris_size))
3860 mutex_enter(CMLB_MUTEX(cl));
3861
3862 if (cl->cl_blockcount > CMLB_OLDVTOC_LIMIT) {
3863 mutex_exit(CMLB_MUTEX(cl));
3864 return (ENOTSUP);
3865 }
3866 mutex_exit(CMLB_MUTEX(cl));
3867 if (cl->cl_solaris_size == 0) {
3868 return (EIO);
3869 }
3870
3871 #ifdef _MULTI_DATAMODEL
3872 switch (ddi_model_convert_from(flag & FMODELS)) {
3873 case DDI_MODEL_ILP32: {
3874 struct dk_map32 dk_map32[NDKMAP];
3875
3876 size = NDKMAP * sizeof (struct dk_map32);
3877 rval = ddi_copyin((void *)arg, dk_map32, size, flag);
3878 if (rval != 0) {
3879 return (EFAULT);
5160 kmem_free(mboot, cl->cl_sys_blocksize);
5161 return (EINVAL);
5162 }
5163
5164 rval = DK_TG_WRITE(cl, mboot, 0, cl->cl_sys_blocksize, tg_cookie);
5165
5166 mutex_enter(CMLB_MUTEX(cl));
5167 #if defined(__i386) || defined(__amd64)
5168 if (rval == 0) {
5169 /*
5170 * mboot has been written successfully.
5171 * update the fdisk and vtoc tables in memory
5172 */
5173 rval = cmlb_update_fdisk_and_vtoc(cl, tg_cookie);
5174 if ((!cl->cl_f_geometry_is_valid) || (rval != 0)) {
5175 mutex_exit(CMLB_MUTEX(cl));
5176 kmem_free(mboot, cl->cl_sys_blocksize);
5177 return (rval);
5178 }
5179 }
5180
5181 #ifdef __lock_lint
5182 cmlb_setup_default_geometry(cl, tg_cookie);
5183 #endif
5184
5185 #else
5186 if (rval == 0) {
5187 /*
5188 * mboot has been written successfully.
5189 * set up the default geometry and VTOC
5190 */
5191 if (cl->cl_blockcount <= CMLB_EXTVTOC_LIMIT)
5192 cmlb_setup_default_geometry(cl, tg_cookie);
5193 }
5194 #endif
5195 cl->cl_msglog_flag |= CMLB_ALLOW_2TB_WARN;
5196 mutex_exit(CMLB_MUTEX(cl));
5197 kmem_free(mboot, cl->cl_sys_blocksize);
5198 return (rval);
5199 }
5200
5201
5202 #if defined(__i386) || defined(__amd64)
5203 /*ARGSUSED*/
5204 static int
|
2691 cmlb_dbg(CMLB_INFO, cl, "fdisk moved 0x%x 0x%lx",
2692 solaris_offset, solaris_size);
2693 bzero(&cl->cl_g, sizeof (struct dk_geom));
2694 bzero(&cl->cl_vtoc, sizeof (struct dk_vtoc));
2695 bzero(&cl->cl_map, NDKMAP * (sizeof (struct dk_map)));
2696 cl->cl_f_geometry_is_valid = B_FALSE;
2697 }
2698 cl->cl_solaris_offset = solaris_offset;
2699 cl->cl_solaris_size = solaris_size;
2700 kmem_free(bufp, blocksize);
2701 return (rval);
2702
2703 #else /* #elif defined(_FIRMWARE_NEEDS_FDISK) */
2704 #error "fdisk table presence undetermined for this platform."
2705 #endif /* #if defined(_NO_FDISK_PRESENT) */
2706 }
2707
2708 static void
2709 cmlb_swap_efi_gpt(efi_gpt_t *e)
2710 {
2711 e->efi_gpt_Signature = LE_64(e->efi_gpt_Signature);
2712 e->efi_gpt_Revision = LE_32(e->efi_gpt_Revision);
2713 e->efi_gpt_HeaderSize = LE_32(e->efi_gpt_HeaderSize);
2714 e->efi_gpt_HeaderCRC32 = LE_32(e->efi_gpt_HeaderCRC32);
2715 e->efi_gpt_MyLBA = LE_64(e->efi_gpt_MyLBA);
2716 e->efi_gpt_AlternateLBA = LE_64(e->efi_gpt_AlternateLBA);
2717 e->efi_gpt_FirstUsableLBA = LE_64(e->efi_gpt_FirstUsableLBA);
2718 e->efi_gpt_LastUsableLBA = LE_64(e->efi_gpt_LastUsableLBA);
2719 UUID_LE_CONVERT(e->efi_gpt_DiskGUID, e->efi_gpt_DiskGUID);
2720 e->efi_gpt_PartitionEntryLBA = LE_64(e->efi_gpt_PartitionEntryLBA);
2721 e->efi_gpt_NumberOfPartitionEntries =
2722 LE_32(e->efi_gpt_NumberOfPartitionEntries);
2723 e->efi_gpt_SizeOfPartitionEntry =
2724 LE_32(e->efi_gpt_SizeOfPartitionEntry);
2725 e->efi_gpt_PartitionEntryArrayCRC32 =
2726 LE_32(e->efi_gpt_PartitionEntryArrayCRC32);
2727 }
2728
2729 static void
2730 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2731 {
2732 int i;
2733
2734 for (i = 0; i < nparts; i++) {
2735 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2736 p[i].efi_gpe_PartitionTypeGUID);
2737 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2738 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2739 /* PartitionAttrs */
2740 }
2741 }
2742
2743 static int
2744 cmlb_validate_efi(efi_gpt_t *labp)
2745 {
2746 if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2747 return (EINVAL);
2748 /* at least 96 bytes in this version of the spec. */
2749 if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2750 labp->efi_gpt_HeaderSize)
2751 return (EINVAL);
2752 /* this should be 128 bytes */
2753 if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
3837 * ENXIO
3838 * EIO
3839 */
3840 static int
3841 cmlb_dkio_set_partition(struct cmlb_lun *cl, caddr_t arg, int flag)
3842 {
3843 struct dk_map dk_map[NDKMAP];
3844 struct dk_map *lp;
3845 int rval = 0;
3846 int size;
3847 int i;
3848 #if defined(_SUNOS_VTOC_16)
3849 struct dkl_partition *vp;
3850 #endif
3851
3852 /*
3853 * Set the map for all logical partitions. We lock
3854 * the priority just to make sure an interrupt doesn't
3855 * come in while the map is half updated.
3856 */
3857 mutex_enter(CMLB_MUTEX(cl));
3858
3859 if (cl->cl_blockcount > CMLB_OLDVTOC_LIMIT) {
3860 mutex_exit(CMLB_MUTEX(cl));
3861 return (ENOTSUP);
3862 }
3863 mutex_exit(CMLB_MUTEX(cl));
3864 if (cl->cl_solaris_size == 0) {
3865 return (EIO);
3866 }
3867
3868 #ifdef _MULTI_DATAMODEL
3869 switch (ddi_model_convert_from(flag & FMODELS)) {
3870 case DDI_MODEL_ILP32: {
3871 struct dk_map32 dk_map32[NDKMAP];
3872
3873 size = NDKMAP * sizeof (struct dk_map32);
3874 rval = ddi_copyin((void *)arg, dk_map32, size, flag);
3875 if (rval != 0) {
3876 return (EFAULT);
5157 kmem_free(mboot, cl->cl_sys_blocksize);
5158 return (EINVAL);
5159 }
5160
5161 rval = DK_TG_WRITE(cl, mboot, 0, cl->cl_sys_blocksize, tg_cookie);
5162
5163 mutex_enter(CMLB_MUTEX(cl));
5164 #if defined(__i386) || defined(__amd64)
5165 if (rval == 0) {
5166 /*
5167 * mboot has been written successfully.
5168 * update the fdisk and vtoc tables in memory
5169 */
5170 rval = cmlb_update_fdisk_and_vtoc(cl, tg_cookie);
5171 if ((!cl->cl_f_geometry_is_valid) || (rval != 0)) {
5172 mutex_exit(CMLB_MUTEX(cl));
5173 kmem_free(mboot, cl->cl_sys_blocksize);
5174 return (rval);
5175 }
5176 }
5177 #else
5178 if (rval == 0) {
5179 /*
5180 * mboot has been written successfully.
5181 * set up the default geometry and VTOC
5182 */
5183 if (cl->cl_blockcount <= CMLB_EXTVTOC_LIMIT)
5184 cmlb_setup_default_geometry(cl, tg_cookie);
5185 }
5186 #endif
5187 cl->cl_msglog_flag |= CMLB_ALLOW_2TB_WARN;
5188 mutex_exit(CMLB_MUTEX(cl));
5189 kmem_free(mboot, cl->cl_sys_blocksize);
5190 return (rval);
5191 }
5192
5193
5194 #if defined(__i386) || defined(__amd64)
5195 /*ARGSUSED*/
5196 static int
|