MMC updates
PATCH 1/1 MMC updates
For anyone who's interested, here's an update to the MMC code Linus recently merged. Essentially, I've added SG support to the MMCI primecell driver.
For specific changes, see the BK comments at the end of the patch.
drivers/mmc/mmc.c +11 -3
@@ -1,7 +1,7 @@/* * linux/drivers/mmc/mmc.c * -* Copyright (C) 2003 Russell King, All Rights Reserved. +* Copyright (C) 2003-2004 Russell King, All Rights Reserved. * * 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
@@ -14,6 +14,7 @@#include <linux/completion.h> #include <linux/device.h> #include <linux/delay.h> +#include <linux/pagemap.h> #include <linux/err.h> #include <linux/mmc/card.h>
@@ -715,14 +716,21 @@if (host) {memset (host,0 ,sizeof (struct mmc_host ) + extra); - host->priv = host +1 ; -spin_lock_init (&host->lock);init_waitqueue_head (&host->wq);INIT_LIST_HEAD (&host->cards);INIT_WORK (&host->detect, mmc_rescan, host); host->dev = dev; + +/* +* By default, hosts do not support SGIO or large requests. +* They have to set these according to their abilities. +*/ + host->max_hw_segs =1 ; + host->max_phys_segs =1 ; + host->max_sectors =1 << (PAGE_CACHE_SHIFT -9 ); + host->max_seg_size =PAGE_CACHE_SIZE ; }return host;
drivers/mmc/mmc_block.c +4 -9
@@ -43,7 +43,6 @@#define MMC_SHIFT 3static int mmc_major; -static int maxsectors =8 ;/* * There is one mmc_blk_data per slot.
@@ -185,7 +184,7 @@ brq.data.timeout_ns = card->csd.tacc_ns *10 ; brq.data.timeout_clks = card->csd.tacc_clks *10 ; brq.data.blksz_bits = md->block_bits; - brq.data.blocks = req->current_nr_sectors >> (md->block_bits -9 ); + brq.data.blocks = req->nr_sectors >> (md->block_bits -9 ); brq.stop.opcode =MMC_STOP_TRANSMISSION ; brq.stop.arg =0 ; brq.stop.flags =MMC_RSP_SHORT |MMC_RSP_CRC |MMC_RSP_BUSY ;
@@ -334,11 +333,10 @@sprintf (md->disk->disk_name,"mmcblk%d" , devidx);sprintf (md->disk->devfs_name,"mmc/blk%d" , devidx); - md->block_bits = md->queue.card->csd.read_blkbits; + md->block_bits = card->csd.read_blkbits; -blk_queue_max_sectors (md->queue.queue, maxsectors);blk_queue_hardsect_size (md->queue.queue,1 << md->block_bits); -set_capacity (md->disk, md->queue.card->csd.capacity); +set_capacity (md->disk, card->csd.capacity); } out:return md;
@@ -440,7 +438,7 @@struct mmc_blk_data *md =mmc_get_drvdata (card);if (md) { -mmc_blk_set_blksize (md, md->queue.card); +mmc_blk_set_blksize (md, card);blk_start_queue (md->queue.queue); }return 0 ;
@@ -489,9 +487,6 @@module_init (mmc_blk_init);module_exit (mmc_blk_exit); -module_param (maxsectors, int,0444 ); - -MODULE_PARM_DESC (maxsectors,"Maximum number of sectors for a single request" );MODULE_LICENSE ("GPL" );MODULE_DESCRIPTION ("Multimedia Card (MMC) block device driver" );
drivers/mmc/mmc_queue.c +7 -2
@@ -124,11 +124,12 @@*/ int mmc_init_queue (struct mmc_queue *mq,struct mmc_card *card,spinlock_t *lock) { +struct mmc_host *host = card->host;u64 limit =BLK_BOUNCE_HIGH ;int ret; -if (card->host->dev->dma_mask && *card->host->dev->dma_mask) - limit = *card->host->dev->dma_mask; +if (host->dev->dma_mask && *host->dev->dma_mask) + limit = *host->dev->dma_mask; mq->card = card; mq->queue =blk_init_queue (mmc_request, lock);
@@ -137,6 +138,10 @@blk_queue_prep_rq (mq->queue, mmc_prep_request);blk_queue_bounce_limit (mq->queue, limit); +blk_queue_max_sectors (mq->queue, host->max_sectors); +blk_queue_max_phys_segments (mq->queue, host->max_phys_segs); +blk_queue_max_hw_segments (mq->queue, host->max_hw_segs); +blk_queue_max_segment_size (mq->queue, host->max_seg_size); mq->queue->queuedata = mq; mq->req =NULL ;
drivers/mmc/mmci.c +175 -51
300 lines not on this page · raw message
drivers/mmc/mmci.h +6 -11
@@ -103,18 +103,15 @@#define MMCIFIFOCNT 0x048#define MMCIFIFO 0x080/* to 0x0bc */ -#define MCI_IRQMASK \ - (MCI_CMDCRCFAIL|MCI_DATACRCFAIL|MCI_CMDTIMEOUT|MCI_DATATIMEOUT| \ - MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_CMDRESPEND|MCI_CMDSENT| \ - MCI_DATAEND|MCI_DATABLOCKEND) -#define MCI_IRQENABLE \ (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ - MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK| \ - MCI_DATABLOCKENDMASK) + MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) -#define MCI_FIFOSIZE 16 +/* +* The size of the FIFO in bytes. +*/ +#define MCI_FIFOSIZE (16*4)#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
@@ -141,8 +138,6 @@unsigned int oldstat;/* pio stuff */ -void *buffer; +unsigned int offset;unsigned int size; }; - -#define to_mmci_host (mmc) container_of(mmc, struct mmci_host, mmc)
drivers/mmc/pxamci.c +5 -0
@@ -530,6 +530,7 @@return 0 ; } +#ifdef CONFIG_PM static int pxamci_suspend (struct device *dev,u32 state,u32 level) {struct mmc_host *mmc =dev_get_drvdata (dev);
@@ -551,6 +552,10 @@return ret; } +#else +#define pxamci_suspend NULL +#define pxamci_resume NULL +#endif static struct device_driver pxamci_driver = { .name ="pxa2xx-mci" ,
include/linux/mmc/host.h +7 -1
@@ -64,11 +64,17 @@struct mmc_host {struct device *dev;struct mmc_host_ops *ops; -void *priv;unsigned int f_min;unsigned int f_max;u32 ocr_avail;char host_name[8 ]; + +/* host specific block data */ +unsigned int max_seg_size;/* see blk_queue_max_segment_size */ +unsigned short max_hw_segs;/* see blk_queue_max_hw_segments */ +unsigned short max_phys_segs;/* see blk_queue_max_phys_segments */ +unsigned short max_sectors;/* see blk_queue_max_sectors */ +unsigned short unused;/* private data */ struct mmc_ios ios;/* current io bus settings */
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/08/30 17:43:10+01:00 [email protected]
# [MMC] PXAMCI: Bracket power management calls with CONFIG_PM.
#
# drivers/mmc/pxamci.c # 2004/08/30 17:40:45+01:00 [email protected] +5 -0 # Bracket power management calls with CONFIG_PM. # # ChangeSet # 2004/08/30 17:33:23+01:00 [email protected] # [MMC] MMCI: Ensure that we read all data from FIFO. # # When we are nearing the end of a transfer from the card, we may not # have sufficient data in the FIFO to trigger a "half FIFO full" IRQ. # Therefore, when we have less than MCI_FIFOSIZE bytes left, switch to # "FIFO contains data" IRQ mode instead. # # drivers/mmc/mmci.c # 2004/08/30 17:31:00+01:00 [email protected] +7 -0 # Enable the rx data available irq mask towards then end of a receive # data transfer. # # ChangeSet # 2004/08/30 17:17:25+01:00 [email protected] # [MMC] MMCI: Add SG support to PIO data transfers # # This allows us to transfer a whole request for multiple pages in one # transaction with the MMC card, resulting in higher overall throughput. # # drivers/mmc/mmci.c # 2004/08/30 17:14:26+01:00 [email protected] +66 -5 # Add scatter-gather support to PIO data transfers, and enable the # feature. # # ChangeSet # 2004/08/30 17:03:48+01:00 [email protected] # [MMC] MMCI: use bio_kmap_irq() rather than req->buffer # # This is in preparation for SG data IO. # # drivers/mmc/mmci.c # 2004/08/30 17:01:15+01:00 [email protected] +41 -22 # Map BIO buffer with bio_kmap_irq() rather than using req->buffer # directly. # # ChangeSet # 2004/08/30 16:23:08+01:00 [email protected] # [MMC] MMCI: Maintain offset rather than buffer pointer for PIO # # drivers/mmc/mmci.h # 2004/08/30 16:20:21+01:00 [email protected] +1 -1 # *buffer becomes offset # # drivers/mmc/mmci.c # 2004/08/30 16:20:20+01:00 [email protected] +11 -9 # Maintain a buffer offset rather than the buffer pointer for PIO # data transfers. # # ChangeSet # 2004/08/30 16:13:28+01:00 [email protected] # [MMC] MMCI: split the PIO data read and write paths. # # drivers/mmc/mmci.c # 2004/08/30 16:11:08+01:00 [email protected] +64 -29 # Separate the PIO data read and write paths. We select read or write # depending on whether the TX or RX active status flags are set. # # ChangeSet # 2004/08/30 15:38:01+01:00 [email protected] # [MMC] MMCI: Manipulate IRQ masks according to the data FSM state. # # Prevent IRQ race conditions between the two handlers and within the # primecell itself. Unfortunately, the primecell does not always mask # the FIFO empty interrupt we reach the end of a transfer to the card. # Also, we may receive the "data end" interrupt prior to finishing a # transfer from the card, so mask this off until we've read the last # bytes from the FIFO. # # drivers/mmc/mmci.h # 2004/08/30 15:35:25+01:00 [email protected] +1 -2 # Disable data end IRQ mask # # drivers/mmc/mmci.c # 2004/08/30 15:35:25+01:00 [email protected] +13 -18 # Manipulate IRQ masks according to the data FSM state. # # ChangeSet # 2004/08/30 12:46:45+01:00 [email protected] # [MMC] MMCI: data FSM handling updates # # - Use mmci_stop_host() to ensure that the data FSM is shut down and # any driver held data is properly released. # - FIFO size is 64 bytes not 16. # # drivers/mmc/mmci.h # 2004/08/30 12:44:09+01:00 [email protected] +4 -3 # Correct MMCI fifo size. # Remove unused to_mmci_host macro. # # drivers/mmc/mmci.c # 2004/08/30 12:44:08+01:00 [email protected] +10 -3 # Add mmci_stop_host() to disable MMCI data FSM. # # ChangeSet # 2004/08/30 11:12:18+01:00 [email protected] # [MMC] MMCI: Remove hardcoded MCI_IRQMASK definition # # drivers/mmc/mmci.h # 2004/08/30 11:09:10+01:00 [email protected] +0 -5 # Remove hardcoded MCI_IRQMASK definition. # # drivers/mmc/mmci.c # 2004/08/30 11:08:33+01:00 [email protected] +1 -3 # Mask chip irq status with irq mask 0 to mask out unwanted IRQs # # ChangeSet # 2004/08/30 10:58:22+01:00 [email protected] # [MMC] Give the MMC host the full-sized request. # # Pass the total number of MMC data blocks in the request to the # host driver. Since existing MMC host drivers do not support # scatter-gather at present, the block queue defaults have been # chosen to prevent scatter-gather block requests for MMC. A # host can alter these parameters when it wishes to take advantage # of SG capabilities. # # drivers/mmc/mmc_block.c # 2004/08/30 10:52:59+01:00 [email protected] +1 -1 # Pass the total number of MMC data blocks in the request to the # host driver. # # ChangeSet # 2004/08/30 10:49:37+01:00 [email protected] # [MMC] Add host specific block queue parameters # # Allow MMC host drivers to specify their data phase capabilities # to the block queue. This will eventually allow us to perform # SG data phase operations, thereby processing a single request # in one go. # # drivers/mmc/mmc_block.c # 2004/08/30 10:43:31+01:00 [email protected] +0 -5 # Remove 'maxsectors' parameter and associated queue setting. # This is a host specific parameter now. # # drivers/mmc/mmc_queue.c # 2004/08/30 10:41:24+01:00 [email protected] +7 -2 # When creating a new block queue, set the queue parameters # from the host specific data. # # drivers/mmc/mmc.c # 2004/08/30 10:40:28+01:00 [email protected] +11 -1 # Add host specific block queue default settings # # include/linux/mmc/host.h # 2004/08/30 10:40:06+01:00 [email protected] +7 -0 # Add host specific block queue data # # ChangeSet # 2004/08/30 10:30:55+01:00 [email protected] # [MMC] Remove unused host->priv # # include/linux/mmc/host.h # 2004/08/30 10:22:39+01:00 [email protected] +0 -1 # Remove unused host->priv # # drivers/mmc/mmc.c # 2004/08/30 10:22:22+01:00 [email protected] +0 -2 # Remove unused host->priv # # ChangeSet # 2004/08/30 10:20:35+01:00 [email protected] # [MMC] Use local card pointer rather than md->queue.card # # drivers/mmc/mmc_block.c # 2004/08/30 10:16:45+01:00 [email protected] +3 -3 # No point using md->queue.card when we already have a # pointer to the card itself. #
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 5 lines · Russell King
For anyone who's interested, here's an update to the MMC code Linus recently merged. Essentially, I've added SG support to the MMCI primecell driver.
Just to make sure I've understood this correctly. SGIO takes a number of memory locations and fills these with data from a continous stream of data from the card? I.e. only the local memory locations need special handling. No seeking on the card? And any "gaps" where data is not wanted is handled by upper layers?
Rgds
Pierre
Quoted 10 lines · Pierre Ossman
Quoted 3 lines · Russell King
For anyone who's interested, here's an update to the MMC code Linus recently merged. Essentially, I've added SG support to the MMCI primecell driver.
Just to make sure I've understood this correctly. SGIO takes a number of memory locations and fills these with data from a continous stream of data from the card? I.e. only the local memory locations need special handling. No seeking on the card? And any "gaps" where data is not wanted is handled by upper layers?
Correct. One "request" is for a set of sectors from N to N+L, where data is read/written to a set of possibly non-contiguous pages.
You don't have to support it - there are defaults chosen by the code to ensure that we won't see these "SG" requests unless the driver can handle them.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core