\label{chap:ahcid} \section{Introduction} \subsection{Public IDC Interface} ahcid's design is modeled after netd. It has a small \acs{idc} interface that facilitates user access to a port: when registering for a port, the user is given the capability for the port registers. Interrupts are forwarded via \acs{idc} messages. Currently the interface also provides access to the {\tt IDENTIFY} data of all available disks. This is useful to determine the type of device and total disk space without having to open the port. \begin{center} \begin{minipage}{100mm} \begin{lstlisting}[label={code:ahci_mgmt.if}, caption={ahci management Flounder interface}] interface ahci_mgmt "AHCI Management Daemon" { rpc list(out uint8 port_ids[len]); rpc identify(in uint8 port_id, out uint8 identify_data[data_len]); rpc open(in uint8 port_id, out errval status, out cap controller_mem, out uint64 offset, out uint32 capabilities); rpc close(in uint8 port_id, out errval status); message command_completed(uint8 port_id, uint32 interrupt_status); }; \end{lstlisting} \end{minipage} \end{center} \section{Initialization} ahcid registers itself as a driver for the \ac{ahci} device class. Once the init procedure is called, ahcid consults the received base address registers to find the memory region used for the \acs{hba}'s registers. As a first step, the \ac{hba} is reset in order to get to a known state. The \ac{hba} is also put into \ac{ahci} mode. After the initial reset, ahcid discovers the number of ports and detects which of them are implemented and have a disk connected. Discovered disks are assigned a system-wide unique port id and are registered with the skb. For every disk, an \ac{ata} {\tt IDENTIFY} command is sent to determine the disk's parameters. A copy of the {\tt IDENTIFY} response is cached in ahcid for later use. After all attached disks are initialized, ahcid exports the ahci management interface, which clients can then use to register themselves for a single port. \section{Interrupt Handling} ahcid registers itself as an interrupt handler for the \ac{ahci} \ac{hba} controller when calling \lstinline+pci_register_driver_irq+. The interrupt handler extracts the current interrupt state of the controller from the device memory and decides if the interrupt was triggered by the \ac{hba}. If the interrupt was triggered by the \ac{hba}, the handler loops over all ports and checks which ports received an interrupt and clears the port's interrupt register. The \ac{hba}'s interrupt register is cleared after all port interrupt registers have been cleared. At last, if a client is registered for a port that has received an interrupt, ahcid sends a \lstinline+command_completed+ message (\autoref{code:ahci_mgmt.if}) using the established \lstinline+ahci_mgmt+ interface. Clearing the interrupts before delivering the completion messages to the respective users ensures that we do not miss interrupts that would be triggered as a consequence of any commands issued in the command completion handler. Missing any interrupts for further completions could deadlock a user since we do not poll the port's state if no interrupts have been triggered.