The easiest (but least useful) way to block a client's system call is simply to block the driver, too. For example, consider Program 10, which implements a device called /dev/console-read. Whenever a process tries to read from this device, the driver prints a prompt to standard input, asking for a reply. (The prompt appears in the shell the driver was run in, not the shell that's trying to read from the device.) When the user enters a line of text, the response is returned to the client that did the original read(). By blocking the driver waiting for the reply, the client that issued the system call is blocked as well.
Blocking the driver this way is safe--unlike programming in the kernel proper, where doing something like this would block the entire system. It's also easy to implement, as seen from the example above. However, it makes the driver unresponsive to system call requests that might be coming from other clients. If another process tries to do anything at all with a blocked driver's device--even an open()--it will block until the driver wakes up again. This limitation makes blocking drivers inappropriate for any device driver that expects to service more than one client at a time.