4141#define IPL_UNKNOWN_STR "unknown"
4242#define IPL_CCW_STR "ccw"
4343#define IPL_ECKD_STR "eckd"
44+ #define IPL_ECKD_DUMP_STR "eckd_dump"
4445#define IPL_FCP_STR "fcp"
4546#define IPL_FCP_DUMP_STR "fcp_dump"
4647#define IPL_NVME_STR "nvme"
4748#define IPL_NVME_DUMP_STR "nvme_dump"
4849#define IPL_NSS_STR "nss"
4950
5051#define DUMP_CCW_STR "ccw"
52+ #define DUMP_ECKD_STR "eckd"
5153#define DUMP_FCP_STR "fcp"
5254#define DUMP_NVME_STR "nvme"
5355#define DUMP_NONE_STR "none"
@@ -96,6 +98,8 @@ static char *ipl_type_str(enum ipl_type type)
9698 return IPL_CCW_STR ;
9799 case IPL_TYPE_ECKD :
98100 return IPL_ECKD_STR ;
101+ case IPL_TYPE_ECKD_DUMP :
102+ return IPL_ECKD_DUMP_STR ;
99103 case IPL_TYPE_FCP :
100104 return IPL_FCP_STR ;
101105 case IPL_TYPE_FCP_DUMP :
@@ -117,6 +121,7 @@ enum dump_type {
117121 DUMP_TYPE_CCW = 2 ,
118122 DUMP_TYPE_FCP = 4 ,
119123 DUMP_TYPE_NVME = 8 ,
124+ DUMP_TYPE_ECKD = 16 ,
120125};
121126
122127static char * dump_type_str (enum dump_type type )
@@ -126,6 +131,8 @@ static char *dump_type_str(enum dump_type type)
126131 return DUMP_NONE_STR ;
127132 case DUMP_TYPE_CCW :
128133 return DUMP_CCW_STR ;
134+ case DUMP_TYPE_ECKD :
135+ return DUMP_ECKD_STR ;
129136 case DUMP_TYPE_FCP :
130137 return DUMP_FCP_STR ;
131138 case DUMP_TYPE_NVME :
@@ -160,6 +167,7 @@ static enum dump_type dump_type = DUMP_TYPE_NONE;
160167static struct ipl_parameter_block * dump_block_fcp ;
161168static struct ipl_parameter_block * dump_block_nvme ;
162169static struct ipl_parameter_block * dump_block_ccw ;
170+ static struct ipl_parameter_block * dump_block_eckd ;
163171
164172static struct sclp_ipl_info sclp_ipl_info ;
165173
@@ -288,7 +296,10 @@ static __init enum ipl_type get_ipl_type(void)
288296 else
289297 return IPL_TYPE_NVME ;
290298 case IPL_PBT_ECKD :
291- return IPL_TYPE_ECKD ;
299+ if (ipl_block .eckd .opt == IPL_PB0_ECKD_OPT_DUMP )
300+ return IPL_TYPE_ECKD_DUMP ;
301+ else
302+ return IPL_TYPE_ECKD ;
292303 }
293304 return IPL_TYPE_UNKNOWN ;
294305}
@@ -343,6 +354,7 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
343354 return sprintf (page , "0.%x.%04x\n" , ipl_block .ccw .ssid ,
344355 ipl_block .ccw .devno );
345356 case IPL_TYPE_ECKD :
357+ case IPL_TYPE_ECKD_DUMP :
346358 return sprintf (page , "0.%x.%04x\n" , ipl_block .eckd .ssid ,
347359 ipl_block .eckd .devno );
348360 case IPL_TYPE_FCP :
@@ -1368,6 +1380,7 @@ static void __reipl_run(void *unused)
13681380 break ;
13691381 case IPL_TYPE_FCP_DUMP :
13701382 case IPL_TYPE_NVME_DUMP :
1383+ case IPL_TYPE_ECKD_DUMP :
13711384 break ;
13721385 }
13731386 disabled_wait ();
@@ -1736,6 +1749,31 @@ static struct attribute_group dump_nvme_attr_group = {
17361749 .attrs = dump_nvme_attrs ,
17371750};
17381751
1752+ /* ECKD dump device attributes */
1753+ DEFINE_IPL_CCW_ATTR_RW (dump_eckd , device , dump_block_eckd -> eckd );
1754+ DEFINE_IPL_ATTR_RW (dump_eckd , bootprog , "%lld\n" , "%llx\n" ,
1755+ dump_block_eckd -> eckd .bootprog );
1756+
1757+ IPL_ATTR_BR_CHR_SHOW_FN (dump , dump_block_eckd -> eckd );
1758+ IPL_ATTR_BR_CHR_STORE_FN (dump , dump_block_eckd -> eckd );
1759+
1760+ static struct kobj_attribute sys_dump_eckd_br_chr_attr =
1761+ __ATTR (br_chr , (S_IRUGO | S_IWUSR ),
1762+ eckd_dump_br_chr_show ,
1763+ eckd_dump_br_chr_store );
1764+
1765+ static struct attribute * dump_eckd_attrs [] = {
1766+ & sys_dump_eckd_device_attr .attr ,
1767+ & sys_dump_eckd_bootprog_attr .attr ,
1768+ & sys_dump_eckd_br_chr_attr .attr ,
1769+ NULL ,
1770+ };
1771+
1772+ static struct attribute_group dump_eckd_attr_group = {
1773+ .name = IPL_ECKD_STR ,
1774+ .attrs = dump_eckd_attrs ,
1775+ };
1776+
17391777/* CCW dump device attributes */
17401778DEFINE_IPL_CCW_ATTR_RW (dump_ccw , device , dump_block_ccw -> ccw );
17411779
@@ -1775,6 +1813,8 @@ static ssize_t dump_type_store(struct kobject *kobj,
17751813 rc = dump_set_type (DUMP_TYPE_NONE );
17761814 else if (strncmp (buf , DUMP_CCW_STR , strlen (DUMP_CCW_STR )) == 0 )
17771815 rc = dump_set_type (DUMP_TYPE_CCW );
1816+ else if (strncmp (buf , DUMP_ECKD_STR , strlen (DUMP_ECKD_STR )) == 0 )
1817+ rc = dump_set_type (DUMP_TYPE_ECKD );
17781818 else if (strncmp (buf , DUMP_FCP_STR , strlen (DUMP_FCP_STR )) == 0 )
17791819 rc = dump_set_type (DUMP_TYPE_FCP );
17801820 else if (strncmp (buf , DUMP_NVME_STR , strlen (DUMP_NVME_STR )) == 0 )
@@ -1803,6 +1843,9 @@ static void __dump_run(void *unused)
18031843 case DUMP_TYPE_CCW :
18041844 diag308_dump (dump_block_ccw );
18051845 break ;
1846+ case DUMP_TYPE_ECKD :
1847+ diag308_dump (dump_block_eckd );
1848+ break ;
18061849 case DUMP_TYPE_FCP :
18071850 diag308_dump (dump_block_fcp );
18081851 break ;
@@ -1888,6 +1931,29 @@ static int __init dump_nvme_init(void)
18881931 return 0 ;
18891932}
18901933
1934+ static int __init dump_eckd_init (void )
1935+ {
1936+ int rc ;
1937+
1938+ if (!sclp_ipl_info .has_dump || !sclp .has_sipl_eckd )
1939+ return 0 ; /* LDIPL DUMP is not installed */
1940+ dump_block_eckd = (void * )get_zeroed_page (GFP_KERNEL );
1941+ if (!dump_block_eckd )
1942+ return - ENOMEM ;
1943+ rc = sysfs_create_group (& dump_kset -> kobj , & dump_eckd_attr_group );
1944+ if (rc ) {
1945+ free_page ((unsigned long )dump_block_eckd );
1946+ return rc ;
1947+ }
1948+ dump_block_eckd -> hdr .len = IPL_BP_ECKD_LEN ;
1949+ dump_block_eckd -> hdr .version = IPL_PARM_BLOCK_VERSION ;
1950+ dump_block_eckd -> eckd .len = IPL_BP0_ECKD_LEN ;
1951+ dump_block_eckd -> eckd .pbt = IPL_PBT_ECKD ;
1952+ dump_block_eckd -> eckd .opt = IPL_PB0_ECKD_OPT_DUMP ;
1953+ dump_capabilities |= DUMP_TYPE_ECKD ;
1954+ return 0 ;
1955+ }
1956+
18911957static int __init dump_init (void )
18921958{
18931959 int rc ;
@@ -1901,6 +1967,9 @@ static int __init dump_init(void)
19011967 return rc ;
19021968 }
19031969 rc = dump_ccw_init ();
1970+ if (rc )
1971+ return rc ;
1972+ rc = dump_eckd_init ();
19041973 if (rc )
19051974 return rc ;
19061975 rc = dump_fcp_init ();
@@ -2337,6 +2406,7 @@ void __init setup_ipl(void)
23372406 ipl_info .data .ccw .dev_id .devno = ipl_block .ccw .devno ;
23382407 break ;
23392408 case IPL_TYPE_ECKD :
2409+ case IPL_TYPE_ECKD_DUMP :
23402410 ipl_info .data .eckd .dev_id .ssid = ipl_block .eckd .ssid ;
23412411 ipl_info .data .eckd .dev_id .devno = ipl_block .eckd .devno ;
23422412 break ;
0 commit comments