July 1, 2021

Parallel port matrix printer printing garbage on Ubuntu 20.04 Focal

As usual, Linux needs a bit of under-the-hood wrenching to get things working. Exploring print issues with a vintage parallel-port matrix printer (a Panasonic 24-pin).

Dot-matrix printing was the most affordable printing technology of the 1990s, so I have a fond memory of these noisy and slow machines. Recently I acquired an old Panasonic printer and wanted to test it out on a modern (Ubuntu 20.04 Focal) setup, but there were a few snags.

For one, the preferred interface of the time was a “Centronics” parallel port. Industrial usage excepted, modern computers don’t have these ports anymore. I tried a cheap Amazon USB-to-parallel converter first, but it didn’t work on any combination of operating system and device I have, so back to Amazon it went.

The next attempt was on an old desktop running Linux. I have a Dell Optiplex 755, a teenage years old system that I use to run my print server and for a few other light duties at home. Thankfully, it does have a parallel port. So I plugged the printer in, set up a CUPS driver, and tried to get a test page out… and got garbage – some characters, bell noises (beeps), and ejected pages.

To troubleshoot that, my first thought was to drop into text mode. All printers use a language to describe what it is that we want printed; printing complex shapes and graphics takes a lot of data, and if there is any hardware or software issue, garbage is the result as the language becomes undecipherable. But all old printers also support minimally formatted, terminal style output. It is produced by simply pushing a text file out into the port, as is: copy foo.txt lpt1:

There was clearly some corruption going on: most of the output is fine, but part of the output goes missing and damaged. The output is still kind-of-readable, but it makes sense that graphical output would be botched since, unlike humans, printers are not very good at dealing with missing or damaged data.

It could have been a hardware issue–this was, after all, an ancient printer. But I did a quick search of the symptoms, and an interesting Ubuntu bug from 2012 popped up, together with a related kernel bug from 2016 that didn’t get any response.

To understand these bugs, a bit of history is in order. Printing text, as matrix printers originally did, wasn’t a hard job even for 1950’s computers: at speeds of perhaps one line a second (80 characters), sending the data out bit by bit or a byte at a time was not a big deal. However, by the 1990s, the parallel port was getting a lot more use: graphical printers, scanners, and data storage devices like the Zip drive were much more data intensive.

The old method of interrupting the computer (the CPU) every time the device is ready to receive more data didn’t work anymore: a 8 MHz CPU could deal with a few hundred characters per second, but trying to handle a million a second made it choke up. So the parallel interface was redesigned to access memory directly, without CPU’s involvement. This was called DMA (Direct Memory Access), and the new parallel port implementation supporting it was named ECP (Extended Capability Port).

However, when DMA was introduced to PCs, there were only 4 devices that could use it at the same time, and plenty of devices wanted to leverage its performance: the computer’s own memory refresh logic, sound cards, floppy disk drives, hard drives, printers, and other peripherals. It was a precious resource, so it was user configurable: a device (such as a printer port) could be configured to use or not to use a DMA “channel”, and could be told which channel to use.

That’s the reason why, in my Dell Optiplex 755 and in many other devices, computer (BIOS) settings include various parallel port options (IBM’s oldest implementation of parallel port for PCs, or ECP, or EPP – another in-between standard) and manual assignment of DMA channels as needed. And, in my 755, the default setting for the printer port was the most compatible, the oldest non-DMA implementation.

Here’s where the bug comes in. It appears that either Ubuntu’s configuration of the parallel port assumes that DMA is always on, or that the parallel port driver has a bug that uses DMA even though it is not detected. This is confirmed by this dmesg output during boot, which I saw on my machine as well:

[ 21.205380] parport0: PC-style at 0x278 (0x678), irq 5, using FIFO [PCSPP,TRISTATE,COMPAT,ECP]

ECP implies DMA, which was not turned on. This is why some of the data was being lost; once I changed the parallel port setting in the BIOS to ECP (which enabled DMA), the output became perfect.

Then I went back to trying to get graphical output (a 24-pin printer should be able to produce very nice black-and-white graphics), but the adventures of CUPS drivers for old 24-bit matrix printers are worth a separate post.