Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_BADBLOCKS_H
0003 #define _LINUX_BADBLOCKS_H
0004 
0005 #include <linux/seqlock.h>
0006 #include <linux/device.h>
0007 #include <linux/kernel.h>
0008 #include <linux/stddef.h>
0009 #include <linux/types.h>
0010 
0011 #define BB_LEN_MASK (0x00000000000001FFULL)
0012 #define BB_OFFSET_MASK  (0x7FFFFFFFFFFFFE00ULL)
0013 #define BB_ACK_MASK (0x8000000000000000ULL)
0014 #define BB_MAX_LEN  512
0015 #define BB_OFFSET(x)    (((x) & BB_OFFSET_MASK) >> 9)
0016 #define BB_LEN(x)   (((x) & BB_LEN_MASK) + 1)
0017 #define BB_ACK(x)   (!!((x) & BB_ACK_MASK))
0018 #define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63))
0019 
0020 /* Bad block numbers are stored sorted in a single page.
0021  * 64bits is used for each block or extent.
0022  * 54 bits are sector number, 9 bits are extent size,
0023  * 1 bit is an 'acknowledged' flag.
0024  */
0025 #define MAX_BADBLOCKS   (PAGE_SIZE/8)
0026 
0027 struct badblocks {
0028     struct device *dev; /* set by devm_init_badblocks */
0029     int count;      /* count of bad blocks */
0030     int unacked_exist;  /* there probably are unacknowledged
0031                  * bad blocks.  This is only cleared
0032                  * when a read discovers none
0033                  */
0034     int shift;      /* shift from sectors to block size
0035                  * a -ve shift means badblocks are
0036                  * disabled.*/
0037     u64 *page;      /* badblock list */
0038     int changed;
0039     seqlock_t lock;
0040     sector_t sector;
0041     sector_t size;      /* in sectors */
0042 };
0043 
0044 int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
0045            sector_t *first_bad, int *bad_sectors);
0046 int badblocks_set(struct badblocks *bb, sector_t s, int sectors,
0047             int acknowledged);
0048 int badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
0049 void ack_all_badblocks(struct badblocks *bb);
0050 ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
0051 ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
0052             int unack);
0053 int badblocks_init(struct badblocks *bb, int enable);
0054 void badblocks_exit(struct badblocks *bb);
0055 struct device;
0056 int devm_init_badblocks(struct device *dev, struct badblocks *bb);
0057 static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb)
0058 {
0059     if (bb->dev != dev) {
0060         dev_WARN_ONCE(dev, 1, "%s: badblocks instance not associated\n",
0061                 __func__);
0062         return;
0063     }
0064     badblocks_exit(bb);
0065 }
0066 #endif