Peripherals & Printing

Revised: 2014-01-27 richard

Class Videos

March 14, 2008 (CUPS only, no video for peripherals)

October 10th, 2008 (CUPS and peripherals)

Class Notes from March (7th?) 2008

Peripherals

------

USB 1.0/1.1 12 Mbit/s
USB 2.0 480 Mbit/s
Firewire 400 Mbit/s DMA
Firewire 2 800 Mbit/s DMA

USB 1 connected to a USB 2 bus forces the bus to 12 Mbit/s

USB is 5 volts and .5 amps
Scanners and hard drives will need to be plugged directly into the computer.  I've seen flash drives freeze the computer when plugged into the keyboard.

Power and driver are the most common problems.

------

FireWire is 30 volts and 1.5 amps
4-pin firewire ports do not have power

FireWire uses direct memory access (DMA).

http://en.wikipedia.org/wiki/Direct_memory_access
Direct memory access (DMA) is a feature of modern computers that allows certain hardware subsystems within the computer to access system memory for reading and/or writing independently of the central processing unit. Many hardware systems use DMA including disk drive controllers, graphics cards, network cards, and sound cards. Computers that have DMA channels can transfer data to and from devices with much less CPU overhead than computers without a DMA channel.

Without DMA, using programmed input/output (PIO) mode, the CPU is typically fully occupied for the entire duration of the read or write operation and is thus unavailable to perform other work. With DMA, the CPU would initiate the transfer, do other operations while the transfer is in progress, and receive an interrupt from the DMA controller once the operation has been done. This is especially useful in real-time computing applications where not stalling behind concurrent operations is critical.


This is why FireWire can bypass full disk encryption, it has DMA meaning it can read the decryption keys in RAM.  However, it appears FireWire DMA is disabled if you turn on full disk encryption.  And don't forget the security principle: "physical access to the hardware equals 0wned machine".

DMA is also part of the reason TDM is possible.  TDM is not possible with USB.

------

Letter soup: PCI, PCI-X, AGP, PCMCIA, ATA, SATA, SCSI

I have nothing to say about these except they exist.

------

IOKit.

The I/O Kit is an object-oriented device driver framework that is a descendent from NEXTSTEP.  It is radically different from other systems and as such vendors may not want to write Mac OS X drivers.  However, it is actually pretty easy to write drivers compared to the other systems (easy if you know how to write drivers).

The I/O Kit is part of the kernel.  I'm pretty sure that means the actual code is in /mach_kernel.  There is also a user-space framework at /System/Library/Frameworks/IOKit.framework.  Privilege separation applies very much between user-space and the kernel (which talks to hardware), so user-space processes can't probe the hardware directly, but must talk to hardware through the I/O Kit framework functions.

A big feature of the I/O Kit is that most of the code is already written.  A driver writer pretty much just says the following.  "My device is (USB, FireWire, ATA, etc) and it is a (storage device, human interface device, printer, scanner, etc).  After you, the I/O Kit, load it, you need to do A, B, and C.  And when the user pulls disconnects it, you need to do X, Y, and Z."

Every driver has 2 families associated with it: the bus and the function.  Examples of busses include ADB, ATA, ATAPI, Network, PC Card, PCI, AGP, Serial, SCSI, USB, FireWire.  Examples of function include human interface device (mouse, keyboard, tablet, etc), printer, scanner, camera,

Devices that follow well-defined and well-supported specifications like many mice and keyboards don't even need drivers because the built drivers in pretty much do everything for them.  Or they may only require a user-space driver, rather than a kernel extension.  That doesn't mean you wont find a renegade mouse that requires a driver though.

The I/O Catalog is a database of all I/O Kit classes.  It is basically the contents of /System/Library/Extensions/.  There also  may be drivers compiled into the kernel (I'm just guessing on this one).

The I/O Registry is a database containing detailed info of all loaded drivers.  The registry is a tree like database.

The database can be viewed over several "planes": power, device, service, USB, and FireWire planes.  Basically, if you want to see the power tree, you look at that plane.  Or if you want to see the USB tree, you look at that plane.  The device tree shows the open firmware tree.  The service tree shows all objects.

Platform Expert - Basically the driver for the motherboard.  It is the root of the service tree.

Plug and play (driver matching).  When a device is plugged in, the system consults the I/O Catalog.  Each driver has a personality, basically a list of what it can do and what it can't.  The drivers that come the closest to describing the device are then probed and they say if they can control the device.  This is why so many devices don't require drivers.  The built in drivers can control them.

------

System Profiler "Hardware" and "Extensions"
ioreg -l -w 0 (will show details, including temps)
iostat
kextstat
kextload
kextunload
/usr/libexec/kextd

system_profiler

/Developer/Applications/Utilities/IORegistryExplorer.app
/Developer/Applications/Utilities/USB Prober.app

Mr Registry.app (part of FireWire SDK)

sysctl
pmset
hostinfo
uname -a

------

Looking for devices

ioreg -c "IOMedia"
ioreg -l | more
ioreg -c "IOMedia" | more
ioreg -c "ATADeviceNum"

Finding idle time:

ioreg -c IOHIDSystem | perl -ane 'if(/Idle/) {$idle=(pop @F)/1000000000; print $idle, " "; last;}'

Battery stats:

ioreg -l | grep Capacity

/usr/sbin/ioreg -p IODeviceTree -n "battery" -w 0

------

Possible drivers:

http://www.kernelthread.com/mac/apme/syscall/
http://www.obdev.at/developers/articles/00001.html
http://chanson.livejournal.com/tag/iokit

--------

iSync

Class Notes from March 14, 2008


CUPS

Owned by Apple now!

---

/var/log/cups/

---

PPD files:

/Library/Printers/PPDs/Contents/Resources/en.lproj (gzippped files)
/usr/share/cups/model

(gimp)
/usr/share/cups/model/C

---

To find out what printers you have setup, look at

lpstat -p

or

/etc/cups/printers.conf

---

To find out what options the printers have, compare

/etc/cups/ppd/yourprinter

with

/Library/Printers/PPDs/Contents/Resources/en.lproj/printermodel

---

IPP is an extension of HTTP.  LPD (Line Printer Daemon) was made for simple text printers (line printers) which had no or very few options.

---

More Printers button - AppleTalk, Bluetooth, Windows (SMB) Printing.

---

Sharing printers - SMB sharing requires Windows File Sharing

If you turn on printer sharing, then anyone can open a web browser to x.x.x.x:631.  However, all admin options are 403 Forbidden (the /etc/cups/cupsd.conf file is modified and is the source of the acl's).

http://127.0.0.1:631/

---

CUPS supports printer classes. Classes are queues with multiple printers for printer load balancing.

---

Adding printers

lpadmin -p Printer_Name -L "Printer Location" -E -v lpd://x.x.x.x -P /Library/Printers/PPDs/Contents/Resources/en.lproj/Printer_Driver.gz

---

Clearing jobs (good to run at login or logout maybe)

#!/bin/bash

lpstat -p | awk '{print $2}' | while read printer
do
  echo "Clearing Queue for Printer:" $printer
  lprm - -P $printer
done

or

rm -fr /var/spool/cups
mkdir /var/spool/cups
mkdir /var/spool/cups/tmp
chmod 710 /var/spool/cups
chmod 1770 /var/spool/cups/tmp
chown -R root:lp /var/spool/cups
killall -HUP cupsd

---

#!/bin/bash

# Tests to see if printer exists - sidesteps a variable scope issue
# Requires the printer name as a parameter.  Returns 1 if the printer exists.
function printerExists()
{
  if [ $# -ne 1 ]; then
    echo "Incorrect parameters"
    return 0
  else
    lpstat -p | awk '{print $2}' | while read printer
    do
      if [ $1 = "${printer}" ]; then
        return 1
      fi
    done
  fi    
}


# Printer Name cannot Include any spaces
prName="formalName"
# User friendly printer name"
prDescription="Printer Name"
# Location
prLocation="Home Office"
# IP Address of printer
prAddress="192.168.1.99"
# PPD Filename... assumes it is installed on machine
prPPD="HP LaserJet 2200.gz"

#Test If Printer is already installed
printerExists $prName
prExists=$?

if [ $prExists -eq 1 ]; then
  echo "Printer already exists. Skipping: "$prName""
else
  # Add Printer Command
  lpadmin -p "${prName}" -D "${prDescription}" -L "${prLocation}"
  -E -v lpd://"${prAddress}" -P "/Library/Printers/PPDs/Contents/Resources/en.lproj/$prPPD"
  -o HPOption_Duplexer=True -o Resolution=1200x1200dpi
fi

---

set default printer

lpoptions -d "${prName}"

Or just:

echo $prName > /Users/you/.lpoptions

---

Complete printer management

http://web.ics.purdue.edu/~tjohnson/osxprinterscripts/