9.6 Request Packets and Function Requests

MS-DOS generates function requests when programs call MS-DOS system functions that require input from or output to a given device. Each function request consists of a request packet that MS-DOS passes to the device driver. A request packet contains information the driver uses to identify and carry out the request. The size and format of a packet depend on the function to be carried out, but all request packets have two parts: a request header (which has the same format for all requests), and request-specific fields. The form of the request header corresponds to a REQUESTHEADER structure:

REQUESTHEADER STRUC

rhLength db ? ;length of record, in bytes

rhUnit db ? ;unit number (block device only)

rhFunction db ? ;function number

rhStatus dw ? ;status

rhReserved db 8 dup(?) ;reserved

REQUESTHEADER ENDS

For a full description of the REQUESTHEADER structure, see Section 9.9, “Structures.”

MS-DOS writes the request packet in a reserved area of memory, setting the rhFunction field (offset 02h) to specify the action to be performed by the device driver and setting the rhUnit field (offset 01h), if the driver supports a block device, to identify the drive the request is for. The rhLength field (offset 00h) contains the length, in bytes, of the complete request packet. This is important for requests that have additional request-specific fields.

MS-DOS first calls the device driver's strategy routine, passing (in the ES:BX registers) the 32-bit address (segment:offset) of the request packet. The strategy routine saves this address and immediately returns to the system. MS-DOS then calls the interrupt routine, which retrieves the address of the request packet and reads the rhFunction field to determine what action to take. If the device driver supports a block device, the interrupt routine also reads the rhUnit field to determine which drive to access. This field specifies a zero-based unit number. (For example, if the driver controls four devices, a request to access the first one specifies number 0.) Note that the drive number and the unit number are not the same. Although programs use drive numbers to access a driver's devices, MS-DOS converts these numbers to zero-based unit numbers before calling the driver with a function request.

Depending on the function, the interrupt routine may read from or write to additional fields. The request packet for Write (Device-Driver Function 08h), for example, includes a transfer address (offset 0Dh), a sector count (offset 12h), and a starting sector (offset 14h). The interrupt routine must translate the starting sector into a physical sector (consisting of track, head, and sector numbers) and then write the specified number of sectors from the transfer address to the designated sectors on the specified drive.

When the interrupt routine completes its actions, it must report the status of the request to MS-DOS by setting one or more bits in the rhStatus field (offset 03h) in the request packet. If the function is successful, the routine sets the done bit (bit 8). If an error occurred, the routine sets the done bit and the error bit (bit 15) and copies an error value to bits 0 through 7 of the rhStatus field. (For a list of these error values, see the REQUESTHEADER structure in Section 9.9, “Structures.”) Finally, the routine returns to MS-DOS.