zipl/boot: Introduce write_addr_range() helper function

Move code from write_dump_segment() to write_addr_range() function to use
it later for writing compressed dump segments as well.

Verify that passed address range is a multiple of dasd block size.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Mikhail Zaslonko
2023-03-02 11:50:08 +01:00
committed by Jan Höppner
parent 7b68552359
commit 0dac47cb62
2 changed files with 31 additions and 13 deletions
+30 -13
View File
@@ -447,25 +447,23 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
}
/*
* Write dump segment with the header to DASD and return the next free
* block number
* Write len/device.blk_size blocks of data at start address starting from
* given block and return the next free block number. The len value must be
* a multiple of a block size (4096 bytes).
*/
unsigned long write_dump_segment(unsigned long blk,
struct df_s390_dump_segm_hdr *segm)
unsigned long write_addr_range(unsigned long blk, unsigned long start, unsigned long len)
{
unsigned long addr, start_blk, blk_count, zero_page;
/* Write the dump segment header itself (1 page) */
zero_page = get_zeroed_page();
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
free_page(zero_page);
blk += m2b(PAGE_SIZE);
/* Write the dump segment */
addr = segm->start;
/* Verify the range is a multiple of a block size */
if (len % device.blk_size)
panic(EINTERNAL, "Invalid address range: [%016x, %016x]",
start, start + len);
addr = start;
start_blk = blk;
while (addr < segm->start + segm->len) {
while (addr < start + len) {
/* Remaining blocks to write */
blk_count = m2b(segm->len) - (blk - start_blk);
blk_count = m2b(len) - (blk - start_blk);
blk_count = MIN(blk_count, eckd_blk_max);
zero_page = get_zeroed_page();
writeblock(blk, addr, blk_count, zero_page);
@@ -477,6 +475,25 @@ unsigned long write_dump_segment(unsigned long blk,
return blk;
}
/*
* Write dump segment with the header to DASD and return the next free
* block number
*/
unsigned long write_dump_segment(unsigned long blk,
struct df_s390_dump_segm_hdr *segm)
{
unsigned long zero_page;
/* Write the dump segment header itself (1 page) */
zero_page = get_zeroed_page();
writeblock(blk, (unsigned long)segm,
m2b(sizeof(struct df_s390_dump_segm_hdr)), zero_page);
free_page(zero_page);
blk += m2b(PAGE_SIZE);
/* Write the dump segment */
return write_addr_range(blk, segm->start, segm->len);
}
/*
* Init ECKD common
*/
+1
View File
@@ -51,5 +51,6 @@ void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
unsigned long write_dump_segment(unsigned long blk,
struct df_s390_dump_segm_hdr *segm);
unsigned long write_addr_range(unsigned long blk, unsigned long addr, unsigned long len);
#endif /* ECKD2DUMP_H */