All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Andrea Adami <andrea.adami@gmail.com>
Cc: linux-mtd@lists.infradead.org,
	"David Woodhouse" <dwmw2@infradead.org>,
	"Brian Norris" <computersforpeace@gmail.com>,
	"Marek Vasut" <marek.vasut@gmail.com>,
	"Richard Weinberger" <richard@nod.at>,
	"Cyrille Pitchen" <cyrille.pitchen@wedev4u.fr>,
	"Rafał Miłecki" <rafal@milecki.pl>,
	"Haojian Zhuang" <haojian.zhuang@gmail.com>,
	"Dmitry Eremin-Solenikov" <dbaryshkov@gmail.com>,
	"Robert Jarzmik" <robert.jarzmik@free.fr>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6] mtd: sharpslpart: Add sharpslpart partition parser
Date: Thu, 24 Aug 2017 12:04:28 +0200	[thread overview]
Message-ID: <20170824120428.46e266c7@bbrezillon> (raw)
In-Reply-To: <CAAQYJAsTCy2nWYjMTmSGqSCn-ttWJ5H8LANmyaaVJ+mPs7x1bg@mail.gmail.com>

On Thu, 24 Aug 2017 11:19:56 +0200
Andrea Adami <andrea.adami@gmail.com> wrote:

> >> +/**
> >> + * struct sharpsl_ftl - Sharp FTL Logical Table
> >> + * @logmax:          number of logical blocks
> >> + * @log2phy:         the logical-to-physical table
> >> + *
> >> + * Stripped down from 2.4 sources for read-only purposes.  
> >
> > Not sure this information is really useful, especially since you don't
> > provide a link to the 2.4 sources (or maybe I missed it).  
> 
> Maybe here I can add that this FTL was originally tailored for devices
> 16KiB erasesize matching the size of the PARAM_BLOCK_ above thus using
> two separate blocks for the partition tables. Should I add an
> ASCII-art?

You can add an ASCII-art if you want but that's not mandatory if you
can explain it with words :-).

> Pls see
> http://www.h5.dion.ne.jp/~rimemoon/zaurus/memo_006.htm
> BTW the link was in the cover-letter 0/9, I'll put it here together
> with the changelog.

Please put it in the code (in a comment). The changelog will disappear
as soon as I apply the patch.

> 
> >
> > You'd better describe what this struct is used for here.  
> Seems self-explanatory..2 fields commented. What would you add here?

Just that the struct contains the logical-to-physical translation
table used by the SHARPSL FTL. It's just that your initial comment
didn't bring any useful information. 

> 
> >  
> >> + */
> >> +struct sharpsl_ftl {
> >> +     u_int logmax;
> >> +     u_int *log2phy;  
> >

[...]

> >> +/*
> >> + * The logical block number assigned to a physical block is stored in the OOB
> >> + * of the first page, in 3 16-bit copies with the following layout:
> >> + *
> >> + * 01234567 89abcdef
> >> + * -------- --------
> >> + * ECC BB   xyxyxy
> >> + *
> >> + * When reading we check that the first two copies agree.
> >> + * In case of error, matching is tried using the following pairs.
> >> + * Reserved values 0xffff mean the block is kept for wear leveling.
> >> + *
> >> + * 01234567 89abcdef
> >> + * -------- --------
> >> + * ECC BB   xyxy    oob[8]==oob[10] && oob[9]==oob[11]   -> byte0=8   byte1=9
> >> + * ECC BB     xyxy  oob[10]==oob[12] && oob[11]==oob[13] -> byte0=10  byte1=11
> >> + * ECC BB   xy  xy  oob[12]==oob[8] && oob[13]==oob[9]   -> byte0=12  byte1=13
> >> + *
> >> + */
> >> +static u_int sharpsl_nand_get_logical_num(u_char *oob)
> >> +{
> >> +     u16 us;
> >> +     int good0, good1;
> >> +
> >> +     if (oob[NAND_NOOB_LOGADDR_00] == oob[NAND_NOOB_LOGADDR_10] &&
> >> +         oob[NAND_NOOB_LOGADDR_01] == oob[NAND_NOOB_LOGADDR_11]) {
> >> +             good0 = NAND_NOOB_LOGADDR_00;
> >> +             good1 = NAND_NOOB_LOGADDR_01;
> >> +     } else if (oob[NAND_NOOB_LOGADDR_10] == oob[NAND_NOOB_LOGADDR_20] &&
> >> +                oob[NAND_NOOB_LOGADDR_11] == oob[NAND_NOOB_LOGADDR_21]) {
> >> +             good0 = NAND_NOOB_LOGADDR_10;
> >> +             good1 = NAND_NOOB_LOGADDR_11;
> >> +     } else if (oob[NAND_NOOB_LOGADDR_20] == oob[NAND_NOOB_LOGADDR_00] &&
> >> +                oob[NAND_NOOB_LOGADDR_21] == oob[NAND_NOOB_LOGADDR_01]) {
> >> +             good0 = NAND_NOOB_LOGADDR_20;
> >> +             good1 = NAND_NOOB_LOGADDR_21;
> >> +     } else {
> >> +             /* wrong oob fingerprint, maybe here by mistake? */
> >> +             return UINT_MAX;
> >> +     }
> >> +
> >> +     us = oob[good0] | oob[good1] << 8;
> >> +
> >> +     /* parity check */
> >> +     if (hweight16(us) & BLOCK_UNMASK_COMPLEMENT)
> >> +             return (UINT_MAX - 1);  
> >
> > Why not making this function return an int and use regular error codes
> > for the parity and wrong fingerprint errors?
> >  
> Originally in case of error it did return the largest values.
> I can return a negative int but then I'd have to check for log_no >0
> 
> Besides, what are the 'regular' error codes you'd use here?
> For the missing FTL we do return -EINVAL later so I'd say this is the
> error for the wrong oob fingerprint.

EINVAL should be fine for all corruption/mismatch.

> 
> About the parity error, it does return UINT_MAX -1 so to allow very
> large log_num. This value is always bigger than log_max so it is
> skipped in the actual code but the read continues.

Well, a parity error is still an error, right?

> Should we change the philosophy of the old 2.4 code and exit in case
> of parity errors?

Hm, you should not exit if the phys -> log information is corrupted, it
just means you can't consider this physical block is containing a valid
logical block, that's all. Pretty much like when there's an oob
fingerprint mismatch.

> 
> >> +
> >> +     /* reserved */
> >> +     if (us == BLOCK_IS_RESERVED)
> >> +             return BLOCK_IS_RESERVED;
> >> +     else  
> >
> > You can drop the 'else' here.  
> Done
> >  
> >> +             return (us & BLOCK_UNMASK) >> 1;  
> >
> > So, this is a 10bit value, right? Why not doing the >> 1 first so that
> > your BLOCK_UNMASK mask really looks like a valid mask (0x3ff, which can
> > also be defined as GENMASK(9, 0)).  
> Right, very nice. Done.
> Can I keep BLOCK_UNMASK COMPLEMENT = 1 ?

Yes.

> 
> >  
> >> +}
> >> +
> >> +static int sharpsl_nand_init_logical(struct mtd_info *mtd, u32 partition_size,  
> >
> > s/sharpsl_nand_init_logical/sharpsl_nand_init_ftl/  
> Oh yes, renamed
> 
> >
> > partition_size is always set to SHARPSL_FTL_PART_SIZE. Please drop this
> > argument.
> >  
> Ok, done
> 
> >> +                                  struct sharpsl_ftl *ftl)
> >> +{
> >> +     u_int block_num, log_num, phymax;
> >> +     loff_t block_adr;
> >> +     u_char *oob;
> >> +     int i, ret;
> >> +
> >> +     oob = kzalloc(mtd->oobsize, GFP_KERNEL);
> >> +     if (!oob)
> >> +             return -ENOMEM;
> >> +
> >> +     /* initialize management structure */
> >> +     phymax = (partition_size / mtd->erasesize);  
> >
> > You can use mtd_div_by_eb() here.
> >  
> Done for all occurrences
> 
> >> +
> >> +     /* FTL reserves 5% of the blocks + 1 spare  */
> >> +     ftl->logmax = ((phymax * 95) / 100) - 1;
> >> +
> >> +     ftl->log2phy = kmalloc_array(ftl->logmax, sizeof(u_int),  
> >
> >                                                   sizeof(*ftl->log2phy)  
> Ok, changed.
> 
> >  
> >> +                                  GFP_KERNEL);
> >> +     if (!ftl->log2phy) {
> >> +             ret = -ENOMEM;
> >> +             goto exit;
> >> +     }
> >> +
> >> +     /* initialize ftl->log2phy */
> >> +     for (i = 0; i < ftl->logmax; i++)
> >> +             ftl->log2phy[i] = UINT_MAX;
> >> +
> >> +     /* create physical-logical table */
> >> +     for (block_num = 0; block_num < phymax; block_num++) {
> >> +             block_adr = block_num * mtd->erasesize;
> >> +
> >> +             if (mtd_block_isbad(mtd, block_adr))
> >> +                     continue;
> >> +
> >> +             if (sharpsl_nand_read_oob(mtd, block_adr, mtd->oobsize, oob))
> >> +                     continue;
> >> +
> >> +             /* get logical block */
> >> +             log_num = sharpsl_nand_get_logical_num(oob);
> >> +
> >> +             /* FTL is not used? Exit here if the oob fingerprint is wrong */
> >> +             if (log_num == UINT_MAX) {
> >> +                     pr_info("sharpslpart: Sharp SL FTL not found.\n");
> >> +                     ret = -EINVAL;
> >> +                     goto exit;
> >> +             }

Okay, I overlooked that part. Why do you exit if there's a fingerprint
mismatch? Can't you just ignore this physical block and continue
scanning the remaining ones?

  reply	other threads:[~2017-08-24 10:04 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-22  9:42 [PATCH v6] mtd: sharpslpart: Add sharpslpart partition parser Andrea Adami
2017-08-22 12:54 ` Boris Brezillon
2017-08-24  9:19   ` Andrea Adami
2017-08-24 10:04     ` Boris Brezillon [this message]
2017-08-24 10:30       ` Andrea Adami
2017-08-24 11:27         ` Boris Brezillon
2017-08-25  4:53           ` Brian Norris
2017-08-25 17:50             ` Andrea Adami
2017-08-25 21:48               ` Boris Brezillon
2017-08-25 22:09                 ` Andrea Adami
2017-08-26  6:58                   ` Boris Brezillon
2017-08-24 22:11 ` Boris Brezillon
2017-08-26  5:59   ` Boris Brezillon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170824120428.46e266c7@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=andrea.adami@gmail.com \
    --cc=computersforpeace@gmail.com \
    --cc=cyrille.pitchen@wedev4u.fr \
    --cc=dbaryshkov@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=haojian.zhuang@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=marek.vasut@gmail.com \
    --cc=rafal@milecki.pl \
    --cc=richard@nod.at \
    --cc=robert.jarzmik@free.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.