This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3352 Booting unstable

Other Parts Discussed in Thread: AM3352, DA8XX

Hi, We had a problem with AM3352 Booting from Micro SD.

Sometimes, it works well, but sometimes, it will fail to boot up with the log below.

Could someone help to review what root cause is..

-Boot SPL 2011.09-svn2848 (Aug 20 2013 - 17:26:44)
Texas Instruments Revision detection unimplemented
OMAP SD/MMC: 0
reading u-boot.img
reading u-boot.img


U-Boot 2011.09-svn2848 (Aug 20 2013 - 17:26:44)

I2C: ready
DRAM: 512 MiB
WARNING: Caches not enabled
MMC: OMAP SD/MMC: 0
Using default environment

reading logo.bmp

460854 bytes read

Done
reading lcd_bl

** Unable to read "lcd_bl" from mmc 0:1 **
file_size==>0
Load Fail...
LCD BL:(85)
Net: cpsw
Hit any key to stop autoboot: 0
SD/MMC found on device 0
reading uEnv.txt

2563 bytes read
Loaded environment from uEnv.txt
Importing environment from mmc ...
Running uenvcmd ...
reading uEnv.txt2

** Unable to read "uEnv.txt2" from mmc 0:1 **
Importing environment from mmc ...
reading uImage

2891808 bytes read
## Booting kernel from Legacy Image at 80007fc0 ...
Image Name: Linux-3.2.0+
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2891744 Bytes = 2.8 MiB
Load Address: 80008000
Entry Point: 80008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[ 0.000000] Linux version 3.2.0+ (neil@bogon) (gcc version 4.5.3 20110311 (prerelease) (GCC) ) #1 Tue Aug 20 17:06:06 CST 2013
[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine: am335xevm
[ 0.000000] Memory policy: ECC disabled, Data cache writeback
[ 0.000000] AM335X ES1.0 (neon )
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048
[ 0.000000] Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait ip=none lcd_bl=85
[ 0.000000] Set LCD BL: 85
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 512MB = 512MB total
[ 0.000000] Memory: 513568k/513568k available, 10720k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] vmalloc : 0xe0800000 - 0xff000000 ( 488 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc0521000 (5220 kB)
[ 0.000000] .init : 0xc0521000 - 0xc0580000 ( 380 kB)
[ 0.000000] .data : 0xc0580000 - 0xc05dbdb0 ( 368 kB)
[ 0.000000] .bss : 0xc05dbdd4 - 0xc0609a30 ( 184 kB)
[ 0.000000] NR_IRQS:396
[ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
[ 0.000000] Total of 128 interrupts on 1 active controller
[ 0.000000] OMAP clockevent source: GPTIMER2 at 24000000 Hz
[ 0.000000] omap_dm_timer_switch_src: Switching to HW default clocksource(sys_clkin_ck) for timer1, this may impact timekeeping in low power state
[ 0.000000] OMAP clocksource: GPTIMER1 at 24000000 Hz
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[ 0.000000] Console: colour dummy device 80x30
[ 0.000234] Calibrating delay loop... 498.89 BogoMIPS (lpj=2494464)
[ 0.056308] pid_max: default: 32768 minimum: 301
[ 0.056473] Security Framework initialized
[ 0.056601] Mount-cache hash table entries: 512
[ 0.057069] CPU: Testing write buffer coherency: ok
[ 0.078402] omap_hwmod: gfx: failed to hardreset
[ 0.095176] omap_hwmod: pruss: failed to hardreset
[ 0.096594] print_constraints: dummy:
[ 0.097055] NET: Registered protocol family 16
[ 0.099874] OMAP GPIO hardware version 0.1
[ 0.103441] omap_mux_init: Add partition: #1: core, flags: 0
[ 0.106160] omap_i2c.1: alias fck already exists
[ 0.107429] omap2_mcspi.1: alias fck already exists
[ 0.107736] omap2_mcspi.2: alias fck already exists
[ 0.108706] edma.0: alias fck already exists
[ 0.108736] edma.0: alias fck already exists
[ 0.108763] edma.0: alias fck already exists
[ 0.142033] bio: create slab <bio-0> at 0
[ 0.144252] SCSI subsystem initialized
[ 0.146459] usbcore: registered new interface driver usbfs
[ 0.146896] usbcore: registered new interface driver hub
[ 0.147170] usbcore: registered new device driver usb
[ 0.147565] registerd cppi-dma Intr @ IRQ 17
[ 0.147585] Cppi41 Init Done Qmgr-base(e087a000) dma-base(e0878000)
[ 0.147599] Cppi41 Init Done
[ 0.147635] musb-ti81xx musb-ti81xx: musb0, board_mode=0x13, plat_mode=0x3
[ 0.148020] musb-ti81xx musb-ti81xx: musb1, board_mode=0x13, plat_mode=0x1
[ 0.149557] omap_i2c omap_i2c.1: bus 1 rev2.4.0 at 100 kHz
[ 0.152852] Switching to clocksource gp timer
[ 0.174502] musb-hdrc: version 6.0, ?dma?, otg (peripheral+host)
[ 0.174720] musb-hdrc musb-hdrc.0: dma type: dma-cppi41
[ 0.175144] MUSB0 controller's USBSS revision = 4ea20800
[ 0.176353] musb-hdrc musb-hdrc.0: USB OTG mode controller at e083c000 using DMA, IRQ 18
[ 0.176558] musb-hdrc musb-hdrc.1: dma type: dma-cppi41
[ 0.176964] MUSB1 controller's USBSS revision = 4ea20800
[ 0.177475] musb-hdrc musb-hdrc.1: MUSB HDRC host driver
[ 0.177586] musb-hdrc musb-hdrc.1: new USB bus registered, assigned bus number 1
[ 0.177752] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 0.177775] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 0.177795] usb usb1: Product: MUSB HDRC host driver
[ 0.177810] usb usb1: Manufacturer: Linux 3.2.0+ musb-hcd
[ 0.177826] usb usb1: SerialNumber: musb-hdrc.1
[ 0.178942] hub 1-0:1.0: USB hub found
[ 0.178982] hub 1-0:1.0: 1 port detected
[ 0.179746] musb-hdrc musb-hdrc.1: USB Host mode controller at e083e800 using DMA, IRQ 19
[ 0.180282] NET: Registered protocol family 2
[ 0.180514] IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.180903] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[ 0.181330] TCP bind hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.181582] TCP: Hash tables configured (established 16384 bind 16384)
[ 0.181599] TCP reno registered
[ 0.181616] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.181649] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.181892] NET: Registered protocol family 1
[ 0.182215] RPC: Registered named UNIX socket transport module.
[ 0.182234] RPC: Registered udp transport module.
[ 0.182247] RPC: Registered tcp transport module.
[ 0.182260] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.182553] NetWinder Floating Point Emulator V0.97 (double precision)
[ 0.205752] VFS: Disk quotas dquot_6.5.2
[ 0.205839] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[ 0.206520] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[ 0.207079] msgmni has been set to 1003
[ 0.211270] alg: No test for stdrng (krng)
[ 0.212138] io scheduler noop registered
[ 0.212157] io scheduler deadline registered
[ 0.212250] io scheduler cfq registered (default)
[ 0.214800] omap_uart.0: ttyO0 at MMIO 0x44e09000 (irq = 72) is a OMAP UART0
[ 0.795635] console [ttyO0] enabled
[ 0.800125] omap_uart.1: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1
[ 0.808169] omap_uart.2: ttyO2 at MMIO 0x48024000 (irq = 74) is a OMAP UART2
[ 0.816172] omap_uart.3: ttyO3 at MMIO 0x481a6000 (irq = 44) is a OMAP UART3
[ 0.824157] omap_uart.4: ttyO4 at MMIO 0x481a8000 (irq = 45) is a OMAP UART4
[ 0.832091] omap_uart.5: ttyO5 at MMIO 0x481aa000 (irq = 46) is a OMAP UART5
[ 0.853189] brd: module loaded
[ 0.863386] loop: module loaded
[ 0.866923] i2c-core: driver [tsl2550] using legacy suspend method
[ 0.873456] i2c-core: driver [tsl2550] using legacy resume method
[ 0.879948] at24 1-0050: 32768 byte 24c256 EEPROM, writable, 64 bytes/write
[ 0.887290] The board is a AM335x Starter Kit.
[ 0.892406] omap_hsmmc.0: alias fck already exists
[ 0.898063] omap_hsmmc.1: alias fck already exists
[ 0.903623] omap_hsmmc.2: alias fck already exists
[ 0.909587] da8xx_lcdc.0: alias fck already exists
[ 0.915193] da8xx_lcdc da8xx_lcdc.0: GLCD: Found NHD-4.3-ATXI#-T-1 panel
[ 0.933155] Console: switching to colour frame buffer device 40x30
[ 0.953420] mtdoops: mtd device (mtddev=name/number) must be supplied
[ 0.962153] usbcore: registered new interface driver zd1201
[ 0.968330] usbcore: registered new interface driver cdc_ether
[ 0.974704] usbcore: registered new interface driver cdc_eem
[ 0.980866] usbcore: registered new interface driver dm9601
[ 0.986804] cdc_ncm: 04-Aug-2011
[ 0.990416] usbcore: registered new interface driver cdc_ncm
[ 0.996396] Initializing USB Mass Storage driver...
[ 1.001823] usbcore: registered new interface driver usb-storage
[ 1.008176] USB Mass Storage support registered.
[ 1.013668] mousedev: PS/2 mouse device common for all mice
[ 1.020909] input: ti-tsc-adcc as /devices/platform/omap/tsc/input/input0
[ 1.029493] omap_rtc omap_rtc: rtc core: registered omap_rtc as rtc0
[ 1.036467] i2c /dev entries driver
[ 1.040679] Linux video capture interface: v2.00
[ 1.046188] usbcore: registered new interface driver uvcvideo
[ 1.052242] USB Video Class driver (1.1.1)
[ 1.057421] OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
[ 1.064408] cpuidle: using governor ladder
[ 1.069399] cpuidle: using governor menu
[ 1.079416] leds-gpio: probe of leds-gpio failed with error -16
[ 1.085945] omap4_aes_mod_init: loading AM33X AES driver
[ 1.091674] omap4-aes omap4-aes: AM33X AES hw accel rev: 3.02
[ 1.098648] omap4_aes_probe: probe() done
[ 1.103165] omap4_sham_mod_init: loading AM33X SHA/MD5 driver
[ 1.109375] omap4-sham omap4-sham: AM33X SHA/MD5 hw accel rev: 4.03
[ 1.129397] omap4_sham_probe: probe() done
[ 1.137055] usbcore: registered new interface driver usbhid
[ 1.142971] usbhid: USB HID core driver
[ 1.147004] oprofile: hardware counters not available
[ 1.152312] oprofile: using timer interrupt.
[ 1.156853] nf_conntrack version 0.5.0 (8024 buckets, 32096 max)
[ 1.163866] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 1.169592] TCP cubic registered
[ 1.173036] NET: Registered protocol family 17
[ 1.177771] Registering the dns_resolver key type
[ 1.182798] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
[ 1.190899] ThumbEE CPU extension supported.
[ 1.195471] mux: Failed to setup hwmod io irq -22
[ 1.201178] Power Management for AM33XX family
[ 1.206127] Trying to load am335x-pm-firmware.bin (60 secs timeout)
[ 1.212832] Copied the M3 firmware to UMEM
[ 1.218083] eCap: Disable pm_runtime_enable in Marbles!!!
[ 1.229189] clock: disabling unused clocks to save power
[ 1.251901] omap_rtc omap_rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
[ 1.261308] Waiting for root device /dev/mmcblk0p2...
[ 1.277476] mmc0: host does not support reading read-only switch. assuming write-enable.
[ 1.288185] mmc0: new high speed SDHC card at address aaaa
[ 1.294774] mmcblk0: mmc0:aaaa SU04G 3.69 GiB
[ 1.303792] mmcblk0: p1 p2 p3 p4 < p5 p6 >
[ 1.454414] kjournald starting. Commit interval 5 seconds
[ 1.461833] EXT3-fs (mmcblk0p2): using internal journal
[ 1.467375] EXT3-fs (mmcblk0p2): recovery complete
[ 1.472421] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[ 1.479727] VFS: Mounted root (ext3 filesystem) on device 179:2.
[ 1.486833] Freeing init memory: 380K
[ 1.502996] usb 1-1: new high-speed USB device number 2 using musb-hdrc
INIT: version 2.86 booting
[ 1.644452] usb 1-1: New USB device found, idVendor=0bda, idProduct=018a
[ 1.651518] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1.659055] usb 1-1: Product: 802.11n WLAN Adapter
[ 1.664112] usb 1-1: Manufacturer: Realtek
[ 1.668419] usb 1-1: SerialNumber: 00e04c000001
Please wait: booting...
Starting udev
[ 3.194223] alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.
Remounting root file system...
Caching udev devnodes
[ 3.482197] kjournald starting. Commit interval 5 seconds
[ 3.490461] EXT3-fs (mmcblk0p3): using internal journal
[ 3.495989] EXT3-fs (mmcblk0p3): recovery complete
[ 3.503091] EXT3-fs (mmcblk0p3): mounted filesystem with ordered data mode
logger: mount: special device /dev/mmcblk1p1 does not exist
logger: mount: special device /dev/mmcblk1 does not exist
[ 3.599563] kjournald starting. Commit interval 5 seconds
[ 3.606995] EXT3-fs (mmcblk0p6): using internal journal
[ 3.612495] EXT3-fs (mmcblk0p6): recovery complete
[ 3.618824] EXT3-fs (mmcblk0p6): mounted filesystem with ordered data mode
Configuring network interfaces... done.
Setting up IP spoofing protection: rp_filter.
[ 9.062379] mmcblk0: error -110 sending status command, retrying
[ 9.069644] mmcblk0: error -110 sending status command, retrying
[ 9.076061] mmcblk0: error -110 sending status command, aborting
[ 9.082756] end_request: I/O error, dev mmcblk0, sector 162283
[ 9.088903] end_request: I/O error, dev mmcblk0, sector 162291
[ 9.095038] end_request: I/O error, dev mmcblk0, sector 162299
[ 9.101170] end_request: I/O error, dev mmcblk0, sector 162307
[ 9.107302] end_request: I/O error, dev mmcblk0, sector 162315
[ 9.113436] end_request: I/O error, dev mmcblk0, sector 162323
[ 9.119569] end_request: I/O error, dev mmcblk0, sector 162331
[ 9.125703] end_request: I/O error, dev mmcblk0, sector 162339
[ 9.131836] end_request: I/O error, dev mmcblk0, sector 162347
[ 9.137970] end_request: I/O error, dev mmcblk0, sector 162355
[ 9.144103] end_request: I/O error, dev mmcblk0, sector 162363
[ 9.150235] end_request: I/O error, dev mmcblk0, sector 162371
[ 9.156368] end_request: I/O error, dev mmcblk0, sector 162379
[ 9.162501] end_request: I/O error, dev mmcblk0, sector 162387
[ 9.168633] end_request: I/O error, dev mmcblk0, sector 162395
[ 9.174766] end_request: I/O error, dev mmcblk0, sector 162403
[ 11.374906] mmcblk0: error -110 sending status command, retrying
[ 11.381260] mmcblk0: error -110 sending status command, retrying
[ 11.387736] mmcblk0: error -110 sending status command, aborting
[ 11.394208] end_request: I/O error, dev mmcblk0, sector 162411
[ 11.400349] end_request: I/O error, dev mmcblk0, sector 162419
[ 11.406484] end_request: I/O error, dev mmcblk0, sector 162427
[ 11.412617] end_request: I/O error, dev mmcblk0, sector 162435
[ 11.418749] end_request: I/O error, dev mmcblk0, sector 162443
[ 11.424882] end_request: I/O error, dev mmcblk0, sector 162451
[ 13.624093] mmcblk0: error -110 sending status command, retrying
[ 13.630438] mmcblk0: error -110 sending status command, retrying
[ 13.636799] mmcblk0: error -110 sending status command, aborting
[ 13.643119] end_request: I/O error, dev mmcblk0, sector 309019
[ 13.649269] end_request: I/O error, dev mmcblk0, sector 309021
[ 13.655409] end_request: I/O error, dev mmcblk0, sector 309023
[ 13.661547] end_request: I/O error, dev mmcblk0, sector 309025
[ 13.667685] end_request: I/O error, dev mmcblk0, sector 309027
[ 13.673822] end_request: I/O error, dev mmcblk0, sector 309029
[ 13.679960] end_request: I/O error, dev mmcblk0, sector 309031
[ 13.686098] end_request: I/O error, dev mmcblk0, sector 309033
[ 13.692235] end_request: I/O error, dev mmcblk0, sector 309035
[ 13.698372] end_request: I/O error, dev mmcblk0, sector 309037
[ 13.704509] end_request: I/O error, dev mmcblk0, sector 309039
[ 13.710644] end_request: I/O error, dev mmcblk0, sector 309041
[ 13.716781] end_request: I/O error, dev mmcblk0, sector 309043
[ 13.722917] end_request: I/O error, dev mmcblk0, sector 309045
[ 13.729052] end_request: I/O error, dev mmcblk0, sector 309047
[ 13.735187] end_request: I/O error, dev mmcblk0, sector 309049
[ 13.741324] end_request: I/O error, dev mmcblk0, sector 309051
[ 13.747460] end_request: I/O error, dev mmcblk0, sector 309053
[ 13.753596] end_request: I/O error, dev mmcblk0, sector 309055
[ 13.759731] end_request: I/O error, dev mmcblk0, sector 309057
[ 13.765867] end_request: I/O error, dev mmcblk0, sector 309059
[ 13.772002] end_request: I/O error, dev mmcblk0, sector 309061
[ 13.778138] end_request: I/O error, dev mmcblk0, sector 309063
[ 13.784272] end_request: I/O error, dev mmcblk0, sector 309065
[ 13.790408] end_request: I/O error, dev mmcblk0, sector 309067
[ 13.796542] end_request: I/O error, dev mmcblk0, sector 309069
[ 13.802677] end_request: I/O error, dev mmcblk0, sector 309071
[ 13.808812] end_request: I/O error, dev mmcblk0, sector 309073
[ 13.814947] end_request: I/O error, dev mmcblk0, sector 309075
[ 13.821081] end_request: I/O error, dev mmcblk0, sector 309077
[ 13.827216] end_request: I/O error, dev mmcblk0, sector 309079
[ 13.833350] end_request: I/O error, dev mmcblk0, sector 309081
[ 16.032877] mmcblk0: error -110 sending status command, retrying
[ 16.039358] Aborting journal on device mmcblk0p2.
[ 16.044407] mmcblk0: error -110 sending status command, retrying
[ 16.050757] mmcblk0: error -110 sending status command, aborting
[ 16.057128] end_request: I/O error, dev mmcblk0, sector 162347

  • There are several things that can cause these issues.  I've got some questions that might help narrow down the cause:

    Is this a TI EVM, or your own custom board?  If custom, verify SD card voltages.

    Will that same SD card work properly at a different time, or once you see this behavior, will it always happen?

    Can the SD card be repaired on a PC?  If it can be repaired and subsequently be reused without boot errors, it is getting corrupted, and may not be an issue with the SD card.

    How is the system shutdown?  Yanking the power versus a proper shutdown command can corrupt the SD card.

    Is the SD card from a quality vendor?  Class?  We've all tried to used poor quality cards, and it usually ends in tears.  Slow cards can also cause issues if read/ writes are not happening in a timely fashion.

    Are you using a good power supply?  

    Does this happen with your USB device removed?  

  • Hello Sir,

    After we added mdelay(10) in below function, it seems fix the problem,booting is stable, but this will cause booting time increased from 25 seconds to 55 seconds, do you have an idea what happened between TI AM3352 and My Sandisk card(class 4, 4GB)? Should we update the SD driver in Linux?

    Regards,

    Maxx 

    static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,

                                   struct mmc_card *card,

                                   int disable_multi,

                                   struct mmc_queue *mq)

    {

            u32 readcmd, writecmd;

            struct mmc_blk_request *brq = &mqrq->brq;

            struct request *req = mqrq->req;

            struct mmc_blk_data *md = mq->data;

     

      printk("neil 1\n");

      msleep(10); 

      printk("neil 2\n");

            /*

            * Reliable writes are used to implement Forced Unit Access and

            * REQ_META accesses, and are supported only on MMCs.

            *

            * XXX: this really needs a good explanation of why REQ_META

            * is treated special.

            */

            bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||

                              (req->cmd_flags & REQ_META)) &&

                    (rq_data_dir(req) == WRITE) &&

                    (md->flags & MMC_BLK_REL_WR);

     

            memset(brq, 0, sizeof(struct mmc_blk_request));

            brq->mrq.cmd = &brq->cmd;

            brq->mrq.data = &brq->data;

     

            brq->cmd.arg = blk_rq_pos(req);

            if (!mmc_card_blockaddr(card))

                    brq->cmd.arg <<= 9;

            brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

            brq->data.blksz = 512;

            brq->stop.opcode = MMC_STOP_TRANSMISSION;

            brq->stop.arg = 0;

            brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;

            brq->data.blocks = blk_rq_sectors(req);

     

            /*

            * The block layer doesn't support all sector count

            * restrictions, so we need to be prepared for too big

            * requests.

            */

            if (brq->data.blocks > card->host->max_blk_count)

                    brq->data.blocks = card->host->max_blk_count;

     

            if (brq->data.blocks > 1) {

                    /*

                    * After a read error, we redo the request one sector

                    * at a time in order to accurately determine which

                    * sectors can be read successfully.

                    */

                    if (disable_multi)

                            brq->data.blocks = 1;

     

                    /* Some controllers can't do multiblock reads due to hw bugs */

                    if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&

                        rq_data_dir(req) == READ)

                            brq->data.blocks = 1;

            }

     

            if (brq->data.blocks > 1 || do_rel_wr) {

                    /* SPI multiblock writes terminate using a special

                    * token, not a STOP_TRANSMISSION request.

                    */

                    if (!mmc_host_is_spi(card->host) ||

                        rq_data_dir(req) == READ)

                            brq->mrq.stop = &brq->stop;

                    readcmd = MMC_READ_MULTIPLE_BLOCK;

                    writecmd = MMC_WRITE_MULTIPLE_BLOCK;

            } else {

                    brq->mrq.stop = NULL;

                    readcmd = MMC_READ_SINGLE_BLOCK;

                    writecmd = MMC_WRITE_BLOCK;

            }

            if (rq_data_dir(req) == READ) {

                    brq->cmd.opcode = readcmd;

                    brq->data.flags |= MMC_DATA_READ;

            } else {

                    brq->cmd.opcode = writecmd;

                    brq->data.flags |= MMC_DATA_WRITE;

            }

     

            if (do_rel_wr)

                    mmc_apply_rel_rw(brq, card, req);

     

            /*

            * Pre-defined multi-block transfers are preferable to

            * open ended-ones (and necessary for reliable writes).

            * However, it is not sufficient to just send CMD23,

            * and avoid the final CMD12, as on an error condition

            * CMD12 (stop) needs to be sent anyway. This, coupled

            * with Auto-CMD23 enhancements provided by some

            * hosts, means that the complexity of dealing

            * with this is best left to the host. If CMD23 is

            * supported by card and host, we'll fill sbc in and let

            * the host deal with handling it correctly. This means

            * that for hosts that don't expose MMC_CAP_CMD23, no

            * change of behavior will be observed.

            *

            * N.B: Some MMC cards experience perf degradation.

            * We'll avoid using CMD23-bounded multiblock writes for

            * these, while retaining features like reliable writes.

            */

     

            if ((md->flags & MMC_BLK_CMD23) &&

                mmc_op_multi(brq->cmd.opcode) &&

                (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {

                    brq->sbc.opcode = MMC_SET_BLOCK_COUNT;

                    brq->sbc.arg = brq->data.blocks |

                            (do_rel_wr ? (1 << 31) : 0);

                    brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;

                    brq->mrq.sbc = &brq->sbc;

            }

     

            mmc_set_data_timeout(&brq->data, card);

     

            brq->data.sg = mqrq->sg;

            brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);

     

            /*

            * Adjust the sg list so it is the same size as the

            * request.

            */

            if (brq->data.blocks != blk_rq_sectors(req)) {

                    int i, data_size = brq->data.blocks << 9;

                    struct scatterlist *sg;

     

                    for_each_sg(brq->data.sg, sg, brq->data.sg_len, i) {

                            data_size -= sg->length;

                            if (data_size <= 0) {

                                    sg->length += data_size;

                                    i++;

                                    break;

                            }

                    }

                    brq->data.sg_len = i;

            }

     

            mqrq->mmc_active.mrq = &brq->mrq;

            mqrq->mmc_active.err_check = mmc_blk_err_check;

     

            mmc_queue_bounce_pre(mqrq);

    }