else
                mval = min(mval, func->max_blksize);
 
+       if (mmc_card_broken_byte_mode_512(func->card))
+               return min(mval, 511u);
+
        return min(mval, 512u); /* maximum size for byte mode */
 }
 
                        func->card->host->max_seg_size / func->cur_blksize);
                max_blocks = min(max_blocks, 511u);
 
-               while (remainder > func->cur_blksize) {
+               while (remainder >= func->cur_blksize) {
                        unsigned blocks;
 
                        blocks = remainder / func->cur_blksize;
        while (remainder > 0) {
                size = min(remainder, sdio_max_byte_size(func));
 
+               /* Indicate byte mode by setting "blocks" = 0 */
                ret = mmc_io_rw_extended(func->card, write, func->num, addr,
-                        incr_addr, buf, 1, size);
+                        incr_addr, buf, 0, size);
                if (ret)
                        return ret;
 
 
 
        BUG_ON(!card);
        BUG_ON(fn > 7);
-       BUG_ON(blocks == 1 && blksz > 512);
-       WARN_ON(blocks == 0);
        WARN_ON(blksz == 0);
 
        /* sanity check */
        cmd.arg |= fn << 28;
        cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
        cmd.arg |= addr << 9;
-       if (blocks == 1 && blksz < 512)
-               cmd.arg |= blksz;                       /* byte mode */
-       else if (blocks == 1 && blksz == 512 &&
-                !(mmc_card_broken_byte_mode_512(card)))
-               cmd.arg |= 0;                           /* byte mode, 0==512 */
+       if (blocks == 0)
+               cmd.arg |= (blksz == 512) ? 0 : blksz;  /* byte mode */
        else
                cmd.arg |= 0x08000000 | blocks;         /* block mode */
        cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
 
        data.blksz = blksz;
-       data.blocks = blocks;
+       /* Code in host drivers/fwk assumes that "blocks" always is >=1 */
+       data.blocks = blocks ? blocks : 1;
        data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
        data.sg = &sg;
        data.sg_len = 1;
 
-       sg_init_one(&sg, buf, blksz * blocks);
+       sg_init_one(&sg, buf, data.blksz * data.blocks);
 
        mmc_set_data_timeout(&data, card);