aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2008-07-25 22:45:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 15:00:04 -0400
commit17017d8d2c005734d7088d8281ce2daab8fcb097 (patch)
treedf689658df7d342143ad399bddf0df7257e8ec20
parentb77899985bdfd85a8e5a6e485033a9b4713d2471 (diff)
memstick: add "start" and "stop" methods to memstick device
In some cases it may be desirable to ensure that associated driver is not going to access the media in some period of time. "start" and "stop" methods are provided therefore to allow it. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/memstick/core/memstick.c11
-rw-r--r--drivers/memstick/core/mspro_block.c33
-rw-r--r--include/linux/memstick.h4
3 files changed, 45 insertions, 3 deletions
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index 3c7d9a79c1ea..7162f772bbfb 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -433,8 +433,11 @@ static void memstick_check(struct work_struct *work)
433 433
434 dev_dbg(&host->dev, "memstick_check started\n"); 434 dev_dbg(&host->dev, "memstick_check started\n");
435 mutex_lock(&host->lock); 435 mutex_lock(&host->lock);
436 if (!host->card) 436 if (!host->card) {
437 memstick_power_on(host); 437 if (memstick_power_on(host))
438 goto out_power_off;
439 } else
440 host->card->stop(host->card);
438 441
439 card = memstick_alloc_card(host); 442 card = memstick_alloc_card(host);
440 443
@@ -452,7 +455,8 @@ static void memstick_check(struct work_struct *work)
452 || !(host->card->check(host->card))) { 455 || !(host->card->check(host->card))) {
453 device_unregister(&host->card->dev); 456 device_unregister(&host->card->dev);
454 host->card = NULL; 457 host->card = NULL;
455 } 458 } else
459 host->card->start(host->card);
456 } 460 }
457 461
458 if (!host->card) { 462 if (!host->card) {
@@ -465,6 +469,7 @@ static void memstick_check(struct work_struct *work)
465 kfree(card); 469 kfree(card);
466 } 470 }
467 471
472out_power_off:
468 if (!host->card) 473 if (!host->card)
469 host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); 474 host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF);
470 475
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 477d0fb6e588..004ac4d176d9 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -752,6 +752,37 @@ static int mspro_block_has_request(struct mspro_block_data *msb)
752 return rc; 752 return rc;
753} 753}
754 754
755static void mspro_block_stop(struct memstick_dev *card)
756{
757 struct mspro_block_data *msb = memstick_get_drvdata(card);
758 int rc = 0;
759 unsigned long flags;
760
761 while (1) {
762 spin_lock_irqsave(&msb->q_lock, flags);
763 if (!msb->has_request) {
764 blk_stop_queue(msb->queue);
765 rc = 1;
766 }
767 spin_unlock_irqrestore(&msb->q_lock, flags);
768
769 if (rc)
770 break;
771
772 wait_for_completion(&card->mrq_complete);
773 }
774}
775
776static void mspro_block_start(struct memstick_dev *card)
777{
778 struct mspro_block_data *msb = memstick_get_drvdata(card);
779 unsigned long flags;
780
781 spin_lock_irqsave(&msb->q_lock, flags);
782 blk_start_queue(msb->queue);
783 spin_unlock_irqrestore(&msb->q_lock, flags);
784}
785
755static int mspro_block_queue_thread(void *data) 786static int mspro_block_queue_thread(void *data)
756{ 787{
757 struct memstick_dev *card = data; 788 struct memstick_dev *card = data;
@@ -1272,6 +1303,8 @@ static int mspro_block_probe(struct memstick_dev *card)
1272 rc = mspro_block_init_disk(card); 1303 rc = mspro_block_init_disk(card);
1273 if (!rc) { 1304 if (!rc) {
1274 card->check = mspro_block_check_card; 1305 card->check = mspro_block_check_card;
1306 card->stop = mspro_block_stop;
1307 card->start = mspro_block_start;
1275 return 0; 1308 return 0;
1276 } 1309 }
1277 1310
diff --git a/include/linux/memstick.h b/include/linux/memstick.h
index 2fe599c66d52..a9f998a3f48b 100644
--- a/include/linux/memstick.h
+++ b/include/linux/memstick.h
@@ -263,6 +263,10 @@ struct memstick_dev {
263 /* Get next request from the media driver. */ 263 /* Get next request from the media driver. */
264 int (*next_request)(struct memstick_dev *card, 264 int (*next_request)(struct memstick_dev *card,
265 struct memstick_request **mrq); 265 struct memstick_request **mrq);
266 /* Tell the media driver to stop doing things */
267 void (*stop)(struct memstick_dev *card);
268 /* Allow the media driver to continue */
269 void (*start)(struct memstick_dev *card);
266 270
267 struct device dev; 271 struct device dev;
268}; 272};