LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Alex Dubov <oakad@yahoo.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] [MEMSTICK] Initial commit for Sony MemoryStick support
Date: Sun, 13 Jan 2008 19:26:20 -0800 (PST)	[thread overview]
Message-ID: <355699.38284.qm@web36712.mail.mud.yahoo.com> (raw)
In-Reply-To: <20080110010049.695da076.akpm@linux-foundation.org>


--- Andrew Morton <akpm@linux-foundation.org> wrote:

> On Wed,  2 Jan 2008 17:42:24 +1100 oakad@exemail.com.au wrote:
> 
> > From: Alex Dubov <oakad@yahoo.com>
> > 
> > Sony MemoryStick cards are used in many products manufactured by Sony. They
> > are available both as storage and as IO expansion cards. Currently, only
> > MemoryStick Pro storage cards are supported via TI FlashMedia MemoryStick
> > interface.
> > 
> 
> Will you be running a git tree for this?  If so, please send me the link.
> 
> Will this enable that thus-far useless slot on my Vaio?
> 
> Where did the info come from which enabled this driver to be written?  I
> thought Sony were super-secretive about this stuff?
> 

I'm going to set-up git tree, yes.

It should support some vaios (newer ones for sure), as far as I know.

The primary reference for the driver is this one:
http://zeniv.linux.org.uk/~winbond/ (link is somewhat slow, but works). Winbond developed GPLv2
driver for linux and there was enough info in their source code for my implementation (totally
different from their's). Some reverse engineering of the windows driver was needed too (for the TI
registers and such).



> 
> > @@ -0,0 +1,26 @@
> > +#
> > +# MemoryStick subsystem configuration
> > +#
> > +
> > +menuconfig MEMSTICK
> > +	tristate "Sony MemoryStick card support (EXPERIMENTAL)"
> > +	help
> > +	  Sony MemoryStick is a proprietary storage/extension card protocol.
> > +
> > +	  If you want MemoryStick support, you should say Y here and also
> > +	  to the specific driver for your MMC interface.
> 
> Are you sure this has enough dependencies?  CONFIG_TIFM_* for a start?

This is supposed to be a generic layer, akin to mmc. I have a jmicron backend in the works, and
windbond backend will be possible, too.


> 
> <fiddles with Kconfig>
> 
> We can create a config which has CONFIG_TIFM_CORE=m, CONFIG_MEMSTICK=y. 
> That might not work?
> 
> Anyway, please have a think about that.


Considering the previous point this should be ok.

> 
> > ...
> >
> > +
> > +struct mspro_sys_attr {
> > +	size_t                  size;
> > +	unsigned char           *data;
> > +	unsigned char           id;
> > +	char                    name[32];
> > +	struct device_attribute sys_attr;
> > +};
> > +
> > +struct mspro_attr_entry {
> > +	unsigned int  address;
> > +	unsigned int  size;
> > +	unsigned char id;
> > +	unsigned char reserved[3];
> > +} __attribute__((packed));
> > +
> > +struct mspro_attribute {
> > +	unsigned short          signature;
> > +	unsigned short          version;
> > +	unsigned char           count;
> > +	unsigned char           reserved[11];
> > +	struct mspro_attr_entry entries[];
> > +} __attribute__((packed));
> 
> Why are these packed?  Do they map onto something whcih hardware knows
> about?

Yes, of course; all structures with "packed" attribute correspond to appropriate protocol ones
(the endianness is tweaked as needed - most, but not all fields, are big-endian).

> >
> > ...
> >
> > +struct mspro_block_data {
> > +	struct memstick_dev   *card;
> > +	unsigned int          usage_count;
> > +	struct gendisk        *disk;
> > +	struct request_queue  *queue;
> > +	spinlock_t            q_lock;
> > +	wait_queue_head_t     q_wait;
> > +	struct task_struct    *q_thread;
> > +
> > +	unsigned short        page_size;
> > +	unsigned short        cylinders;
> > +	unsigned short        heads;
> > +	unsigned short        sectors_per_track;
> > +
> > +	unsigned char         system;
> > +	unsigned char         read_only:1,
> > +			      active:1,
> > +			      has_request:1,
> > +			      data_dir:1;
> 
> You're aware that these four fields occupy the same machine word and that
> the compiler provides no locking?  So if one thread attempts to modify
> "read_only" while another modifies "has_request", one can corrupt the work
> of the other?
> 
> If this is indeed safe then a comment here whcih clearly explains that
> would be useful.

The access to these fields should be exclusively under q_lock (I'll check the locking again, just
to make sure). After all, the same applies to old fashioned bit masks.

> 
> > +}
> > +
> > +static ssize_t mspro_block_attr_show_modelname(struct device *dev,
> > +					       struct device_attribute *attr,
> > +					       char *buffer)
> > +{
> > +	struct mspro_sys_attr *x_attr = container_of(attr,
> > +						     struct mspro_sys_attr,
> > +						     sys_attr);
> > +
> > +	return snprintf(buffer, PAGE_SIZE, "%s", x_attr->data);
> > +}
> >
> > ...
> >
> > +static int mspro_block_sysfs_register(struct memstick_dev *card)
> > +{
> > +	struct mspro_block_data *msb = memstick_get_drvdata(card);
> > +	int cnt, rc = 0;
> > +
> > +	for (cnt = 0; cnt < msb->attr_count; cnt++) {
> > +		rc = device_create_file(&card->dev,
> > +					&msb->attributes[cnt].sys_attr);
> > +
> > +		if (rc) {
> > +			if (cnt) {
> > +				for (cnt--; cnt >= 0; cnt--)
> 
> ow. my brain hurts.
> 
> The `if (cnt)' is actually unneeded.  But if it were mine I'd be doing
> something simpler and obviouser here.  Like `for (i = 0; i < cnt; i++)'
> simple == good.  !simple == !.
> 
> > +					device_remove_file(&card->dev,
> > +							   &msb->attributes[cnt]
> > +								.sys_attr);
> > +			}
> > +			break;
> > +		}
> > +	}
> > +	return rc;
> > +}
> 
> Could we be using attribute groups for all this?

The idea here is that MSPro media have an attribute namespace, which may contain various entries.
Some of them I know how to decode, others I still want to be presented in sysfs for further study
(as hex dumps). Sysfs attr group should be fine, but I was not aware that such thing exists.

> > > ...
> >
> >
> > +static int mspro_block_queue_thread(void *data)
> > +{
> > +	struct memstick_dev *card = data;
> > +	struct memstick_host *host = card->host;
> > +	struct mspro_block_data *msb = memstick_get_drvdata(card);
> > +	struct request *req;
> > +	unsigned long flags;
> > +
> > +	while (1) {
> > +		wait_event(msb->q_wait, mspro_block_has_request(msb));
> > +		dev_dbg(&card->dev, "thread iter\n");
> > +
> > +		spin_lock_irqsave(&msb->q_lock, flags);
> > +		req = elv_next_request(msb->queue);
> > +		dev_dbg(&card->dev, "next req %p\n", req);
> > +		if (!req) {
> > +			msb->has_request = 0;
> > +			if (kthread_should_stop()) {
> > +				spin_unlock_irqrestore(&msb->q_lock, flags);
> > +				break;
> > +			}
> > +		} else
> > +			msb->has_request = 1;
> > +		spin_unlock_irqrestore(&msb->q_lock, flags);
> > +
> > +		if (req) {
> > +			mutex_lock(&host->lock);
> > +			mspro_block_process_request(card, req);
> > +			mutex_unlock(&host->lock);
> > +		}
> > +	}
> 
> Should this have a try_to_freeze() in it?

The thread is stopped on suspend and restarted on resume.It works on my machine.

> > ...
> >
> > +static int mspro_block_resume(struct memstick_dev *card)
> > +{
> > +	struct mspro_block_data *msb = memstick_get_drvdata(card);
> > +	unsigned long flags;
> > +	int rc = 0;
> > +
> > +#ifdef CONFIG_MEMSTICK_UNSAFE_RESUME
> > +
> > +	struct mspro_block_data *new_msb;
> > +	struct memstick_host *host = card->host;
> > +	unsigned char cnt;
> > +
> > +	mutex_lock(&host->lock);
> > +	new_msb = kzalloc(sizeof(struct mspro_block_data), GFP_KERNEL);
> 
> If anything takes host->lock on the IO path then there might be a deadlock
> here.  GFP_NOIO, perhaps.  or just swap these two lines.


There's no IO path at this point, as IO thread was stopped on suspend. The fine point here is that
thread is restarted only with "UNSAFE_RESUME" set, otherwise the block device just sits dead in
the water waiting for the bus driver to kick it out and run the media detection routine anew.


> > +inline void *memstick_priv(struct memstick_host *host)
> > +{
> > +	return (void *)host->private;
> > +}
> > +
> > +inline void *memstick_get_drvdata(struct memstick_dev *card)
> > +{
> > +	return dev_get_drvdata(&card->dev);
> > +}
> > +
> > +inline void memstick_set_drvdata(struct memstick_dev *card, void *data)
> > +{
> > +	dev_set_drvdata(&card->dev, data);
> > +}
> 
> static inline.
> 

Somebody was already kind enough to fix this.

I hope it'll be ok for me to address the rest of the issues with incremental patches.I expect to
have a web accessible git within a few days.



      ____________________________________________________________________________________
Looking for last minute shopping deals?  
Find them fast with Yahoo! Search.  http://tools.search.yahoo.com/newsearch/category.php?category=shopping

  parent reply	other threads:[~2008-01-14  3:26 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-02  6:42 oakad
2008-01-10  9:00 ` Andrew Morton
2008-01-11 12:14   ` Jens Axboe
2008-01-14  3:26   ` Alex Dubov [this message]
2008-01-22 16:12   ` Alex Dubov
2008-01-22 18:59     ` Andrew Morton
2008-01-25  7:58       ` [PATCH] [MEMSTICK] Updates for the memstick driver Alex Dubov
2008-01-27  6:01         ` Andrew Morton
2008-02-03  0:16         ` Andrew Morton
2008-02-04  4:31           ` [PATCH] memstick: use __blk_end_request to complete requests Alex Dubov
2008-02-04  7:07             ` Andrew Morton
2008-02-09 14:59               ` [PATCH] memstick: fix attribute structure casting in mspro_block_resume Alex Dubov
2008-01-15 17:21 ` [PATCH] [MEMSTICK] Initial commit for Sony MemoryStick support Mariusz Kozlowski
2008-01-16  1:52   ` Alex Dubov
  -- strict thread matches above, loose matches on Subject: below --
2008-01-13 22:47 Miguel Botón
2007-12-24  3:06 oakad
2007-12-31  0:01 ` Carlos Corbacho
2007-12-31  0:31   ` Jan Engelhardt
2007-12-31  0:54     ` Alex Dubov
2007-12-31  0:56     ` Carlos Corbacho
2007-12-31  1:01   ` Alex Dubov
2007-12-31  1:15     ` Carlos Corbacho
2007-12-31  4:51       ` Alex Dubov

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=355699.38284.qm@web36712.mail.mud.yahoo.com \
    --to=oakad@yahoo.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --subject='Re: [PATCH] [MEMSTICK] Initial commit for Sony MemoryStick support' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).