aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/sdio_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/sdio_io.c')
-rw-r--r--drivers/mmc/core/sdio_io.c167
1 files changed, 128 insertions, 39 deletions
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 625b92ce9ce..f61fc2d4cd0 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mmc/core/sdio_io.c 2 * linux/drivers/mmc/core/sdio_io.c
3 * 3 *
4 * Copyright 2007 Pierre Ossman 4 * Copyright 2007-2008 Pierre Ossman
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -76,11 +76,7 @@ int sdio_enable_func(struct sdio_func *func)
76 if (ret) 76 if (ret)
77 goto err; 77 goto err;
78 78
79 /* 79 timeout = jiffies + msecs_to_jiffies(func->enable_timeout);
80 * FIXME: This should timeout based on information in the CIS,
81 * but we don't have card to parse that yet.
82 */
83 timeout = jiffies + HZ;
84 80
85 while (1) { 81 while (1) {
86 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg); 82 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg);
@@ -167,10 +163,8 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
167 return -EINVAL; 163 return -EINVAL;
168 164
169 if (blksz == 0) { 165 if (blksz == 0) {
170 blksz = min(min( 166 blksz = min(func->max_blksize, func->card->host->max_blk_size);
171 func->max_blksize, 167 blksz = min(blksz, 512u);
172 func->card->host->max_blk_size),
173 512u);
174 } 168 }
175 169
176 ret = mmc_io_rw_direct(func->card, 1, 0, 170 ret = mmc_io_rw_direct(func->card, 1, 0,
@@ -186,9 +180,116 @@ int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
186 func->cur_blksize = blksz; 180 func->cur_blksize = blksz;
187 return 0; 181 return 0;
188} 182}
189
190EXPORT_SYMBOL_GPL(sdio_set_block_size); 183EXPORT_SYMBOL_GPL(sdio_set_block_size);
191 184
185/*
186 * Calculate the maximum byte mode transfer size
187 */
188static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
189{
190 unsigned mval = min(func->card->host->max_seg_size,
191 func->card->host->max_blk_size);
192 mval = min(mval, func->max_blksize);
193 return min(mval, 512u); /* maximum size for byte mode */
194}
195
196/**
197 * sdio_align_size - pads a transfer size to a more optimal value
198 * @func: SDIO function
199 * @sz: original transfer size
200 *
201 * Pads the original data size with a number of extra bytes in
202 * order to avoid controller bugs and/or performance hits
203 * (e.g. some controllers revert to PIO for certain sizes).
204 *
205 * If possible, it will also adjust the size so that it can be
206 * handled in just a single request.
207 *
208 * Returns the improved size, which might be unmodified.
209 */
210unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
211{
212 unsigned int orig_sz;
213 unsigned int blk_sz, byte_sz;
214 unsigned chunk_sz;
215
216 orig_sz = sz;
217
218 /*
219 * Do a first check with the controller, in case it
220 * wants to increase the size up to a point where it
221 * might need more than one block.
222 */
223 sz = mmc_align_data_size(func->card, sz);
224
225 /*
226 * If we can still do this with just a byte transfer, then
227 * we're done.
228 */
229 if (sz <= sdio_max_byte_size(func))
230 return sz;
231
232 if (func->card->cccr.multi_block) {
233 /*
234 * Check if the transfer is already block aligned
235 */
236 if ((sz % func->cur_blksize) == 0)
237 return sz;
238
239 /*
240 * Realign it so that it can be done with one request,
241 * and recheck if the controller still likes it.
242 */
243 blk_sz = ((sz + func->cur_blksize - 1) /
244 func->cur_blksize) * func->cur_blksize;
245 blk_sz = mmc_align_data_size(func->card, blk_sz);
246
247 /*
248 * This value is only good if it is still just
249 * one request.
250 */
251 if ((blk_sz % func->cur_blksize) == 0)
252 return blk_sz;
253
254 /*
255 * We failed to do one request, but at least try to
256 * pad the remainder properly.
257 */
258 byte_sz = mmc_align_data_size(func->card,
259 sz % func->cur_blksize);
260 if (byte_sz <= sdio_max_byte_size(func)) {
261 blk_sz = sz / func->cur_blksize;
262 return blk_sz * func->cur_blksize + byte_sz;
263 }
264 } else {
265 /*
266 * We need multiple requests, so first check that the
267 * controller can handle the chunk size;
268 */
269 chunk_sz = mmc_align_data_size(func->card,
270 sdio_max_byte_size(func));
271 if (chunk_sz == sdio_max_byte_size(func)) {
272 /*
273 * Fix up the size of the remainder (if any)
274 */
275 byte_sz = orig_sz % chunk_sz;
276 if (byte_sz) {
277 byte_sz = mmc_align_data_size(func->card,
278 byte_sz);
279 }
280
281 return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
282 }
283 }
284
285 /*
286 * The controller is simply incapable of transferring the size
287 * we want in decent manner, so just return the original size.
288 */
289 return orig_sz;
290}
291EXPORT_SYMBOL_GPL(sdio_align_size);
292
192/* Split an arbitrarily sized data transfer into several 293/* Split an arbitrarily sized data transfer into several
193 * IO_RW_EXTENDED commands. */ 294 * IO_RW_EXTENDED commands. */
194static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, 295static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
@@ -199,14 +300,13 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
199 int ret; 300 int ret;
200 301
201 /* Do the bulk of the transfer using block mode (if supported). */ 302 /* Do the bulk of the transfer using block mode (if supported). */
202 if (func->card->cccr.multi_block) { 303 if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
203 /* Blocks per command is limited by host count, host transfer 304 /* Blocks per command is limited by host count, host transfer
204 * size (we only use a single sg entry) and the maximum for 305 * size (we only use a single sg entry) and the maximum for
205 * IO_RW_EXTENDED of 511 blocks. */ 306 * IO_RW_EXTENDED of 511 blocks. */
206 max_blocks = min(min( 307 max_blocks = min(func->card->host->max_blk_count,
207 func->card->host->max_blk_count, 308 func->card->host->max_seg_size / func->cur_blksize);
208 func->card->host->max_seg_size / func->cur_blksize), 309 max_blocks = min(max_blocks, 511u);
209 511u);
210 310
211 while (remainder > func->cur_blksize) { 311 while (remainder > func->cur_blksize) {
212 unsigned blocks; 312 unsigned blocks;
@@ -231,11 +331,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
231 331
232 /* Write the remainder using byte mode. */ 332 /* Write the remainder using byte mode. */
233 while (remainder > 0) { 333 while (remainder > 0) {
234 size = remainder; 334 size = min(remainder, sdio_max_byte_size(func));
235 if (size > func->cur_blksize)
236 size = func->cur_blksize;
237 if (size > 512)
238 size = 512; /* maximum size for byte mode */
239 335
240 ret = mmc_io_rw_extended(func->card, write, func->num, addr, 336 ret = mmc_io_rw_extended(func->card, write, func->num, addr,
241 incr_addr, buf, 1, size); 337 incr_addr, buf, 1, size);
@@ -260,11 +356,10 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
260 * function. If there is a problem reading the address, 0xff 356 * function. If there is a problem reading the address, 0xff
261 * is returned and @err_ret will contain the error code. 357 * is returned and @err_ret will contain the error code.
262 */ 358 */
263unsigned char sdio_readb(struct sdio_func *func, unsigned int addr, 359u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
264 int *err_ret)
265{ 360{
266 int ret; 361 int ret;
267 unsigned char val; 362 u8 val;
268 363
269 BUG_ON(!func); 364 BUG_ON(!func);
270 365
@@ -293,8 +388,7 @@ EXPORT_SYMBOL_GPL(sdio_readb);
293 * function. @err_ret will contain the status of the actual 388 * function. @err_ret will contain the status of the actual
294 * transfer. 389 * transfer.
295 */ 390 */
296void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, 391void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
297 int *err_ret)
298{ 392{
299 int ret; 393 int ret;
300 394
@@ -355,7 +449,6 @@ int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
355{ 449{
356 return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count); 450 return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
357} 451}
358
359EXPORT_SYMBOL_GPL(sdio_readsb); 452EXPORT_SYMBOL_GPL(sdio_readsb);
360 453
361/** 454/**
@@ -385,8 +478,7 @@ EXPORT_SYMBOL_GPL(sdio_writesb);
385 * function. If there is a problem reading the address, 0xffff 478 * function. If there is a problem reading the address, 0xffff
386 * is returned and @err_ret will contain the error code. 479 * is returned and @err_ret will contain the error code.
387 */ 480 */
388unsigned short sdio_readw(struct sdio_func *func, unsigned int addr, 481u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
389 int *err_ret)
390{ 482{
391 int ret; 483 int ret;
392 484
@@ -400,7 +492,7 @@ unsigned short sdio_readw(struct sdio_func *func, unsigned int addr,
400 return 0xFFFF; 492 return 0xFFFF;
401 } 493 }
402 494
403 return le16_to_cpu(*(u16*)func->tmpbuf); 495 return le16_to_cpup((__le16 *)func->tmpbuf);
404} 496}
405EXPORT_SYMBOL_GPL(sdio_readw); 497EXPORT_SYMBOL_GPL(sdio_readw);
406 498
@@ -415,12 +507,11 @@ EXPORT_SYMBOL_GPL(sdio_readw);
415 * function. @err_ret will contain the status of the actual 507 * function. @err_ret will contain the status of the actual
416 * transfer. 508 * transfer.
417 */ 509 */
418void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr, 510void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
419 int *err_ret)
420{ 511{
421 int ret; 512 int ret;
422 513
423 *(u16*)func->tmpbuf = cpu_to_le16(b); 514 *(__le16 *)func->tmpbuf = cpu_to_le16(b);
424 515
425 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2); 516 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
426 if (err_ret) 517 if (err_ret)
@@ -439,8 +530,7 @@ EXPORT_SYMBOL_GPL(sdio_writew);
439 * 0xffffffff is returned and @err_ret will contain the error 530 * 0xffffffff is returned and @err_ret will contain the error
440 * code. 531 * code.
441 */ 532 */
442unsigned long sdio_readl(struct sdio_func *func, unsigned int addr, 533u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
443 int *err_ret)
444{ 534{
445 int ret; 535 int ret;
446 536
@@ -454,7 +544,7 @@ unsigned long sdio_readl(struct sdio_func *func, unsigned int addr,
454 return 0xFFFFFFFF; 544 return 0xFFFFFFFF;
455 } 545 }
456 546
457 return le32_to_cpu(*(u32*)func->tmpbuf); 547 return le32_to_cpup((__le32 *)func->tmpbuf);
458} 548}
459EXPORT_SYMBOL_GPL(sdio_readl); 549EXPORT_SYMBOL_GPL(sdio_readl);
460 550
@@ -469,12 +559,11 @@ EXPORT_SYMBOL_GPL(sdio_readl);
469 * function. @err_ret will contain the status of the actual 559 * function. @err_ret will contain the status of the actual
470 * transfer. 560 * transfer.
471 */ 561 */
472void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr, 562void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
473 int *err_ret)
474{ 563{
475 int ret; 564 int ret;
476 565
477 *(u32*)func->tmpbuf = cpu_to_le32(b); 566 *(__le32 *)func->tmpbuf = cpu_to_le32(b);
478 567
479 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4); 568 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
480 if (err_ret) 569 if (err_ret)