Since I expect the hpoj software will be the main (or only) user of these
ioctls, I'm currently in the process of implementing them myself, so as not
to be a burden on other kernel developers. I listed suggested ioctl names
in most cases below.
- LPIOC_GET_PROTOCOLS -- Returns a bitmask of which
printer-class alternate setting protocols are supported by the device,
and which one is currently selected (7/1/1, 7/1/2, 7/1/3, and any others
that may be added in the future).
- LPIOC_SET_PROTOCOL -- Selects a new alternate setting
protocol (7/1/1, 7/1/2, 7/1/3). If possible, the same file descriptor
should still be useable without requiring the device to be closed and
re-opened after issuing this ioctl. According to a fellow firmware
engineer at HP, there shouldn't be any problem with changing the alternate
setting any number of times after enumeration. Otherwise, at a minimum
the /dev/usb/lpX device-node assignment should not change.
Should return an error if the alternate setting couldn't be changed, for
example, because the requested alternate setting isn't supported by the
device.
This ioctl and the previous one are needed in order to get to the 7/1/3
(MLC/1284.4 packets) interface on HP OfficeJets and LaserJets. That way,
printer.c can be changed to bind to 7/1/2 (raw print data) whenever
possible in order to make the LaserJet 1200/2200 work properly,
which aren't multi-function peripherals but have 7/1/3, 7/1/2, and 7/1/1
interfaces (in that order).
Note: Incorporate as appropriate Pete Zaitcev's
proto_bias patch for RedHat 7.2.
- LPIOC_HP_SET_CHANNEL -- Issues an HP vendor-specific
CHANNEL_CHANGE_REQUEST control transaction, unless the DeskJet 8xx
"quirk" bit is set (in which case an error should be returned).
If the device STALLs (because it doesn't actually support the command),
then the STALL should be cleared and an error should be returned.
This is needed in order to get to the MLC/1284.4 functionality on
HP DeskJets (such as the 9xx and 12xx series) and PhotoSmart printers
(so I can implement photo upload on the 1000/1100/1215/1218).
CHANNEL_CHANGE_REQUEST -- Similar to ECP (parallel port) channels,
used to switch a 7/1/2 or 7/1/3 interface into a different mode:
- USB SETUP packet: C1 00 XX YY WW ZZ 01 00
- Transfer direction: device-to-host
- Request type: vendor
- Recipient: interface
- bRequest: 0x00 (CHANNEL_CHANGE_REQUEST)
- wValue: channel number (0xYYXX) (specified as the ioctl parameter)
- wIndex: targeted printer-class interface number (0xZZWW)
- wLength: 1
- The peripheral responds with an IN packet containing a single byte,
which is the requested channel number echoed back to the host.
- The following are typical channel numbers:
- 0 -- raw print data (the default for 7/1/1 and 7/1/2)
- 77 -- MLC/1284.4 packets (the default for 7/1/3)
- 78 -- MLC/1284.4 reset channel (a null byte is subsequently sent on the
bulk-OUT endpoint to reset the peripheral's MLC/1284.4 protocol stack)
- LPIOC_GET_BUS_ADDRESS -- Returns the USB bus and device
numbers assigned to this device, similar to the T: line in
/proc/bus/usb/devices.
Note: If all of the other high- and medium-priority requested
additions are already possible via /proc/bus/usb/devices and/or
usbdevfs, even after printer.c has already bound to the
device, then it is probably acceptable to only implement this ioctl.
However, it has been my experience that usbdevfs disallows
control transactions to devices to which printer.c has already
bound (at least when using
Adam Richter's usb-printer-id utility).
- LPIOC_GET_VENDOR_ID, LPIOC_GET_PRODUCT_ID --
Return the device's vendor and product IDs, respectively, similar to the
P: line from /proc/bus/usb/devices.
Could also be combined into a single ioctl, such as LPIOC_GET_VID_PID.