int chsc_secm(struct channel_subsystem *css, int enable) { int ret; if (enable && !css->cm_enabled) { css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!css->cub_addr1 || !css->cub_addr2) { free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr2); return -ENOMEM; } } ret = __chsc_do_secm(css, enable); if (!ret) { css->cm_enabled = enable; if (css->cm_enabled) { ret = chsc_add_cmg_attr(css); if (ret) { __chsc_do_secm(css, 0); css->cm_enabled = 0; } } else chsc_remove_cmg_attr(css); } if (!css->cm_enabled) { free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr2); } return ret; }
int chsc_secm(struct channel_subsystem *css, int enable) { void *secm_area; int ret; secm_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!secm_area) return -ENOMEM; if (enable && !css->cm_enabled) { css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!css->cub_addr1 || !css->cub_addr2) { free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr2); free_page((unsigned long)secm_area); return -ENOMEM; } } ret = __chsc_do_secm(css, enable, secm_area); if (!ret) { css->cm_enabled = enable; if (css->cm_enabled) { ret = chsc_add_cmg_attr(css); if (ret) { memset(secm_area, 0, PAGE_SIZE); __chsc_do_secm(css, 0, secm_area); css->cm_enabled = 0; } } else chsc_remove_cmg_attr(css); } if (!css->cm_enabled) { free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr2); } free_page((unsigned long)secm_area); return ret; }