aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-07 13:43:40 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-07 13:43:40 -0500
commitf9c5d0451b406a6bd0d0bf1fdd63c7777af6ebc6 (patch)
tree717e9fc0044e9d94dd363670cacc2dff9d5b4407 /drivers/mmc
parentd354d9afe923eb08f7ee89128b38ddb6415de01d (diff)
parentf3e2628bed0d5a88ced8239b35f1534557f9631c (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc.c10
-rw-r--r--drivers/mmc/mmc_block.c175
-rw-r--r--drivers/mmc/mmci.c17
-rw-r--r--drivers/mmc/mmci.h4
-rw-r--r--drivers/mmc/wbsd.c27
5 files changed, 158 insertions, 75 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index eb41391e06e9..6696f71363b9 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -550,6 +550,11 @@ static void mmc_decode_csd(struct mmc_card *card)
550 csd->capacity = (1 + m) << (e + 2); 550 csd->capacity = (1 + m) << (e + 2);
551 551
552 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); 552 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
553 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
554 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
555 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
556 csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
557 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
553 } else { 558 } else {
554 /* 559 /*
555 * We only understand CSD structure v1.1 and v1.2. 560 * We only understand CSD structure v1.1 and v1.2.
@@ -579,6 +584,11 @@ static void mmc_decode_csd(struct mmc_card *card)
579 csd->capacity = (1 + m) << (e + 2); 584 csd->capacity = (1 + m) << (e + 2);
580 585
581 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); 586 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
587 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
588 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
589 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
590 csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
591 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
582 } 592 }
583} 593}
584 594
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 8e380c14bf65..198561d21710 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -54,6 +54,7 @@ struct mmc_blk_data {
54 54
55 unsigned int usage; 55 unsigned int usage;
56 unsigned int block_bits; 56 unsigned int block_bits;
57 unsigned int read_only;
57}; 58};
58 59
59static DECLARE_MUTEX(open_lock); 60static DECLARE_MUTEX(open_lock);
@@ -85,12 +86,6 @@ static void mmc_blk_put(struct mmc_blk_data *md)
85 up(&open_lock); 86 up(&open_lock);
86} 87}
87 88
88static inline int mmc_blk_readonly(struct mmc_card *card)
89{
90 return mmc_card_readonly(card) ||
91 !(card->csd.cmdclass & CCC_BLOCK_WRITE);
92}
93
94static int mmc_blk_open(struct inode *inode, struct file *filp) 89static int mmc_blk_open(struct inode *inode, struct file *filp)
95{ 90{
96 struct mmc_blk_data *md; 91 struct mmc_blk_data *md;
@@ -102,8 +97,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
102 check_disk_change(inode->i_bdev); 97 check_disk_change(inode->i_bdev);
103 ret = 0; 98 ret = 0;
104 99
105 if ((filp->f_mode & FMODE_WRITE) && 100 if ((filp->f_mode & FMODE_WRITE) && md->read_only)
106 mmc_blk_readonly(md->queue.card))
107 ret = -EROFS; 101 ret = -EROFS;
108 } 102 }
109 103
@@ -299,6 +293,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
299 293
300static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; 294static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
301 295
296static inline int mmc_blk_readonly(struct mmc_card *card)
297{
298 return mmc_card_readonly(card) ||
299 !(card->csd.cmdclass & CCC_BLOCK_WRITE);
300}
301
302static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) 302static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
303{ 303{
304 struct mmc_blk_data *md; 304 struct mmc_blk_data *md;
@@ -310,64 +310,121 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
310 __set_bit(devidx, dev_use); 310 __set_bit(devidx, dev_use);
311 311
312 md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); 312 md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
313 if (md) { 313 if (!md) {
314 memset(md, 0, sizeof(struct mmc_blk_data)); 314 ret = -ENOMEM;
315 goto out;
316 }
315 317
316 md->disk = alloc_disk(1 << MMC_SHIFT); 318 memset(md, 0, sizeof(struct mmc_blk_data));
317 if (md->disk == NULL) {
318 kfree(md);
319 md = ERR_PTR(-ENOMEM);
320 goto out;
321 }
322 319
323 spin_lock_init(&md->lock); 320 /*
324 md->usage = 1; 321 * Set the read-only status based on the supported commands
322 * and the write protect switch.
323 */
324 md->read_only = mmc_blk_readonly(card);
325 325
326 ret = mmc_init_queue(&md->queue, card, &md->lock); 326 /*
327 if (ret) { 327 * Figure out a workable block size. MMC cards have:
328 put_disk(md->disk); 328 * - two block sizes, one for read and one for write.
329 kfree(md); 329 * - may support partial reads and/or writes
330 md = ERR_PTR(ret); 330 * (allows block sizes smaller than specified)
331 goto out; 331 */
332 md->block_bits = card->csd.read_blkbits;
333 if (card->csd.write_blkbits != card->csd.read_blkbits) {
334 if (card->csd.write_blkbits < card->csd.read_blkbits &&
335 card->csd.read_partial) {
336 /*
337 * write block size is smaller than read block
338 * size, but we support partial reads, so choose
339 * the smaller write block size.
340 */
341 md->block_bits = card->csd.write_blkbits;
342 } else if (card->csd.write_blkbits > card->csd.read_blkbits &&
343 card->csd.write_partial) {
344 /*
345 * read block size is smaller than write block
346 * size, but we support partial writes. Use read
347 * block size.
348 */
349 } else {
350 /*
351 * We don't support this configuration for writes.
352 */
353 printk(KERN_ERR "%s: unable to select block size for "
354 "writing (rb%u wb%u rp%u wp%u)\n",
355 md->disk->disk_name,
356 1 << card->csd.read_blkbits,
357 1 << card->csd.write_blkbits,
358 card->csd.read_partial,
359 card->csd.write_partial);
360 md->read_only = 1;
332 } 361 }
333 md->queue.prep_fn = mmc_blk_prep_rq; 362 }
334 md->queue.issue_fn = mmc_blk_issue_rq;
335 md->queue.data = md;
336 363
337 md->disk->major = major; 364 /*
338 md->disk->first_minor = devidx << MMC_SHIFT; 365 * Refuse to allow block sizes smaller than 512 bytes.
339 md->disk->fops = &mmc_bdops; 366 */
340 md->disk->private_data = md; 367 if (md->block_bits < 9) {
341 md->disk->queue = md->queue.queue; 368 printk(KERN_ERR "%s: unable to support block size %u\n",
342 md->disk->driverfs_dev = &card->dev; 369 mmc_card_id(card), 1 << md->block_bits);
370 ret = -EINVAL;
371 goto err_kfree;
372 }
343 373
344 /* 374 md->disk = alloc_disk(1 << MMC_SHIFT);
345 * As discussed on lkml, GENHD_FL_REMOVABLE should: 375 if (md->disk == NULL) {
346 * 376 ret = -ENOMEM;
347 * - be set for removable media with permanent block devices 377 goto err_kfree;
348 * - be unset for removable block devices with permanent media 378 }
349 *
350 * Since MMC block devices clearly fall under the second
351 * case, we do not set GENHD_FL_REMOVABLE. Userspace
352 * should use the block device creation/destruction hotplug
353 * messages to tell when the card is present.
354 */
355 379
356 sprintf(md->disk->disk_name, "mmcblk%d", devidx); 380 spin_lock_init(&md->lock);
357 sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); 381 md->usage = 1;
358 382
359 md->block_bits = card->csd.read_blkbits; 383 ret = mmc_init_queue(&md->queue, card, &md->lock);
384 if (ret)
385 goto err_putdisk;
360 386
361 blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); 387 md->queue.prep_fn = mmc_blk_prep_rq;
388 md->queue.issue_fn = mmc_blk_issue_rq;
389 md->queue.data = md;
362 390
363 /* 391 md->disk->major = major;
364 * The CSD capacity field is in units of read_blkbits. 392 md->disk->first_minor = devidx << MMC_SHIFT;
365 * set_capacity takes units of 512 bytes. 393 md->disk->fops = &mmc_bdops;
366 */ 394 md->disk->private_data = md;
367 set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); 395 md->disk->queue = md->queue.queue;
368 } 396 md->disk->driverfs_dev = &card->dev;
369 out: 397
398 /*
399 * As discussed on lkml, GENHD_FL_REMOVABLE should:
400 *
401 * - be set for removable media with permanent block devices
402 * - be unset for removable block devices with permanent media
403 *
404 * Since MMC block devices clearly fall under the second
405 * case, we do not set GENHD_FL_REMOVABLE. Userspace
406 * should use the block device creation/destruction hotplug
407 * messages to tell when the card is present.
408 */
409
410 sprintf(md->disk->disk_name, "mmcblk%d", devidx);
411 sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
412
413 blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
414
415 /*
416 * The CSD capacity field is in units of read_blkbits.
417 * set_capacity takes units of 512 bytes.
418 */
419 set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9));
370 return md; 420 return md;
421
422 err_putdisk:
423 put_disk(md->disk);
424 err_kfree:
425 kfree(md);
426 out:
427 return ERR_PTR(ret);
371} 428}
372 429
373static int 430static int
@@ -403,12 +460,6 @@ static int mmc_blk_probe(struct mmc_card *card)
403 if (!(card->csd.cmdclass & CCC_BLOCK_READ)) 460 if (!(card->csd.cmdclass & CCC_BLOCK_READ))
404 return -ENODEV; 461 return -ENODEV;
405 462
406 if (card->csd.read_blkbits < 9) {
407 printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
408 mmc_card_id(card), 1 << card->csd.read_blkbits);
409 return -ENODEV;
410 }
411
412 md = mmc_blk_alloc(card); 463 md = mmc_blk_alloc(card);
413 if (IS_ERR(md)) 464 if (IS_ERR(md))
414 return PTR_ERR(md); 465 return PTR_ERR(md);
@@ -419,7 +470,7 @@ static int mmc_blk_probe(struct mmc_card *card)
419 470
420 printk(KERN_INFO "%s: %s %s %luKiB %s\n", 471 printk(KERN_INFO "%s: %s %s %luKiB %s\n",
421 md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), 472 md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
422 get_capacity(md->disk) >> 1, mmc_blk_readonly(card)?"(ro)":""); 473 get_capacity(md->disk) >> 1, md->read_only ? "(ro)" : "");
423 474
424 mmc_set_drvdata(card, md); 475 mmc_set_drvdata(card, md);
425 add_disk(md->disk); 476 add_disk(md->disk);
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 166c9b0ad04e..2b10a2d4ae09 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -20,6 +20,7 @@
20#include <linux/mmc/host.h> 20#include <linux/mmc/host.h>
21#include <linux/mmc/protocol.h> 21#include <linux/mmc/protocol.h>
22 22
23#include <asm/cacheflush.h>
23#include <asm/div64.h> 24#include <asm/div64.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/scatterlist.h> 26#include <asm/scatterlist.h>
@@ -157,6 +158,13 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
157 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) 158 else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
158 data->error = MMC_ERR_FIFO; 159 data->error = MMC_ERR_FIFO;
159 status |= MCI_DATAEND; 160 status |= MCI_DATAEND;
161
162 /*
163 * We hit an error condition. Ensure that any data
164 * partially written to a page is properly coherent.
165 */
166 if (host->sg_len && data->flags & MMC_DATA_READ)
167 flush_dcache_page(host->sg_ptr->page);
160 } 168 }
161 if (status & MCI_DATAEND) { 169 if (status & MCI_DATAEND) {
162 mmci_stop_data(host); 170 mmci_stop_data(host);
@@ -292,7 +300,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
292 /* 300 /*
293 * Unmap the buffer. 301 * Unmap the buffer.
294 */ 302 */
295 mmci_kunmap_atomic(host, &flags); 303 mmci_kunmap_atomic(host, buffer, &flags);
296 304
297 host->sg_off += len; 305 host->sg_off += len;
298 host->size -= len; 306 host->size -= len;
@@ -301,6 +309,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
301 if (remain) 309 if (remain)
302 break; 310 break;
303 311
312 /*
313 * If we were reading, and we have completed this
314 * page, ensure that the data cache is coherent.
315 */
316 if (status & MCI_RXACTIVE)
317 flush_dcache_page(host->sg_ptr->page);
318
304 if (!mmci_next_sg(host)) 319 if (!mmci_next_sg(host))
305 break; 320 break;
306 321
diff --git a/drivers/mmc/mmci.h b/drivers/mmc/mmci.h
index 4589bbd68192..6d7eadc9a678 100644
--- a/drivers/mmc/mmci.h
+++ b/drivers/mmc/mmci.h
@@ -172,8 +172,8 @@ static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flag
172 return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; 172 return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
173} 173}
174 174
175static inline void mmci_kunmap_atomic(struct mmci_host *host, unsigned long *flags) 175static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
176{ 176{
177 kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); 177 kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
178 local_irq_restore(*flags); 178 local_irq_restore(*flags);
179} 179}
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index c7eb7c269081..4f13bd2ccf9a 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1456,13 +1456,11 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1456 * Iterate through all ports, all codes to 1456 * Iterate through all ports, all codes to
1457 * find hardware that is in our known list. 1457 * find hardware that is in our known list.
1458 */ 1458 */
1459 for (i = 0;i < sizeof(config_ports)/sizeof(int);i++) 1459 for (i = 0; i < ARRAY_SIZE(config_ports); i++) {
1460 {
1461 if (!request_region(config_ports[i], 2, DRIVER_NAME)) 1460 if (!request_region(config_ports[i], 2, DRIVER_NAME))
1462 continue; 1461 continue;
1463 1462
1464 for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) 1463 for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) {
1465 {
1466 id = 0xFFFF; 1464 id = 0xFFFF;
1467 1465
1468 host->config = config_ports[i]; 1466 host->config = config_ports[i];
@@ -1478,8 +1476,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
1478 1476
1479 wbsd_lock_config(host); 1477 wbsd_lock_config(host);
1480 1478
1481 for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) 1479 for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
1482 {
1483 if (id == valid_ids[k]) 1480 if (id == valid_ids[k])
1484 { 1481 {
1485 host->chip_id = id; 1482 host->chip_id = id;
@@ -2090,10 +2087,20 @@ static int __init wbsd_drv_init(void)
2090 if (result < 0) 2087 if (result < 0)
2091 return result; 2088 return result;
2092 2089
2093 wbsd_device = platform_device_register_simple(DRIVER_NAME, -1, 2090 wbsd_device = platform_device_alloc(DRIVER_NAME, -1);
2094 NULL, 0); 2091 if (!wbsd_device)
2095 if (IS_ERR(wbsd_device)) 2092 {
2096 return PTR_ERR(wbsd_device); 2093 platform_driver_unregister(&wbsd_driver);
2094 return -ENOMEM;
2095 }
2096
2097 result = platform_device_add(wbsd_device);
2098 if (result)
2099 {
2100 platform_device_put(wbsd_device);
2101 platform_driver_unregister(&wbsd_driver);
2102 return result;
2103 }
2097 } 2104 }
2098 2105
2099 return 0; 2106 return 0;