Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *    SE/HMC Drive (Read) Cache Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *    Copyright IBM Corp. 2013
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *    Author(s): Ralf Hoppe (rhoppe@de.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define KMSG_COMPONENT "hmcdrv"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "hmcdrv_ftp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "hmcdrv_cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define HMCDRV_CACHE_TIMEOUT		30 /* aging timeout in seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * struct hmcdrv_cache_entry - file cache (only used on read/dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * @id: FTP command ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * @content: kernel-space buffer, 4k aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * @len: size of @content cache (0 if caching disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * @ofs: start of content within file (-1 if no cached content)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * @fname: file name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * @fsize: file size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * @timeout: cache timeout in jiffies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * Notice that the first three members (id, fname, fsize) are cached on all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * read/dir requests. But content is cached only under some preconditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * Uncached content is signalled by a negative value of @ofs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct hmcdrv_cache_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	enum hmcdrv_ftp_cmdid id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	char fname[HMCDRV_FTP_FIDENT_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	size_t fsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	loff_t ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	void *content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static int hmcdrv_cache_order; /* cache allocated page order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static struct hmcdrv_cache_entry hmcdrv_cache_file = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	.fsize = SIZE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	.ofs = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	.len = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	.fname = {'\0'}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * hmcdrv_cache_get() - looks for file data/content in read cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @ftp: pointer to FTP command specification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * Return: number of bytes read from cache or a negative number if nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * in content cache (for the file/cmd specified in @ftp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static ssize_t hmcdrv_cache_get(const struct hmcdrv_ftp_cmdspec *ftp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	loff_t pos; /* position in cache (signed) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if ((ftp->id != hmcdrv_cache_file.id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	    strcmp(hmcdrv_cache_file.fname, ftp->fname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (ftp->ofs >= hmcdrv_cache_file.fsize) /* EOF ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if ((hmcdrv_cache_file.ofs < 0) || /* has content? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	    time_after(jiffies, hmcdrv_cache_file.timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	/* there seems to be cached content - calculate the maximum number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 * of bytes that can be returned (regarding file size and offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	len = hmcdrv_cache_file.fsize - ftp->ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (len > ftp->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		len = ftp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	/* check if the requested chunk falls into our cache (which starts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 * at offset 'hmcdrv_cache_file.ofs' in the file of interest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	pos = ftp->ofs - hmcdrv_cache_file.ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if ((pos >= 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	    ((pos + len) <= hmcdrv_cache_file.len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		memcpy(ftp->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		       hmcdrv_cache_file.content + pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		       len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		pr_debug("using cached content of '%s', returning %zd/%zd bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			 hmcdrv_cache_file.fname, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			 hmcdrv_cache_file.fsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * hmcdrv_cache_do() - do a HMC drive CD/DVD transfer with cache update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * @ftp: pointer to FTP command specification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * @func: FTP transfer function to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * Return: number of bytes read/written or a (negative) error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static ssize_t hmcdrv_cache_do(const struct hmcdrv_ftp_cmdspec *ftp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			       hmcdrv_cache_ftpfunc func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/* only cache content if the read/dir cache really exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * (hmcdrv_cache_file.len > 0), is large enough to handle the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * request (hmcdrv_cache_file.len >= ftp->len) and there is a need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * to do so (ftp->len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if ((ftp->len > 0) && (hmcdrv_cache_file.len >= ftp->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		/* because the cache is not located at ftp->buf, we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		 * assemble a new HMC drive FTP cmd specification (pointing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		 * to our cache, and using the increased size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		struct hmcdrv_ftp_cmdspec cftp = *ftp; /* make a copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		cftp.buf = hmcdrv_cache_file.content;  /* and update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		cftp.len = hmcdrv_cache_file.len;      /* buffer data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		len = func(&cftp, &hmcdrv_cache_file.fsize); /* now do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			pr_debug("caching %zd bytes content for '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				 len, ftp->fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			if (len > ftp->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				len = ftp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			hmcdrv_cache_file.ofs = ftp->ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			hmcdrv_cache_file.timeout = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				HMCDRV_CACHE_TIMEOUT * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			memcpy(ftp->buf, hmcdrv_cache_file.content, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		len = func(ftp, &hmcdrv_cache_file.fsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		hmcdrv_cache_file.ofs = -1; /* invalidate content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		/* cache some file info (FTP command, file name and file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		 * size) unconditionally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		strlcpy(hmcdrv_cache_file.fname, ftp->fname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			HMCDRV_FTP_FIDENT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		hmcdrv_cache_file.id = ftp->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		pr_debug("caching cmd %d, file size %zu for '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			 ftp->id, hmcdrv_cache_file.fsize, ftp->fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * hmcdrv_cache_cmd() - perform a cached HMC drive CD/DVD transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * @ftp: pointer to FTP command specification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * @func: FTP transfer function to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * Attention: Notice that this function is not reentrant - so the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * must ensure exclusive execution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * Return: number of bytes read/written or a (negative) error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ssize_t hmcdrv_cache_cmd(const struct hmcdrv_ftp_cmdspec *ftp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			 hmcdrv_cache_ftpfunc func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if ((ftp->id == HMCDRV_FTP_DIR) || /* read cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	    (ftp->id == HMCDRV_FTP_NLIST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	    (ftp->id == HMCDRV_FTP_GET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		len = hmcdrv_cache_get(ftp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		if (len >= 0) /* got it from cache ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			return len; /* yes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		len = hmcdrv_cache_do(ftp, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (len >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		len = func(ftp, NULL); /* simply do original command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/* invalidate the (read) cache in case there was a write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	 * or an error on read/dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	hmcdrv_cache_file.id = HMCDRV_FTP_NOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	hmcdrv_cache_file.fsize = LLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	hmcdrv_cache_file.ofs = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * hmcdrv_cache_startup() - startup of HMC drive cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * @cachesize: cache size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Return: 0 on success, else a (negative) error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int hmcdrv_cache_startup(size_t cachesize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (cachesize > 0) { /* perform caching ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		hmcdrv_cache_order = get_order(cachesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		hmcdrv_cache_file.content =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			(void *) __get_free_pages(GFP_KERNEL | GFP_DMA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 						  hmcdrv_cache_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (!hmcdrv_cache_file.content) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			pr_err("Allocating the requested cache size of %zu bytes failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			       cachesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		pr_debug("content cache enabled, size is %zu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			 cachesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	hmcdrv_cache_file.len = cachesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * hmcdrv_cache_shutdown() - shutdown of HMC drive cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void hmcdrv_cache_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (hmcdrv_cache_file.content) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		free_pages((unsigned long) hmcdrv_cache_file.content,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			   hmcdrv_cache_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		hmcdrv_cache_file.content = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	hmcdrv_cache_file.id = HMCDRV_FTP_NOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	hmcdrv_cache_file.fsize = LLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	hmcdrv_cache_file.ofs = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	hmcdrv_cache_file.len = 0; /* no cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }