[S390] cio: Clean up chsc response code handling.
This provides unified return codes for common response codes and also makes the debug feature messages more similar and informational. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
6f52ac2971
commit
b9c9a21a7c
@@ -26,6 +26,25 @@
|
|||||||
|
|
||||||
static void *sei_page;
|
static void *sei_page;
|
||||||
|
|
||||||
|
static int chsc_error_from_response(int response)
|
||||||
|
{
|
||||||
|
switch (response) {
|
||||||
|
case 0x0001:
|
||||||
|
return 0;
|
||||||
|
case 0x0002:
|
||||||
|
case 0x0003:
|
||||||
|
case 0x0006:
|
||||||
|
case 0x0007:
|
||||||
|
case 0x0008:
|
||||||
|
case 0x000a:
|
||||||
|
return -EINVAL;
|
||||||
|
case 0x0004:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
default:
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct chsc_ssd_area {
|
struct chsc_ssd_area {
|
||||||
struct chsc_header request;
|
struct chsc_header request;
|
||||||
u16 :10;
|
u16 :10;
|
||||||
@@ -75,11 +94,11 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
|
|||||||
ret = (ccode == 3) ? -ENODEV : -EBUSY;
|
ret = (ccode == 3) ? -ENODEV : -EBUSY;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
if (ssd_area->response.code != 0x0001) {
|
ret = chsc_error_from_response(ssd_area->response.code);
|
||||||
|
if (ret != 0) {
|
||||||
CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n",
|
CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n",
|
||||||
schid.ssid, schid.sch_no,
|
schid.ssid, schid.sch_no,
|
||||||
ssd_area->response.code);
|
ssd_area->response.code);
|
||||||
ret = -EIO;
|
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
if (!ssd_area->sch_valid) {
|
if (!ssd_area->sch_valid) {
|
||||||
@@ -717,36 +736,15 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
|
|||||||
return (ccode == 3) ? -ENODEV : -EBUSY;
|
return (ccode == 3) ? -ENODEV : -EBUSY;
|
||||||
|
|
||||||
switch (secm_area->response.code) {
|
switch (secm_area->response.code) {
|
||||||
case 0x0001: /* Success. */
|
case 0x0102:
|
||||||
ret = 0;
|
case 0x0103:
|
||||||
break;
|
|
||||||
case 0x0003: /* Invalid block. */
|
|
||||||
case 0x0007: /* Invalid format. */
|
|
||||||
case 0x0008: /* Other invalid block. */
|
|
||||||
CIO_CRW_EVENT(2, "Error in chsc request block!\n");
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
|
||||||
case 0x0004: /* Command not provided in model. */
|
|
||||||
CIO_CRW_EVENT(2, "Model does not provide secm\n");
|
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
case 0x0102: /* cub adresses incorrect */
|
|
||||||
CIO_CRW_EVENT(2, "Invalid addresses in chsc request block\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
case 0x0103: /* key error */
|
|
||||||
CIO_CRW_EVENT(2, "Access key error in secm\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
case 0x0105: /* error while starting */
|
|
||||||
CIO_CRW_EVENT(2, "Error while starting channel measurement\n");
|
|
||||||
ret = -EIO;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
|
ret = chsc_error_from_response(secm_area->response.code);
|
||||||
secm_area->response.code);
|
|
||||||
ret = -EIO;
|
|
||||||
}
|
}
|
||||||
|
if (ret != 0)
|
||||||
|
CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
|
||||||
|
secm_area->response.code);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,27 +825,14 @@ int chsc_determine_channel_path_description(struct chp_id chpid,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (scpd_area->response.code) {
|
ret = chsc_error_from_response(scpd_area->response.code);
|
||||||
case 0x0001: /* Success. */
|
if (ret == 0)
|
||||||
|
/* Success. */
|
||||||
memcpy(desc, &scpd_area->desc,
|
memcpy(desc, &scpd_area->desc,
|
||||||
sizeof(struct channel_path_desc));
|
sizeof(struct channel_path_desc));
|
||||||
ret = 0;
|
else
|
||||||
break;
|
CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n",
|
||||||
case 0x0003: /* Invalid block. */
|
|
||||||
case 0x0007: /* Invalid format. */
|
|
||||||
case 0x0008: /* Other invalid block. */
|
|
||||||
CIO_CRW_EVENT(2, "Error in chsc request block!\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
case 0x0004: /* Command not provided in model. */
|
|
||||||
CIO_CRW_EVENT(2, "Model does not provide scpd\n");
|
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
|
|
||||||
scpd_area->response.code);
|
scpd_area->response.code);
|
||||||
ret = -EIO;
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
free_page((unsigned long)scpd_area);
|
free_page((unsigned long)scpd_area);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -923,8 +908,9 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (scmc_area->response.code) {
|
ret = chsc_error_from_response(scmc_area->response.code);
|
||||||
case 0x0001: /* Success. */
|
if (ret == 0) {
|
||||||
|
/* Success. */
|
||||||
if (!scmc_area->not_valid) {
|
if (!scmc_area->not_valid) {
|
||||||
chp->cmg = scmc_area->cmg;
|
chp->cmg = scmc_area->cmg;
|
||||||
chp->shared = scmc_area->shared;
|
chp->shared = scmc_area->shared;
|
||||||
@@ -935,22 +921,9 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
|
|||||||
chp->cmg = -1;
|
chp->cmg = -1;
|
||||||
chp->shared = -1;
|
chp->shared = -1;
|
||||||
}
|
}
|
||||||
ret = 0;
|
} else {
|
||||||
break;
|
CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n",
|
||||||
case 0x0003: /* Invalid block. */
|
|
||||||
case 0x0007: /* Invalid format. */
|
|
||||||
case 0x0008: /* Invalid bit combination. */
|
|
||||||
CIO_CRW_EVENT(2, "Error in chsc request block!\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
case 0x0004: /* Command not provided. */
|
|
||||||
CIO_CRW_EVENT(2, "Model does not provide scmc\n");
|
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
|
|
||||||
scmc_area->response.code);
|
scmc_area->response.code);
|
||||||
ret = -EIO;
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
free_page((unsigned long)scmc_area);
|
free_page((unsigned long)scmc_area);
|
||||||
@@ -1002,21 +975,17 @@ chsc_enable_facility(int operation_code)
|
|||||||
ret = (ret == 3) ? -ENODEV : -EBUSY;
|
ret = (ret == 3) ? -ENODEV : -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sda_area->response.code) {
|
switch (sda_area->response.code) {
|
||||||
case 0x0001: /* everything ok */
|
case 0x0101:
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
case 0x0003: /* invalid request block */
|
|
||||||
case 0x0007:
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
case 0x0004: /* command not provided */
|
|
||||||
case 0x0101: /* facility not provided */
|
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
break;
|
break;
|
||||||
default: /* something went wrong */
|
default:
|
||||||
ret = -EIO;
|
ret = chsc_error_from_response(sda_area->response.code);
|
||||||
}
|
}
|
||||||
|
if (ret != 0)
|
||||||
|
CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
|
||||||
|
operation_code, sda_area->response.code);
|
||||||
out:
|
out:
|
||||||
free_page((unsigned long)sda_area);
|
free_page((unsigned long)sda_area);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1041,33 +1010,27 @@ chsc_determine_css_characteristics(void)
|
|||||||
} __attribute__ ((packed)) *scsc_area;
|
} __attribute__ ((packed)) *scsc_area;
|
||||||
|
|
||||||
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
if (!scsc_area) {
|
if (!scsc_area)
|
||||||
CIO_MSG_EVENT(0, "Was not able to determine available "
|
|
||||||
"CHSCs due to no memory.\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
scsc_area->request.length = 0x0010;
|
scsc_area->request.length = 0x0010;
|
||||||
scsc_area->request.code = 0x0010;
|
scsc_area->request.code = 0x0010;
|
||||||
|
|
||||||
result = chsc(scsc_area);
|
result = chsc(scsc_area);
|
||||||
if (result) {
|
if (result) {
|
||||||
CIO_MSG_EVENT(0, "Was not able to determine available CHSCs, "
|
result = (result == 3) ? -ENODEV : -EBUSY;
|
||||||
"cc=%i.\n", result);
|
|
||||||
result = -EIO;
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scsc_area->response.code != 1) {
|
result = chsc_error_from_response(scsc_area->response.code);
|
||||||
CIO_MSG_EVENT(0, "Was not able to determine "
|
if (result == 0) {
|
||||||
"available CHSCs.\n");
|
memcpy(&css_general_characteristics, scsc_area->general_char,
|
||||||
result = -EIO;
|
sizeof(css_general_characteristics));
|
||||||
goto exit;
|
memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
|
||||||
}
|
sizeof(css_chsc_characteristics));
|
||||||
memcpy(&css_general_characteristics, scsc_area->general_char,
|
} else
|
||||||
sizeof(css_general_characteristics));
|
CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
|
||||||
memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
|
scsc_area->response.code);
|
||||||
sizeof(css_chsc_characteristics));
|
|
||||||
exit:
|
exit:
|
||||||
free_page ((unsigned long) scsc_area);
|
free_page ((unsigned long) scsc_area);
|
||||||
return result;
|
return result;
|
||||||
|
Reference in New Issue
Block a user