Assignment 5, Solutions

Part of the homework for 22C:112, Spring 2011
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

  1. Background: IBM's modelk 3330 disk system was the defining disk technology of the early 1970s. Each disk pack had 404 cylinders (of which only 400 were typically used) and 20 surfaces (IBM used one surface for formatting information, other vendors used all 20 surfaces) and 13,030 bytes per track (frequently arranged as 24 sectors of 512 bytes each, wasting a few bytes in the process). So, for the purpose of this assignment, consider a 3330 as 400 cylinders of 20 surfaces of 24 sectors of 512 bytes. This gives 98.3 megabytes per disk pack.

    A problem: Write a C routine linearize(int linear, struct diskad * da) to translate linearized disk addresses of the form you would get from lseek() when applied to the raw disk device. The disk address parameter points to a structure with fields called cylinder, track (within cylinder), sector (within track), and byte (within sector). (1 point)

    int linearize(int linear, struct diskad * da) {
            return diskad->byte
                 + BYTES_PER_SECTOR * (
                     diskad->sector
                   + SECTORS_PER_TRACK * (
                       diskad->track
                     + TRACKS_PER_CYLINDER * (
                         diskad->cylinder
                       )
                     )
                   );
    }
    

  2. Background: Assume that you have a disk interface with the following control registers:

    The disk is one of many devices attached to a DMA controller with the following control registers:

    With multiple disks attached to one DMA channel, it is essential to tell both the controller and the disk interface to move the data in the same direction, and it is essential that only one disk attempt to transfer data at a time.

    a) Outline the code for a stupid version of disk_IO( struct diskad * da, char * buf, int command) that will perform one disk operation on the disk device. It should work correctly in a single-threaded system under the assumption that other devices (including other disks) are driven by similar routines. (1 point)

    First, wait for the DMA controller and the disk controller to be idle, as indicated by the status bits. This is redundant in a single-threaded system, but in a multithreaded system, some other thread could have started I/O on some disk.

    Then, load the DMA address register with the buffer address and the DMA count register with the sector size. Also, load the disk sector, surface and cylinder registers with the corresponding data from the request.

    Next, load the disk command register with the command and as nearly simultaneously as possible, load the DMA command register with the corresponding command (it is easiest if both devices encode read and write identically, but of course, they probably don't).

    Finally, wait for the DMA controller and disk controller to be idle. indicating that the transfer is done.

    b) Now, assume that each device can request an interrupt when it is done, and assume that disk interrupts are handled by a different interrupt handler than DMA interrupts. In support of disk interrupts, you have a disk request queue, but you also have to deal with the relationship between the disk and DMA interrupt routines. This might be mediated by an additional queue or queues. Design the communication pattern between the user-side routine that enqueues disk requests, the disk interrupt handler and the DMA interrupt handler. A sensible answer will probably involve a diagram showing how the queue or queues relate to the software components, a description of what goes in each queue, and a textual description of how the different routines relate to each other. (1 point)

    When the disk interrupt handler gets a request it has never seen before from the disk queue, it issues a seek command. Other disk I/O on other disks can continue while the seek is being done by this disk drive. When the seek completes, it sends an interrupt telling the handler that real I/O can be done.

    When the handler gets a "seek complete" interrupt, it enqueues the disk read request on the DMA queue. If there are other DMA jobs to be done, the disk may remain idle for a while. When the DMA request reaches the head of the DMA queue, the DMA interrupt handler sets up both the DMA request and the disk request (probably by a callback so that the DMA interrupt service routine doesn't have to know anything about disk I/O).

    Both the disk driver and the DMA driver will receive interrupts when the actual disk operation completes. The disk driver just gets the next request from the disk queue and starts the seek operation. The DMA driver signals the user that the transfer is done and gets the next pending DMA request.