Linux Device Driver

xiaoxiao2021-03-06  47

The ocl method

Like Char Devices, Block Devices Can Be Acted on by Using The IOCTL System Call.

The only Relevant Difference Between Block and char ioctl importations is what

Block Drivers Share a Number of Common IOCTL COMMANDS That MOST Drivers Are

Expected to support.

The Commands That Block Drivers Usually Handle Are The Following, Declared in

.

BLKGETSIZE

Retrieve the size of the capital device, expressed as the number of search.

The value of arg passed in by the system call is a pointer to a long value

The ocl method

349

Chapter 12: Loading Block Drivers

And Should Be Used to Copy The Size TO A User-Space Variable. this ioctl command

Is buy, for instance, by mkfs to know the size of the filesistem being

CREATED.

BLKFLSBUF

Literally, '' Flush Buffers. '' '' 'THEMPLEMENTATION OF THIS THIS THE SAME for

Every Device and is shown later with the sample code for the whole ioctl

Method.

BLKRRPART

Reread the partition table. This command is meaningful Only for PartitionAble

Devices, Introduced Later in this chapter.

BLKRAGET

BLKRASET

Used to get and change the current block-level read-ahead value (The One ONE

Stored in the read_ahead array) for the device. for get, The Current Value

SHOULD BE WRITTEN TO User Space As a long item using the pointer passed to

IOCTL IN arg; for set, the new value is passed as an argument.

BLKFRAGET

BLKFRASET

Get and set the filesystem-level read-ahead value (The One Stored in

MAX_READAHEAD).

BLKROSET

BLKROGET

THESE COMMANDS Are Used to Change and Check The Read-Only Flag for the Read-Only Flag for THE

DEVICE.

BLKSECTGET

BLKsectSet

Thase Commands Retrieve and Set The Maximum Number of Sectors Per Request

(AS Stored In max_sectors).

BLKSSZGETRETURns The Sector Size of this Block Device In The Integer Variable Pointed To

By The Caller; This Size Comes Directly from the Hardsect_size Array.

BLKPG

The BLKPG Command Allows User-Mode Programs To Add and delete Partitions.

IT IS IMPLEMENTED BY BLK_IOCTL (Described Shortly), And no Drivers in the

Mainline Kernel Provide Their Own IMplementation.

350

BLKELVGET

BLKELVSET

Thase Commands Allow Some Control Over How The Elevator Request Sorting

Algorithm Works. AS with BLKPG, No Driver Implements Them Directly.

HDIO_GETGEO

Defined in and used to retrieve the disk geometry. The disk geometry.

Geometry Should Be Written To User Space In A Struct HD_Geometry,

Which is declared in hdreg.h as well. Sbull shows the general importation

For this command.

The HDio_Getgeo Command Is The Most Commonly Used of a Series of HDIO_

Commands, All defined in . The interested Reader Can Look in

Ide.c and hd.c for more information about these Commands.

Almost All of these IOCTL COMMANDS Aremented in The Same Way for All Block

Devices. The 2.4 kernel Has Provided a Function, BLK_IOCTL, THAT May Be Called To

Implement the commit; it is declared in . OFTEN

The only ones That Must Be Implement in The Driver Itself Are BLKGETSIZE AND

HDio_getgeo. The Driver Can the Safely Pass Any Other Commands To BLK_IOCTL

For Handling.

The Sbull Device Supports Only The General Commands Just Listed, Because Immistings

Device-Specific Commands Is No Different from The Implementation of

Commands for char drives. The ioctl importation for sbull is as follows:

Int sbull_ioctl (struct inode * inode, struct file * filterp,

Unsigned int cmd, unsigned long arg) {

Int Err;

Long size;

Struct HD_Geometry Geo;

PDEBUG ("IOCTL 0x% x 0x% LX / N", CMD, ARG);

Switch (cmd) {

Case BLKGETSIZE:

/ * Return the device size, expressed in sectors * /

IF (! arg) Return-EinVal; / * Null Pointer: Not valid * /

Err =! Access_ok (Verify_Write, Arg, Sizeof (long);

IF (ERR) Return-Efault;

Size = blksize * sbull_sizes [minor (inode-> i_rdev)]

/ sbull_hardsects [minor (inode-> i_rdev)];

IF (COPY_TO_USER ((long *) Arg, & size, sizeof (long))))))

Return-Efault;

Return 0;

Case Blkrrpart: / * RERead Partition Table: Can't do it * /

Return -Notty;

Case HDio_getgeo:

The ocl method

351

Chapter 12: Loading Block Drivers

/ *

* GET Geometry: Since We are a Virtual Device, We Have To Make

* Upsomething Plausible. So We Claim 16 Sectors, Four Heads,

* And Calculate The Corresponding Number of Cylinders. WE SET

* The Start of Data At Sector Four.

* /

Err =! Access_ok (Verify_Write, Arg, SizeOf (GEO));

IF (ERR) Return-Efault;

Size = SBULL_SIZE * BLKSIZE / SBULL_HARDSECT;

Geo.cylinders = (SIZE & ~ 0X3F) >> 6;

Geo.Heads = 4;

Geo.sectors = 16;

Geo.start = 4;

IF (copy_to_user ((void *) arg, & geo, sizeof (geo)))))))

Return-Efault;

Return 0;

DEFAULT:

/ *

* For ioctls we don't understand, let the block iser

* Handle Them.

* /

Return BLK_IOCTL (Inode-> i_rdev, cmd, arg);

}

Return -Notty; / * unknown command * /

}

The Pdebug Statement At the Beginning of The Function Has Been Left in So That

WHEN You Compile The Module You Can Turn on Debugging To See Which IOCTL

Commands is invoked on the device.

转载请注明原文地址:https://www.9cbs.com/read-47529.html

New Post(0)