Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
sdhci: tell which spurious interrupt we got
sdhci: handle data interrupts during command
mmc: ignore bad max block size in sdhci
sdhci: be more cautious about block count register
drivers/mmc/core/host.c: kmalloc + memset conversion to kzalloc
drivers/mmc/core/bus.c: kmalloc + memset conversion to kzalloc

+36 -26
+1 -3
drivers/mmc/core/bus.c
··· 186 186 { 187 187 struct mmc_card *card; 188 188 189 - card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); 189 + card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); 190 190 if (!card) 191 191 return ERR_PTR(-ENOMEM); 192 - 193 - memset(card, 0, sizeof(struct mmc_card)); 194 192 195 193 card->host = host; 196 194
+1 -3
drivers/mmc/core/host.c
··· 58 58 { 59 59 struct mmc_host *host; 60 60 61 - host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 61 + host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 62 62 if (!host) 63 63 return NULL; 64 - 65 - memset(host, 0, sizeof(struct mmc_host) + extra); 66 64 67 65 host->parent = dev; 68 66 host->class_dev.parent = dev;
+33 -20
drivers/mmc/host/sdhci.c
··· 385 385 BUG_ON(data->blksz > host->mmc->max_blk_size); 386 386 BUG_ON(data->blocks > 65535); 387 387 388 + host->data = data; 389 + host->data_early = 0; 390 + 388 391 /* timeout in us */ 389 392 target_timeout = data->timeout_ns / 1000 + 390 393 data->timeout_clks / host->clock; ··· 446 443 { 447 444 u16 mode; 448 445 449 - WARN_ON(host->data); 450 - 451 446 if (data == NULL) 452 447 return; 448 + 449 + WARN_ON(!host->data); 453 450 454 451 mode = SDHCI_TRNS_BLK_CNT_EN; 455 452 if (data->blocks > 1) ··· 480 477 /* 481 478 * Controller doesn't count down when in single block mode. 482 479 */ 483 - if ((data->blocks == 1) && (data->error == MMC_ERR_NONE)) 484 - blocks = 0; 480 + if (data->blocks == 1) 481 + blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; 485 482 else 486 483 blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); 487 484 data->bytes_xfered = data->blksz * (data->blocks - blocks); ··· 603 600 604 601 host->cmd->error = MMC_ERR_NONE; 605 602 606 - if (host->cmd->data) 607 - host->data = host->cmd->data; 608 - else 603 + if (host->data && host->data_early) 604 + sdhci_finish_data(host); 605 + 606 + if (!host->cmd->data) 609 607 tasklet_schedule(&host->finish_tasklet); 610 608 611 609 host->cmd = NULL; ··· 933 929 BUG_ON(intmask == 0); 934 930 935 931 if (!host->cmd) { 936 - printk(KERN_ERR "%s: Got command interrupt even though no " 937 - "command operation was in progress.\n", 938 - mmc_hostname(host->mmc)); 932 + printk(KERN_ERR "%s: Got command interrupt 0x%08x even " 933 + "though no command operation was in progress.\n", 934 + mmc_hostname(host->mmc), (unsigned)intmask); 939 935 sdhci_dumpregs(host); 940 936 return; 941 937 } ··· 965 961 if (intmask & SDHCI_INT_DATA_END) 966 962 return; 967 963 968 - printk(KERN_ERR "%s: Got data interrupt even though no " 969 - "data operation was in progress.\n", 970 - mmc_hostname(host->mmc)); 964 + printk(KERN_ERR "%s: Got data interrupt 0x%08x even " 965 + "though no data operation was in progress.\n", 966 + mmc_hostname(host->mmc), (unsigned)intmask); 971 967 sdhci_dumpregs(host); 972 968 973 969 return; ··· 995 991 writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), 996 992 host->ioaddr + SDHCI_DMA_ADDRESS); 997 993 998 - if (intmask & SDHCI_INT_DATA_END) 999 - sdhci_finish_data(host); 994 + if (intmask & SDHCI_INT_DATA_END) { 995 + if (host->cmd) { 996 + /* 997 + * Data managed to finish before the 998 + * command completed. Make sure we do 999 + * things in the proper order. 1000 + */ 1001 + host->data_early = 1; 1002 + } else { 1003 + sdhci_finish_data(host); 1004 + } 1005 + } 1000 1006 } 1001 1007 } 1002 1008 ··· 1361 1347 */ 1362 1348 mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; 1363 1349 if (mmc->max_blk_size >= 3) { 1364 - printk(KERN_ERR "%s: Invalid maximum block size.\n", 1350 + printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n", 1365 1351 host->slot_descr); 1366 - ret = -ENODEV; 1367 - goto unmap; 1368 - } 1369 - mmc->max_blk_size = 512 << mmc->max_blk_size; 1352 + mmc->max_blk_size = 512; 1353 + } else 1354 + mmc->max_blk_size = 512 << mmc->max_blk_size; 1370 1355 1371 1356 /* 1372 1357 * Maximum block count.
+1
drivers/mmc/host/sdhci.h
··· 182 182 struct mmc_request *mrq; /* Current request */ 183 183 struct mmc_command *cmd; /* Current command */ 184 184 struct mmc_data *data; /* Current data request */ 185 + int data_early:1; /* Data finished before cmd */ 185 186 186 187 struct scatterlist *cur_sg; /* We're working on this */ 187 188 int num_sg; /* Entries left */