mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: Maxim Levitsky <maximlevitsky@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Alex Dubov <oakad@yahoo.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] memstick: add support for legacy memorysticks
Date: Tue, 25 Sep 2012 11:25:00 -0700	[thread overview]
Message-ID: <20120925182500.GD16296@google.com> (raw)
In-Reply-To: <1348562326-10462-3-git-send-email-maximlevitsky@gmail.com>

Hello,

On Tue, Sep 25, 2012 at 10:38:46AM +0200, Maxim Levitsky wrote:
> diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
> new file mode 100644
> index 0000000..318e40b
> --- /dev/null
> +++ b/drivers/memstick/core/ms_block.c
> @@ -0,0 +1,2422 @@
> +/*
> + *  ms_block.c - Sony MemoryStick (legacy) storage support
> +

Missing '*'?

> + *  Copyright (C) 2012 Maxim Levitsky <maximlevitsky@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Minor portions of the driver were copied from mspro_block.c which is
> + * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com>
> + *
> + */
...
> +static size_t sg_copy(struct scatterlist *sg_from, struct scatterlist *sg_to,
> +					int to_nents, size_t offset, size_t len)

Probably not the best idea to use a name this generic in driver code.
linux/scatterlist.h likely might wanna use the name.

> +{
> +	size_t copied = 0;
> +
> +	while (offset > 0) {
> +
> +		if (offset >= sg_from->length) {
> +			if (sg_is_last(sg_from))
> +				return 0;
> +
> +			offset -= sg_from->length;
> +			sg_from = sg_next(sg_from);
> +			continue;
> +		}
> +
> +		copied = min(len, sg_from->length - offset);
> +		sg_set_page(sg_to, sg_page(sg_from),
> +			copied, sg_from->offset + offset);
> +
> +		len -= copied;
> +		offset = 0;
> +
> +		if (sg_is_last(sg_from) || !len)
> +			goto out;
> +
> +		sg_to = sg_next(sg_to);
> +		to_nents--;
> +		sg_from = sg_next(sg_from);
> +	}
> +
> +	while (len > sg_from->length && to_nents--) {
> +
> +		len -= sg_from->length;
> +		copied += sg_from->length;
> +
> +		sg_set_page(sg_to, sg_page(sg_from),
> +				sg_from->length, sg_from->offset);
> +
> +		if (sg_is_last(sg_from) || !len)
> +			goto out;
> +
> +		sg_from = sg_next(sg_from);
> +		sg_to = sg_next(sg_to);
> +	}
> +
> +	if (len && to_nents) {
> +		sg_set_page(sg_to, sg_page(sg_from), len, sg_from->offset);
> +		copied += len;
> +	}
> +
> +out:
> +	sg_mark_end(sg_to);
> +	return copied;
> +}

Also, from what it does, it seems sg_copy() is a bit of misnomer.
Rename it to sg_remap_with_offset() or something and move it to
lib/scatterlist.c?

> +/*
> + * Compares section of 'sg' starting from offset 'offset' and with length 'len'
> + * to linear buffer of length 'len' at address 'buffer'
> + * Returns 0 if equal and  -1 otherwice
> + */
> +static int sg_compare_to_buffer(struct scatterlist *sg,
> +					size_t offset, u8 *buffer, size_t len)
> +{
> +	int retval = 0;
> +	struct sg_mapping_iter miter;
> +
> +	sg_miter_start(&miter, sg, sg_nents(sg),
> +					SG_MITER_ATOMIC | SG_MITER_FROM_SG);
> +
> +	while (sg_miter_next(&miter) && len > 0) {
> +
> +		int cmplen;
> +
> +		if (offset >= miter.length) {
> +			offset -= miter.length;
> +			continue;
> +		}
> +
> +		cmplen = min(miter.length - offset, len);
> +		retval = memcmp(miter.addr + offset, buffer, cmplen) ? -1 : 0;
> +		if (retval)
> +			break;
> +
> +		buffer += cmplen;
> +		len -= cmplen;
> +		offset = 0;
> +	}
> +
> +	if (!retval && len)
> +		retval = -1;
> +
> +	sg_miter_stop(&miter);
> +	return retval;
> +}

Maybe we can make sg_copy_buffer() more generic so that it takes a
callback and implement this on top of it?  Having sglist manipulation
scattered isn't too attractive.

...
> +/*
> + * This function is a handler for reads of one page from device.
> + * Writes output to msb->current_sg, takes sector address from msb->reg.param
> + * Can also be used to read extra data only. Set params accordintly.
> + */
> +static int h_msb_read_page(struct memstick_dev *card,
> +					struct memstick_request **out_mrq)
> +{
> +	struct msb_data *msb = memstick_get_drvdata(card);
> +	struct memstick_request *mrq = *out_mrq = &card->current_mrq;
> +	struct scatterlist sg[2];
> +	u8 command, intreg;
> +
> +	if (mrq->error) {
> +		dbg("read_page, unknown error");
> +		return msb_exit_state_machine(msb, mrq->error);
> +	}
> +again:
> +	switch (msb->state) {
> +	case MSB_RP_SEND_BLOCK_ADDRESS:
...
> +	case MSB_RP_SEND_READ_COMMAND:
...
> +	case MSB_RP_SEND_INT_REQ:
...
> +	case MSB_RP_RECEIVE_INT_REQ_RESULT:
...

Is it really necessary to implement explicit state machine?  Can't you
just throw a work item at it and process it synchronously?  Explicit
state machines can save some resources at the cost of a lot more
complexity and generally making things a lot more fragile.  Is it
really worth it here?

> +/* Registers the block device */
> +static int msb_init_disk(struct memstick_dev *card)
> +{
> +	struct msb_data *msb = memstick_get_drvdata(card);
> +	struct memstick_host *host = card->host;
> +	int rc, disk_id;
> +	u64 limit = BLK_BOUNCE_HIGH;
> +	unsigned long capacity;
> +
> +	if (host->dev.dma_mask && *(host->dev.dma_mask))
> +		limit = *(host->dev.dma_mask);
> +
> +	mutex_lock(&msb_disk_lock);
> +
> +	if (!idr_pre_get(&msb_disk_idr, GFP_KERNEL)) {
> +		mutex_unlock(&msb_disk_lock);
> +		return -ENOMEM;
> +	}
> +
> +	rc = idr_get_new(&msb_disk_idr, card, &disk_id);
> +	mutex_unlock(&msb_disk_lock);
> +
> +	if (rc)
> +		return rc;
> +
> +	if ((disk_id << MS_BLOCK_PART_SHIFT) > 255) {
> +		rc = -ENOSPC;
> +		goto out_release_id;
> +	}
> +
> +	msb->disk = alloc_disk(1 << MS_BLOCK_PART_SHIFT);
> +	if (!msb->disk) {
> +		rc = -ENOMEM;
> +		goto out_release_id;
> +	}

Unless you need fixed major:minor mapping (and you don't), you can
simply leave disk->major, first_minor and minors zero and set
GENHD_FL_EXT_DEVT.  Block layer will automatically allocate device
numbers dynamically as necessary.  No need to worry about MAJ:MIN.

Thanks.

-- 
tejun

  reply	other threads:[~2012-09-25 18:25 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-25  8:38 [PATCH v2 memstick: support for legacy sony memsticks Maxim Levitsky
2012-09-25  8:38 ` [PATCH 1/2] scatterlist: add sg_nents Maxim Levitsky
2012-09-25  8:38 ` [PATCH 2/2] memstick: add support for legacy memorysticks Maxim Levitsky
2012-09-25 18:25   ` Tejun Heo [this message]
2012-09-25 19:26     ` Maxim Levitsky
2012-09-25 19:38       ` Tejun Heo
2012-09-25 20:24         ` Maxim Levitsky
2012-09-25 18:02 ` [PATCH v2 memstick: support for legacy sony memsticks Tejun Heo
2012-09-25 19:34   ` Maxim Levitsky
2012-09-25 19:40     ` Tejun Heo
2012-09-25 20:13       ` Maxim Levitsky
2012-09-26  9:48 [PATCH v3 " Maxim Levitsky
2012-09-26  9:49 ` [PATCH 2/2] memstick: add support for legacy memorysticks Maxim Levitsky
2012-09-26 16:41   ` Tejun Heo
2012-09-29 17:20   ` Geert Uytterhoeven
2012-10-01 20:24     ` Maxim Levitsky

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=20120925182500.GD16296@google.com \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maximlevitsky@gmail.com \
    --cc=oakad@yahoo.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome