nathan rutman wrote: > Right now, I've got a standalone scan utility that talks directly to the > usb device through the kernel usb scanner driver. > [ open("/dev/usb/scanner0", O_RDWR), read, write, and > ioctl(fd, SCANNER_IOCTL_CTRLMSG, &cmsg) ]
You're exactly in the same situation as I was when I began my backend for the UMAX 1220U. I too had a command line driver that operated via "ioctl" and wanted to make it into a sane backend. The short answer (which is also only my opinion, so don't think it's the only way to do it :) , is that the "pnm" backend is a really good starting point and "sanei" is preferable to other methods. But for the purposes of getting a working backend, you can use "ioctl", and only migrate to "sanei" after you have something up and running. The long answer is an description of how I did it, which may or may not be how you want to approach it. Since I wasn't the original author of the command line driver, and I knew very little about how it worked, I was quite paranoid about breaking it, so I stuck to a rather strict "refactoring" approach (http://www.refactoring.com/), which is say that I took the project in really small steps, making small changes, testing, changing some more, and repeating ad nauseum until I ended up with a SANE backend. I first split my monolithic command-line interface into two parts, one being the command-line related stuff, and the other being an intermediate scanner API that resembled, as much as possible, what SANE would expect. Then, I took the "pnm" backend and proceeded to work the other way, making it fit to my intermediate API. At this point, I had something that would work either as a command-line or as a SANE backend, which was really nice for testing. My first working driver used "ioctl" directly. Then somewhere along the line I also wrote wrapper functions that looked just like the "sanei" functions, but worked through "ioctl," "read" and "write," allowing me to run the command-line tool and certify that it worked with "sanei" style routines Doing so, and making sure nothing broke, I finally removed all the extra wrappers and ended up with what I have now. Though the process was tedious, it did allow me to have a working driver every step of the way, which is different from the approach of doing things from scratch, in which you aren't done until you're finished (did that last statement make any sense? :) Marcio Luis Teixeira