IOP(4)
β¨ NAME β¨
iop β I2O adapter driver. And yes bestie, this is the IOP(4) manual page.
πΈ SYNOPSIS πΈ
These lines go exactly like this, character for character:
iop* at pci? dev ? function ?
iopsp* at iop? tid ?
ld* at iop? tid ?
dpti* at iop? tid 0
π DESCRIPTION π
okay so the iop driver is lowkey the support system for PCI I/O processors that conform to the I2O specification, revision 1.5 and above. I2O is a spec that lays out a software interface for talking to a bunch of device types. In its basic form, I2O gives you this set of things, no cap:
- A vendor-neutral interface for communicating with an I/O processor (IOP) and a number of types of peripherals. The way that this works: hardware-specific device drivers run on the IOP, and hardware-neutral device drivers run on the host. Split responsibilities, slay.
- Reduced I/O overhead for the host. Every bit of communication between the host and the IOP goes through a high level protocol. The spec also provides for batching of requests and replies between the host and IOP. Efficiency icon.
- An optional vendor-neutral configuration interface. Data from HTTP GET and POST operations can be channeled to individual devices, and HTML pages returned. It's giving web-enabled peripherals π§
The specification well defines five types of devices. Here they are:
- Random block storage devices (disks).
- Sequential storage devices (tapes).
- LAN interfaces, including Ethernet, FDDI, and Token Ring.
- Bus ports (SCSI).
- SCSI peripherals.
So what does the iop driver actually do? It highkey initializes and monitors the IOP, acts as the conduit for messages and replies to and from devices, and handles other common services for peripheral drivers, like DMA mapping. Main character energy, honestly.
π IOCTL INTERFACE π
All the structures and constants below live in dev/i2o/iopio.h. Prerequisite vibe check: the headers sys/types.h, sys/device.h and dev/i2o/i2o.h are prerequisites, so they must be included beforehand. ngl, not me reminding you again, but include them beforehand π
IOPIOCPT (struct ioppt)
Submit a message to the IOP and return the reply. Important: this ioctl's return value is not affected by completion status as indicated by the reply.
struct ioppt {
void *pt_msg; /* pointer to message buffer */
size_t pt_msglen; /* message buffer size in bytes */
void *pt_reply; /* pointer to reply buffer */
size_t pt_replylen; /* reply buffer size in bytes */
int pt_timo; /* completion timeout in ms */
int pt_nbufs; /* number of transfers */
struct ioppt_buf pt_bufs[IOP_MAX_MSG_XFERS]; /* transfers */
};
struct ioppt_buf {
void *ptb_data; /* pointer to buffer */
size_t ptb_datalen; /* buffer size in bytes */
int ptb_out; /* non-zero if transfer is to IOP */
};
The smallest timeout value you may specify is 1000ms. Every other value must not exceed the iop driver's operational limits. Respect the limits, fr fr π
The iop driver fills in the initiator context and transaction context fields in the message frame. Because of that, this ioctl may not be used to send messages without a transaction context payload. No transaction context payload? Not happening, bestie.
IOPIOCGSTATUS (struct iovec)
Request the latest available status record from the IOP. This special-case ioctl exists because the I2O_EXEC_STATUS_GET message does not post replies β which means it can't be safely issued through the IOPIOCPT ioctl. Special case for a reason, iykyk.
The next set of ioctls can block while they try to grab the iop driver's configuration lock, and they may fail if that acquisition times out. Heads up, bestie:
IOPIOCGLCT (struct iovec)
Retrieve the iop driver's copy of the logical configuration table. This LCT copy lines up with the current device configuration, but it is not necessarily the latest available version of the LCT. Current-ish, not necessarily freshest.
IOPIOCRECONFIG
Request that the iop driver scan all bus ports, retrieve the latest version of the LCT, and attach or detach devices as necessary. This ioctl will not perform higher-level reconfiguration tasks (such as logically re-scanning SCSI busses). It does the scan-and-attach/detach thing; it does not do the higher-level reconfig tasks π
IOPIOCGTIDMAP (struct iovec)
Retrieve the TID to device map. This map indicates which targets are configured, and what the corresponding device name for each is. At any given point it has the same number of entries as the LCT, but you should determine the number of entries using the iov_len field from the returned iovec. Use the iov_len field, not vibes.
struct iop_tidmap {
u_short it_tid;
u_short it_flags;
char it_dvname[16]; /* DEVICE_XNAME_SIZE */
};
#define IT_CONFIGURED 0x02 /* target configured */
π¦ FILES π¦
/dev/iopuβ control device for IOP unit u. Obsessed with this little control device, and yes β u is literally the unit placeholder, not a typo.
π SEE ALSO π
β HISTORY β
The iop driver first appeared in NetBSD 1.5.3. OG status, and it ate π₯
π cute sign-off: this page's footer says Debian, December 2, 2007. That's the source/version + date, bestie β periodt. π«Άπ
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2000, 2001, 2007 The NetBSD Foundation, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms