What is the reason of implementing this "kernel module stack" structure?
This is the way pretty much all software is written, in modular stacks. Consider your GUI: there's all the kernel space stuff involved including a driver stack, then in userspace you have the X server, and on top of that a window manager, and on top of that probably a desktop environment, and on top of that (e.g.) your browser.
That's a software stack.
The reason is fairly straightforward: consider the situation if there were no such userspace stack. Every GUI application would have to write it's own code interfacing with the kernel to access the screen, etc. Staying organized in relation to other GUI applications would be completely voluntary (read: a serious mess), the system's memory would be completely filled with redundant things, and almost no one would bother writing anything because of the immense amount of work involved.
The situation is exactly the same with same with kernel modules. A piece which can be put to more than one purpose must be an independent piece. So WRT to USB devices, rather than every driver having to build into itself a driver for the USB controller as well, you have one driver for the controller and individual device drivers interface with that.
Doesn't it just complicate the process?
No, it greatly simplifies it. True, you may have 3 modules involved instead of one, but if there were just one, it would have to implement the things the other two implement anyway.
There are many benefits to modular design and it is a fundamental tenant of software engineering. Strong modularity is essential to avoiding the sin of excessive coupling. I am sure if you ask anyone who has spent a lot of time programming that as they have gotten better at it and become more competent with larger and more complex projects, they have become more and more modular with their work -- i.e., they have grown to write smaller and more discrete pieces. This amounts to realizing that you will be better off with 3 parts instead of 1 whenever it makes sense to do so (finding "where it makes sense" is part of the skill -- the more places you can see, the better).1
If that seems counter-intuitive, consider what happens if a module,
bigfoobar, misbehaves indicating a bug. Figuring out where it is will be much simpler if it is actually composed of three smaller parts, because you can independently test
bar to determine which one is the culprit. Furthermore,
foo may have a general use elsewhere (e.g., as part of
altfoothing, but note that naming conventions don't really work that way). The more places
foo is used, the more contexts it is subjected to and the more robust (functional, efficient, bug-free) it is likely to end up.
1. The further you look into a stack the more you will recognize it is composed of a regress of other stacks on a smaller and smaller scale. 90% (don't quote me) of the userspace code your CPU executes is actually part of the native C library, which is a relatively small executable. This is part of what makes it possible to run a wide variety of complex software efficiently -- because everything is made from the same few little pieces. Think about lego and the difference between having 5 big blocks or 50 smaller ones.