Loading drivers/mmc/mmc.c +10 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,11 @@ static void mmc_decode_csd(struct mmc_card *card) csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } else { /* * We only understand CSD structure v1.1 and v1.2. Loading Loading @@ -579,6 +584,11 @@ static void mmc_decode_csd(struct mmc_card *card) csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } } Loading drivers/mmc/mmc_block.c +113 −62 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ struct mmc_blk_data { unsigned int usage; unsigned int block_bits; unsigned int read_only; }; static DECLARE_MUTEX(open_lock); Loading Loading @@ -85,12 +86,6 @@ static void mmc_blk_put(struct mmc_blk_data *md) up(&open_lock); } static inline int mmc_blk_readonly(struct mmc_card *card) { return mmc_card_readonly(card) || !(card->csd.cmdclass & CCC_BLOCK_WRITE); } static int mmc_blk_open(struct inode *inode, struct file *filp) { struct mmc_blk_data *md; Loading @@ -102,8 +97,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp) check_disk_change(inode->i_bdev); ret = 0; if ((filp->f_mode & FMODE_WRITE) && mmc_blk_readonly(md->queue.card)) if ((filp->f_mode & FMODE_WRITE) && md->read_only) ret = -EROFS; } Loading Loading @@ -299,6 +293,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; static inline int mmc_blk_readonly(struct mmc_card *card) { return mmc_card_readonly(card) || !(card->csd.cmdclass & CCC_BLOCK_WRITE); } static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) { struct mmc_blk_data *md; Loading @@ -310,26 +310,80 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) __set_bit(devidx, dev_use); md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); if (md) { if (!md) { ret = -ENOMEM; goto out; } memset(md, 0, sizeof(struct mmc_blk_data)); /* * Set the read-only status based on the supported commands * and the write protect switch. */ md->read_only = mmc_blk_readonly(card); /* * Figure out a workable block size. MMC cards have: * - two block sizes, one for read and one for write. * - may support partial reads and/or writes * (allows block sizes smaller than specified) */ md->block_bits = card->csd.read_blkbits; if (card->csd.write_blkbits != card->csd.read_blkbits) { if (card->csd.write_blkbits < card->csd.read_blkbits && card->csd.read_partial) { /* * write block size is smaller than read block * size, but we support partial reads, so choose * the smaller write block size. */ md->block_bits = card->csd.write_blkbits; } else if (card->csd.write_blkbits > card->csd.read_blkbits && card->csd.write_partial) { /* * read block size is smaller than write block * size, but we support partial writes. Use read * block size. */ } else { /* * We don't support this configuration for writes. */ printk(KERN_ERR "%s: unable to select block size for " "writing (rb%u wb%u rp%u wp%u)\n", md->disk->disk_name, 1 << card->csd.read_blkbits, 1 << card->csd.write_blkbits, card->csd.read_partial, card->csd.write_partial); md->read_only = 1; } } /* * Refuse to allow block sizes smaller than 512 bytes. */ if (md->block_bits < 9) { printk(KERN_ERR "%s: unable to support block size %u\n", mmc_card_id(card), 1 << md->block_bits); ret = -EINVAL; goto err_kfree; } md->disk = alloc_disk(1 << MMC_SHIFT); if (md->disk == NULL) { kfree(md); md = ERR_PTR(-ENOMEM); goto out; ret = -ENOMEM; goto err_kfree; } spin_lock_init(&md->lock); md->usage = 1; ret = mmc_init_queue(&md->queue, card, &md->lock); if (ret) { put_disk(md->disk); kfree(md); md = ERR_PTR(ret); goto out; } if (ret) goto err_putdisk; md->queue.prep_fn = mmc_blk_prep_rq; md->queue.issue_fn = mmc_blk_issue_rq; md->queue.data = md; Loading @@ -356,8 +410,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) sprintf(md->disk->disk_name, "mmcblk%d", devidx); sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); md->block_bits = card->csd.read_blkbits; blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); /* Loading @@ -365,9 +417,14 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) * set_capacity takes units of 512 bytes. */ set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); } out: return md; err_putdisk: put_disk(md->disk); err_kfree: kfree(md); out: return ERR_PTR(ret); } static int Loading Loading @@ -403,12 +460,6 @@ static int mmc_blk_probe(struct mmc_card *card) if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; if (card->csd.read_blkbits < 9) { printk(KERN_WARNING "%s: read blocksize too small (%u)\n", mmc_card_id(card), 1 << card->csd.read_blkbits); return -ENODEV; } md = mmc_blk_alloc(card); if (IS_ERR(md)) return PTR_ERR(md); Loading @@ -419,7 +470,7 @@ static int mmc_blk_probe(struct mmc_card *card) printk(KERN_INFO "%s: %s %s %luKiB %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), get_capacity(md->disk) >> 1, mmc_blk_readonly(card)?"(ro)":""); get_capacity(md->disk) >> 1, md->read_only ? "(ro)" : ""); mmc_set_drvdata(card, md); add_disk(md->disk); Loading drivers/mmc/mmci.c +16 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/protocol.h> #include <asm/cacheflush.h> #include <asm/div64.h> #include <asm/io.h> #include <asm/scatterlist.h> Loading Loading @@ -157,6 +158,13 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) data->error = MMC_ERR_FIFO; status |= MCI_DATAEND; /* * We hit an error condition. Ensure that any data * partially written to a page is properly coherent. */ if (host->sg_len && data->flags & MMC_DATA_READ) flush_dcache_page(host->sg_ptr->page); } if (status & MCI_DATAEND) { mmci_stop_data(host); Loading Loading @@ -292,7 +300,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs) /* * Unmap the buffer. */ mmci_kunmap_atomic(host, &flags); mmci_kunmap_atomic(host, buffer, &flags); host->sg_off += len; host->size -= len; Loading @@ -301,6 +309,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs) if (remain) break; /* * If we were reading, and we have completed this * page, ensure that the data cache is coherent. */ if (status & MCI_RXACTIVE) flush_dcache_page(host->sg_ptr->page); if (!mmci_next_sg(host)) break; Loading drivers/mmc/mmci.h +2 −2 Original line number Diff line number Diff line Loading @@ -172,8 +172,8 @@ static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flag return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; } static inline void mmci_kunmap_atomic(struct mmci_host *host, unsigned long *flags) static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags) { kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); kunmap_atomic(buffer, KM_BIO_SRC_IRQ); local_irq_restore(*flags); } drivers/mmc/wbsd.c +17 −10 Original line number Diff line number Diff line Loading @@ -1456,13 +1456,11 @@ static int __devinit wbsd_scan(struct wbsd_host* host) * Iterate through all ports, all codes to * find hardware that is in our known list. */ for (i = 0;i < sizeof(config_ports)/sizeof(int);i++) { for (i = 0; i < ARRAY_SIZE(config_ports); i++) { if (!request_region(config_ports[i], 2, DRIVER_NAME)) continue; for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) { for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) { id = 0xFFFF; host->config = config_ports[i]; Loading @@ -1478,8 +1476,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host) wbsd_lock_config(host); for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) { for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { if (id == valid_ids[k]) { host->chip_id = id; Loading Loading @@ -2090,10 +2087,20 @@ static int __init wbsd_drv_init(void) if (result < 0) return result; wbsd_device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); if (IS_ERR(wbsd_device)) return PTR_ERR(wbsd_device); wbsd_device = platform_device_alloc(DRIVER_NAME, -1); if (!wbsd_device) { platform_driver_unregister(&wbsd_driver); return -ENOMEM; } result = platform_device_add(wbsd_device); if (result) { platform_device_put(wbsd_device); platform_driver_unregister(&wbsd_driver); return result; } } return 0; Loading Loading
drivers/mmc/mmc.c +10 −0 Original line number Diff line number Diff line Loading @@ -550,6 +550,11 @@ static void mmc_decode_csd(struct mmc_card *card) csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } else { /* * We only understand CSD structure v1.1 and v1.2. Loading Loading @@ -579,6 +584,11 @@ static void mmc_decode_csd(struct mmc_card *card) csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); } } Loading
drivers/mmc/mmc_block.c +113 −62 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ struct mmc_blk_data { unsigned int usage; unsigned int block_bits; unsigned int read_only; }; static DECLARE_MUTEX(open_lock); Loading Loading @@ -85,12 +86,6 @@ static void mmc_blk_put(struct mmc_blk_data *md) up(&open_lock); } static inline int mmc_blk_readonly(struct mmc_card *card) { return mmc_card_readonly(card) || !(card->csd.cmdclass & CCC_BLOCK_WRITE); } static int mmc_blk_open(struct inode *inode, struct file *filp) { struct mmc_blk_data *md; Loading @@ -102,8 +97,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp) check_disk_change(inode->i_bdev); ret = 0; if ((filp->f_mode & FMODE_WRITE) && mmc_blk_readonly(md->queue.card)) if ((filp->f_mode & FMODE_WRITE) && md->read_only) ret = -EROFS; } Loading Loading @@ -299,6 +293,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; static inline int mmc_blk_readonly(struct mmc_card *card) { return mmc_card_readonly(card) || !(card->csd.cmdclass & CCC_BLOCK_WRITE); } static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) { struct mmc_blk_data *md; Loading @@ -310,26 +310,80 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) __set_bit(devidx, dev_use); md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); if (md) { if (!md) { ret = -ENOMEM; goto out; } memset(md, 0, sizeof(struct mmc_blk_data)); /* * Set the read-only status based on the supported commands * and the write protect switch. */ md->read_only = mmc_blk_readonly(card); /* * Figure out a workable block size. MMC cards have: * - two block sizes, one for read and one for write. * - may support partial reads and/or writes * (allows block sizes smaller than specified) */ md->block_bits = card->csd.read_blkbits; if (card->csd.write_blkbits != card->csd.read_blkbits) { if (card->csd.write_blkbits < card->csd.read_blkbits && card->csd.read_partial) { /* * write block size is smaller than read block * size, but we support partial reads, so choose * the smaller write block size. */ md->block_bits = card->csd.write_blkbits; } else if (card->csd.write_blkbits > card->csd.read_blkbits && card->csd.write_partial) { /* * read block size is smaller than write block * size, but we support partial writes. Use read * block size. */ } else { /* * We don't support this configuration for writes. */ printk(KERN_ERR "%s: unable to select block size for " "writing (rb%u wb%u rp%u wp%u)\n", md->disk->disk_name, 1 << card->csd.read_blkbits, 1 << card->csd.write_blkbits, card->csd.read_partial, card->csd.write_partial); md->read_only = 1; } } /* * Refuse to allow block sizes smaller than 512 bytes. */ if (md->block_bits < 9) { printk(KERN_ERR "%s: unable to support block size %u\n", mmc_card_id(card), 1 << md->block_bits); ret = -EINVAL; goto err_kfree; } md->disk = alloc_disk(1 << MMC_SHIFT); if (md->disk == NULL) { kfree(md); md = ERR_PTR(-ENOMEM); goto out; ret = -ENOMEM; goto err_kfree; } spin_lock_init(&md->lock); md->usage = 1; ret = mmc_init_queue(&md->queue, card, &md->lock); if (ret) { put_disk(md->disk); kfree(md); md = ERR_PTR(ret); goto out; } if (ret) goto err_putdisk; md->queue.prep_fn = mmc_blk_prep_rq; md->queue.issue_fn = mmc_blk_issue_rq; md->queue.data = md; Loading @@ -356,8 +410,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) sprintf(md->disk->disk_name, "mmcblk%d", devidx); sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); md->block_bits = card->csd.read_blkbits; blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); /* Loading @@ -365,9 +417,14 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) * set_capacity takes units of 512 bytes. */ set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); } out: return md; err_putdisk: put_disk(md->disk); err_kfree: kfree(md); out: return ERR_PTR(ret); } static int Loading Loading @@ -403,12 +460,6 @@ static int mmc_blk_probe(struct mmc_card *card) if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; if (card->csd.read_blkbits < 9) { printk(KERN_WARNING "%s: read blocksize too small (%u)\n", mmc_card_id(card), 1 << card->csd.read_blkbits); return -ENODEV; } md = mmc_blk_alloc(card); if (IS_ERR(md)) return PTR_ERR(md); Loading @@ -419,7 +470,7 @@ static int mmc_blk_probe(struct mmc_card *card) printk(KERN_INFO "%s: %s %s %luKiB %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), get_capacity(md->disk) >> 1, mmc_blk_readonly(card)?"(ro)":""); get_capacity(md->disk) >> 1, md->read_only ? "(ro)" : ""); mmc_set_drvdata(card, md); add_disk(md->disk); Loading
drivers/mmc/mmci.c +16 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/protocol.h> #include <asm/cacheflush.h> #include <asm/div64.h> #include <asm/io.h> #include <asm/scatterlist.h> Loading Loading @@ -157,6 +158,13 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) data->error = MMC_ERR_FIFO; status |= MCI_DATAEND; /* * We hit an error condition. Ensure that any data * partially written to a page is properly coherent. */ if (host->sg_len && data->flags & MMC_DATA_READ) flush_dcache_page(host->sg_ptr->page); } if (status & MCI_DATAEND) { mmci_stop_data(host); Loading Loading @@ -292,7 +300,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs) /* * Unmap the buffer. */ mmci_kunmap_atomic(host, &flags); mmci_kunmap_atomic(host, buffer, &flags); host->sg_off += len; host->size -= len; Loading @@ -301,6 +309,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs) if (remain) break; /* * If we were reading, and we have completed this * page, ensure that the data cache is coherent. */ if (status & MCI_RXACTIVE) flush_dcache_page(host->sg_ptr->page); if (!mmci_next_sg(host)) break; Loading
drivers/mmc/mmci.h +2 −2 Original line number Diff line number Diff line Loading @@ -172,8 +172,8 @@ static inline char *mmci_kmap_atomic(struct mmci_host *host, unsigned long *flag return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; } static inline void mmci_kunmap_atomic(struct mmci_host *host, unsigned long *flags) static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags) { kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); kunmap_atomic(buffer, KM_BIO_SRC_IRQ); local_irq_restore(*flags); }
drivers/mmc/wbsd.c +17 −10 Original line number Diff line number Diff line Loading @@ -1456,13 +1456,11 @@ static int __devinit wbsd_scan(struct wbsd_host* host) * Iterate through all ports, all codes to * find hardware that is in our known list. */ for (i = 0;i < sizeof(config_ports)/sizeof(int);i++) { for (i = 0; i < ARRAY_SIZE(config_ports); i++) { if (!request_region(config_ports[i], 2, DRIVER_NAME)) continue; for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++) { for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) { id = 0xFFFF; host->config = config_ports[i]; Loading @@ -1478,8 +1476,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host) wbsd_lock_config(host); for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++) { for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { if (id == valid_ids[k]) { host->chip_id = id; Loading Loading @@ -2090,10 +2087,20 @@ static int __init wbsd_drv_init(void) if (result < 0) return result; wbsd_device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); if (IS_ERR(wbsd_device)) return PTR_ERR(wbsd_device); wbsd_device = platform_device_alloc(DRIVER_NAME, -1); if (!wbsd_device) { platform_driver_unregister(&wbsd_driver); return -ENOMEM; } result = platform_device_add(wbsd_device); if (result) { platform_device_put(wbsd_device); platform_driver_unregister(&wbsd_driver); return result; } } return 0; Loading