OpenWrt Forum Archive

Topic: Optimized version of mmc.c

The content of this topic has been archived between 5 Jun 2014 and 7 Mar 2018. Unfortunately there are posts – most likely complete pages – missing.

Cyril wrote:

Look twice.

SD_DI is sent. That means data input bit is 1.
8 times => data is 0xFF.

If you're interested in MMC protocol : http://elm-chan.org/docs/mmc/mmc_e.html .

thanks for clerifying that smile

And to answer differently : there are many cases in the MMC protocol where you just have to cycle the clock :
- to read data
- when the MMC is in busy state
- when your are waiting for it to respond to a command.
- while initing it.
- ...

in which case you'd expect a test (and/)or action to be preformed every clock cycle.. I didn't notice that you were just sending the same data 8 times

kevin wrote:

in which case you'd expect a test (and/)or action to be preformed every clock cycle.. I didn't notice that you were just sending the same data 8 times

Is it a question ?

Kevin, if you want me to explain some parts of the code, can you do it by PM ? And please, be more precise ! smile

Will you try to code some addons (like buffering) or is this only curiosity ? In that last case, sorry but i don't have that time.

it wasn't a question, no.  if I do any coding it will be porting the driver to 2.6 and to different hardware, not optimization immediately, but right now i'm just reading up on mmc/ linux driver development and looking for other people to do it smile

For nicefile (and others) about 4GB support :

I thought that 2GB limit was due to the SPI protocol but in fact it is not.
SPI seems limited to 4GB (unsigned 32bit int).

Though it is a software limit and i may have found the problem in the code.
One address conversion in the code is calculated from signed integers then the result may be a signed int even if the result is stored in an unsigned int.

I have corrected this line but i don't know if 4GB now work as i don't have that a huge card.

Can someone try it ? PM me.

I shouldn't have to mention this considering the context of all this discussion is gpl released code from linksys, fon, etc, but you should, and must, release the source code for any gpled binaries you release.  sorry to bring it up like this, but this is one of those things that really gets under my skin.  if your worried about keeping the  official source.. copy paste.. stable, I recommend you put the .c files on a web server with version codes.  would help for looking through the changes made too.

I remember someone before worked out a fix for 4gb spi support, but lost the code (and binaries, for that matter), in a hard drive crash. glad to see it working, maybe, again smile

(Last edited by Kevin on 8 Mar 2007, 18:58)

Kevin,

thanks for this comment but what i do here is experimental.
1.2 is stable and is released.

For the rest, i don't have time to make a cvs env.

Maybe in the near future.

And any help is apprecieted.
Please don't give me advices like that in the near future. If GPL is under your skin; contribute and don't talk too much. Thanks.

i'd be glad to set up a web server or cvs repository if you need one, but that's not really the issue.
In this case, it's the LAW. I don't see any reason to ignore it, either. you'd get more testing if you just put up a .c file. I personally have been just copying the source from your first post every time I wanted to play with it, and have completely ignored the binaries.  as I said, I hate to bring it up like this, as the most likely result is driving people away, but it really shouldn't be happening.
i'll contribute once i'm finished reading my book on the subject, thanks smile (really)

I'm excited at the improved speed! Is there going to be a version for the buffalo routers? Can someone post a link to it? The gpio pins are

GPIO3 SD_CLK
GPIO6 DO
GPIO7 SD_CS
GPIO5 DI

Thank you! smile

Hi everybody!

Is there an MMC/SD card compatibility list for the MMC gpio mod?

I soldered yesterday a card, but it didnt responded to anything. I measured voltage and 3.3V was at the VDD contact of the MMC Card ( used an 1GB MMC plus Extremmemory card).

While try to load the driver dmesg/logread shows this:

mmc Hardware init
[INFO] mmc_card_init: powering card on. sending 80 CLK
[INFO] mmc_card_init: resetting card (CMD0)
[FATAL] mmc_card_init: invalid response from card: ff found, waiting for 01
[INFO] mmc_card_init: powering card on. sending 80 CLK
[INFO] mmc_card_init: resetting card (CMD0)
[FATAL] mmc_card_init: invalid response from card: ff found, waiting for 01
mmc: error in mmc_card_init (1)
mmc: error in mmc_init (-1)

Funny thing is....this comes up with and without card soldered...so no change at all!

I'm using 1.3.1 driver with whiterussian RC6. Also tried different values for mp_max_init_tries .. but no change.

I've got an WRT54G V. 2.0 and did the mod @ http://kiel.kool.dk/

I don't know what might be wrong there...except that maybe the card is just not comaptible.... so please post which card worked for you or not!

Maybe we should start an new thread for this...


Freezer

(Last edited by freezer2k on 15 Mar 2007, 16:05)

Hello.

Sorry for the long time without news but holidays are finished for me smile
I am now at work for 14 hours a day ... pfff


I am currently testing some other ways to speed things up. Maybe you will get news soon ... and sources for 1.3.2 on a fresh CVS server.


lemonteh wrote:

I'm excited at the improved speed! Is there going to be a version for the buffalo routers? Can someone post a link to it? The gpio pins are

GPIO3 SD_CLK
GPIO6 DO
GPIO7 SD_CS
GPIO5 DI

I will do it this evening and will post the binary.

freezer2k wrote:

I've got an WRT54G V. 2.0 and did the mod @ http://kiel.kool.dk/
I don't know what might be wrong there...except that maybe the card is just not comaptible.... so please post which card worked for you or not!
Maybe we should start an new thread for this...

insmod mmc.o mp_max_init_tries=30000 will not work for you.
For it to work, you need a message like : card not initialized after xxxxx tries.

What I can tell you is that you need the GPIO5 binary and double check your solder points.

I think that ANY card is compatible with this first phase of Initialization that blocks you (At protocol level I mean).
Maybe GPIO's voltage are not enough.
Maybe 80 CLK is not enough.
Or maybe the clock frequency is too fast for the card.
I can try to export a new parameter to alter this number ?

I will do it this evening.

Can you give me the reference of this SD ?

(Last edited by Cyril on 15 Mar 2007, 18:05)

Hi,

Yes i tested it with the GPIO5 Version.

I didn't found a real datasheet for this card, but if you look here:

http://www.extrememory.com/index.cfm?lc=products&nc=pmenue&pageID=6

Its the second card (1GB version) "MMC plus PREMIUM"

Also: http://kiel.kool.dk/pics/solderpoint_1_annotated.jpg

Is it correct that the DI-connect has to be soldered behind the RP3 IC, in front of the ADM chip? Because the three red lines are all pointing to the front pins of RP3.. and two of three wires are also connected to the front pins. I soldered it like it is to see on the picture: DI behind the RP3 and the two other wires in front of... is this correct?

Greetings,
Freezer

(Last edited by freezer2k on 15 Mar 2007, 19:58)

Hi.

for buffalos, I have posted a binary on heading post.

freezer2k :
try to play with mp_max_pwr_on_clocks . Do go to high. 200 must be enough.
If it don't work, report me, i will search for other hypothesis.
I will look anyway to your docs and questions for tomorrow.

Cyril

hi cyrill !

good work, with your mmc-mod driver i have less problems with root on the mmc card.
I used the How-To from the USBStorageHowTo in the Wiki.
My device is an WRT54GS v1.0 GS.

Some things mention:
a) I have to configure the switch before loading the the mmc.o an mounting the fs on the SD card as root. Reading from the device is not possible afterwards anymore, with a bunch of kernel messages on tts/0. Sounds clear to me because of using the GPIOs to program the switch are used for the mmc-mod, too.
I suggest trying to re-init the card after some reading problems.

b) I can cause kernel oopses with sometime hanging router, when I do the steps in sequence
1) insmod mmc.o with card inserted
2) using SD card (fdisk or mount)
3) unmounting and unloading mmc.o
4) insmod mmc.o with card inserted
- now defvs complains that some device nodes those already exist
5) using SD card with user space program like fdisk, e2fsck or mke2fs no matter using part1 or disc device node.

I can reproduce that with 1.2, 1.3.1, 1.3.2

c) after using mmc.o (1.2, 1.3.1, 1.3.2) and soft rebooting the router boots auto-magically in failsafe.
I have no guess why. can you give me a hint ?

danke and cya

abraXxl wrote:

Some things mention:
a) I have to configure the switch before loading the the mmc.o an mounting the fs on the SD card as root. Reading from the device is not possible afterwards anymore, with a bunch of kernel messages on tts/0. Sounds clear to me because of using the GPIOs to program the switch are used for the mmc-mod, too.
I suggest trying to re-init the card after some reading problems.

OK. In the TODO list

abraXxl wrote:

b) I can cause kernel oopses with sometime hanging router, when I do the steps in sequence
1) insmod mmc.o with card inserted
2) using SD card (fdisk or mount)
3) unmounting and unloading mmc.o
4) insmod mmc.o with card inserted
- now defvs complains that some device nodes those already exist
5) using SD card with user space program like fdisk, e2fsck or mke2fs no matter using part1 or disc device node.

idem


abraXxl wrote:

c) after using mmc.o (1.2, 1.3.1, 1.3.2) and soft rebooting the router boots auto-magically in failsafe.
I have no guess why. can you give me a hint ?

i don't know. Is 1.3.3 correcting things ?


for freezer2k and MMC owners:
I have read in specification that initialization phase must be done with a clock of 400Khz max for MMC compatibility.
Sure it is a blocking problem. 400Khz max frequency is in TODO list for next version. (Out in a few hours/days)
freezer2k : have you checked your soldering ? Is it working now ? Or are you still waiting for a fix ?


Cyril

Hi,

After finding out the gpio points for my WRT54G *v1.0* I have been trying to use mmc.o with no luck:

(whiterussian 0.9 - clean flash)
root@OpenWrt:/# insmod ./mmc.o
Using ./mmc.o
Segmentation fault

Dump:


mmc Hardware init
Data bus error, epc == c00b0f18, ra == c00b0f0c
Oops in traps.c::do_be, line 385:
$0 : 00000000 1000fc00 b8000060 c00b0000 b8000068 00000000 0000001f 8037a420
$8 : 00000000 00001890 00001890 0000187b 801a0000 801a0000 801a0000 00000001
$16: 00000000 80013514 100df418 80010000 00000060 c00b0000 c00b0000 100dde68
$24: ba2e8ba3 801a95d4                   80eb0000 80eb1e30 00000007 c00b0f0c
Hi : 00000000
Lo : 000005a0
epc   : c00b0f18    Tainted: P
Status: 1000fc03
Cause : 0000001c
PrId  : 00024000
Process insmod (pid: 604, stackpage=80eb0000)
Stack:    100df418 00000001 801e0000 1000fc01 000de000 0000001a 8002c4bc
8002c3a0 1000fc01 c00b0000 100df418 ffffffea 00000060 809c6b60 00000007
c00b0000 100df418 ffffffea 00000060 809c6b60 80957000 100dde68 80014978
80014898 80239800 000001f2 000007df 00000002 00000060 c00e3000 c00b0060
00001e48 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 ...
Call Trace:   [<8002c4bc>] [<8002c3a0>] [<80014978>] [<80014898>] [<c00b0060>]
[<80008a00>] [<8005bdac>]

Code: 3c03c00b  8c641604  3c03c00b <8c820000> 344200a8  304200ef  ac820000  8c641600  3c02c00b

Apparently this is due to some gpio structure diference for v1.0 than other versions,  as mbm and nbd pointed out. They suggested that, since diag correctly manages gpios in this model from diag.c could be seen what needed to be changed in mmc. But my knowledge of C is very limited.

The only thing i could figure out is that, this is the difference in the structure:

<<from diag.c>>
[WRT54GV1] = {
118                     .name           = "Linksys WRT54G V1.x",
119                     .buttons        = {
120                             { .name = "reset",      .gpio = 1 << 6 },
121                     },
122                     .leds           = {
123                             { .name = "diag",       .gpio = 0x13 | GPIO_TYPE_EXTIF, .polarity = NORMAL },
124                             { .name = "dmz",        .gpio = 0x12 | GPIO_TYPE_EXTIF, .polarity = NORMAL },
125                     },
126             },
127             [WRT54G] = {
128                     .name           = "Linksys WRT54G/GS/GL",
129                     .buttons        = {
130                             { .name = "reset",      .gpio = 1 << 6 },
131                             { .name = "ses",        .gpio = 1 << 4 },
132                     },
133                     .leds           = {
134                             { .name = "power",      .gpio = 1 << 1, .polarity = NORMAL },
135                             { .name = "dmz",        .gpio = 1 << 7, .polarity = REVERSE },
136                             { .name = "ses_white",  .gpio = 1 << 2, .polarity = REVERSE },
137                             { .name = "ses_orange", .gpio = 1 << 3, .polarity = REVERSE },
138                             { .name = "wlan",       .gpio = 1 << 0, .polarity = REVERSE },
139                     },
140             },

<<from diag.h>>
107     #define GPIO_TYPE_NORMAL        (0x0 << 24)
108     #define GPIO_TYPE_EXTIF         (0x1 << 24)

So I though that if GPIO 7 was being hadled in such a different way, and I had another two extra gpios to use, it would be just easier to swap GPIO 7 for GPIO 6 and forget about the "different" gpio... So i changed it like:

#define SD_DI 0x20
#define SD_DO 0x10
#define SD_CLK 0x08
#define SD_CS 0x40         <- I changed gpio 7 for gpio 6 which is available on my board (and also gpio 1 - no serial in this model)
with a gpiomask of 0x5c .....

No luck, once again it seg faults... Probably I just dont understant it and what I am trying doesnt make sense...

Cyril perhaps could you fix it to work with V1.0?

I don't know what else to do.

I would supposse that it should work just not using gpio 7 because, also when using the gpio utility for locating the gpio points all were correctly located and operating except gpio 7 and gpio 0, even though writing to /proc/diag/led/DMZ or DIAG would correctly change the led. (but no action using gpio utility).

I hope something of this makes any sense to anyone and comes a fix. Thanks for the great work!

P.D.: The same problem happens with V1.1. Another guy (_trine) also figured the gpio points for that board but mmc behaviour is the same as in v1.0.

Hello.

I've released a new version (v1.3.4) with these changes :
* MMC init backward compatibility added (frequency limited to 380KHz)
* MMC CID register parsing. It now shows product serial number, product manufacturer, product name, product version, and product release date in the dmesg.

shadsec : don't know WRT54G v1. problem. Do you have links to posts/info that I can read ?

Hi Cyril!

There's no info on SD mod for the v1.x, thats why we had to find where the gpios where for v1.0 and v1.1 boards. Using the gpio utility we found gpios # 1, 2, 3, 4, 5 and 6, all available to use for anything. GPIO 7 and GPIO 0 (if that is diag led) are also probably available because, though unable to find it using gpio utility, the leds get lit by diag when "echo "1" > /prov/diag/leds/DMZ'.

The reason why we couldn't make it lit using gpio utility perhaps it is the same as mmc not working... probably both gpio utility and mmc try to "control" it the same way as for v2.0+ WRT's. Diag works on them because it uses a different structure for WRTGV1 (see my previous post).

I woulnt mind using different gpios for the SD mod, as many are available and already located on this version (it has no serial so I guess that freeds more), but I tried changing the source to use others, recompiled, and still segmentation fault.

My understanding is that it was never before tried to use mmc on a WRT54g v1.x, or at least I was unable to find any info on it. The good thing is that diag.c knows how to "work" gpios on this model and it would be a good reference.

From what I can see, It seems that the polarity is reversed for GPIO7 and also does an EXTIF call that seems to mask the bits differently. Also, other GPIO's are not defined since they are available but not USED on this model. Perhaps it would be needed to define them before loading mmc module? Please forgive my lack of knowledge about this but I know very little C and have tried all I can do.

It would be great if you could take a look at that difference in diag.c /diag.h and make a fix for V1.x.

Again, thanks for the good work!

Hi shadsec

shadsec wrote:

Hi Cyril!
It would be great if you could take a look at that difference in diag.c /diag.h and make a fix for V1.x.

Thanks for your advice. I have read the code.
It works the same way than the gpio utility : it uses broadcom closed (or i haven't found the source code in the kernel) sb_gpio* functions.
The only difference is what you have spotted out : GPIOs bits outputted to gpio register are different.

The problem with this mmc driver is that we don't use sb_gpio* broadcom functions because they are too slow.
We are using a hard coded set of addresses instead : 0xb8000060, 0xb8000064, 0xb8000068 to read and write from/to GPIOs.
You got a kernel oops (Segmentation fault) because your router is trying to use an address that doesn't exist :
$0 : 00000000 1000fc00 b8000060 c00b0000 b8000068 00000000 0000001f 8037a420

I don't know where in the address space we have to read/write for your version.
Maybe someone can try do disassemble/reverse closed broadcom binary to find this out.

mbm ?

[edit]
Oops: i have found the source of what i called closed gpio functions. Arf.
It is in drivers/net/hnd/sbutils.c !
I am looking at it.

(Last edited by Cyril on 25 Mar 2007, 11:52)

shadsec wrote:

Hi Cyril!

It would be great if you could take a look at that difference in diag.c /diag.h and make a fix for V1.x.

hi shadsec. i've modified the original mmc driver to support 4702 units (linksys v1 and many baffulo units).
i believe you can find the source in this forum. and yes, it's slower than the unmodified one, but the best thing is, it realy works.
the source code is here:
http://forum.openwrt.org/viewtopic.php?id=7081

(Last edited by jnjn on 25 Mar 2007, 12:15)

Cyril wrote:
abraXxl wrote:

b) I can cause kernel oopses with sometime hanging router, when I do the steps in sequence
1) insmod mmc.o with card inserted
2) using SD card (fdisk or mount)
3) unmounting and unloading mmc.o
4) insmod mmc.o with card inserted
- now defvs complains that some device nodes those already exist
5) using SD card with user space program like fdisk, e2fsck or mke2fs no matter using part1 or disc device node.

I can't reproduce it for 1.3.3. But i notice that in /dev/mmc/ the number of discX is increasing each time when i reload (unload then load) the module. I can only use disc0 directory.
When i use fdisk or busybox mount on discX (X>0) they say "no such file or directory".

Cyril wrote:
abraXxl wrote:

c) after using mmc.o (1.2, 1.3.1, 1.3.2) and soft rebooting the router boots auto-magically in failsafe.
I have no guess why. can you give me a hint ?

i don't know. Is 1.3.3 correcting things ?

Regarding issue c) I read a bit in /etc/preinit to understand, when OpenWrt should go in safe mode.
It is a trick with hotplug.
While in preinit hotplug events are sent to /sbin/hotplug.failsafe, which sends on button events SIGUSR1 to 1 (/etc/preinit).
Setting FAILSAFE=yes in failsafe via trap. So that eval ${FAILSAFE:+failsafe} executes the failsafe function.
For some case the mmc mod still sends hotplug events after reboot.

Is it because SD-Card is still active and the gpiomask is reset after reboot ?
Are the hotplug events the answers of the card to switch configuration in /etc/preinit ?
Some other suggestions ?

Is it possible to trap reboot in module ? To do one of the following: let the SD card sleep and/or reset the gpio pins to boot up settings ?

cya

(Last edited by abra on 25 Mar 2007, 12:25)

abraXxl wrote:

Is it because SD-Card is still active and the gpiomask is reset after reboot ?
Are the hotplug events the answers of the card to switch configuration in /etc/preinit ?
Some other suggestions ?

Thanks for all your technical info. Maybe it will help someone (maybe me ?) to find a solution to your problem.

I am very happy with this entire topic because I am sure there is still a lot to do with this driver :
* better compatibility
* better stability
* maybe some performance improvements.

The real problem is allways the same ... TIME ! I have tried to look at some stuff (WRT54G v1 compatibility) this week end
and it is already finished ...

About performance subject :
* WRT54G v1 uses EXTIF (external interface) to control GPIOs. I don't know how EXTIF performs in read/write speed. I will test and I will certainly post a version for this router this week.
* others use I think PCI (via a SOC Core called ChipCommon). Thats why clock frequency is limited to 16MHz (33MHz/2) at burst speed (in real world it is less than 10MHz because the CPU must do some calculations : arithmetic OR / AND ...).

- Maybe EXTIF is faster than PCI so I will definitely look at it...
- There is maybe a way to use GPIOs using DMA interface so that CPU is not involved in transfers ? Does someone have an idea about this subject ?

See ya

Hi Cyril!

Cyril wrote:

* WRT54G v1 uses EXTIF (external interface) to control GPIOs. I don't know how EXTIF performs in read/write speed. I will test and I will certainly post a version for this router this week.
- Maybe EXTIF is faster than PCI so I will definitely look at it...

Glad to hear that! Even if it isn't as fast as the other way it will be great to have mmc support for V1.x

I have everything ready to test it as soon as you have the code smile

Thanks again

Hi jnjn!

jnjn wrote:

hi shadsec. i've modified the original mmc driver to support 4702 units (linksys v1 and many baffulo units).
i believe you can find the source in this forum. and yes, it's slower than the unmodified one, but the best thing is, it realy works.
the source code is here:
http://forum.openwrt.org/viewtopic.php?id=7081

I am not sure if it works for me... After changing the paths in Makefile I made it to compile (not without a big bunch of warnings) and tried it.

The good thing is that it loaded smoothly, but:

mmc_driver_init: devfs_register_blkdev start
mmc_driver_init: devfs_register_blkdev finished, major_nr=121, rc=0
mmc_driver_init: blk_init_queue started
mmc_driver_init: blk_init_queue finished
mmc_driver_init: add_gendisk finished
mmc_driver_init: mmc_check_media start
mmc_check_media: old_state=mmc_media_detect=0
mmc_check_media: mmc_init start
mmc_init: mmc_hardware_init start
mmc Hardware init
rc=0
mmc_hardware_init: gpio_outen_jnjn = 45. finished
2_port_state_jnjn=245
//set di/clk/cs to low state finished.
3_port_state_jnjn=209
mmc Card init
4_port_state_jnjn=241
5_port_state_jnjn=213
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
mmc Card init
4_port_state_jnjn=245
5_port_state_jnjn=213
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
r = mmc_spi_io(0xff) = 255
mmc: error in mmc_card_init (1)
mmc: error in mmc_init (-1)
mmc_driver_init: mmc_check_media exit

It says the same either if I have an SD card in the socket or not.

To make sure it wasnt my fault, I swapped gpios in my wiring and also in the source. Again the same result, except for a change in:

[original]
mmc_hardware_init: gpio_outen_jnjn = 1. finished
2_port_state_jnjn=209
//set di/clk/cs to low state finished.
3_port_state_jnjn=209
mmc Card init
4_port_state_jnjn=241
5_port_state_jnjn=213

[Other gpios]
mmc_hardware_init: gpio_outen_jnjn = 45. finished
2_port_state_jnjn=245
//set di/clk/cs to low state finished.
3_port_state_jnjn=85
mmc Card init
4_port_state_jnjn=213
5_port_state_jnjn=117

I think I didnt make any mistake in the wiring, but as it is untested I can't be positively sure. If you tell me this code should work for WRT54G V1.0 I will try again from scratch... Or perhaps from the output you can tell me what may be?

Thanks!

shadsec :

Hello. I got news for you.

But before:
Please don't send output of another mmc driver version here as the post is only for the optimized version.  It confuses users.
You can post in the old jnjn post or try to call him in a private way. Thanks in advance.

For the news:
Here is the source of a 1.3.5 version that searches at runtime for GPIO addresses specific to each router.
Would you please test it and report me if it crashes like the 1.3.4 ?
If not, please output the dmesg and I will finalize the version for tomorrow.
source of 1.3.5 work

Cyril

(Last edited by Cyril on 26 Mar 2007, 21:14)