i was practising writing block device driver from linux device driver 3rd edition
but was confused
as
it gives two implementation to transfer data from device
1.without using bios
2.using bios
in ist implementation ---- cut short version of book code is -----
while ((req = elv_next_request(q)) != NULL) {
struct sbull_dev *dev = req->rq_disk->private_data;
sbull_transfer(dev, req->sector, req->current_nr_sectors,req->buffer, rq_data_dir(req));
end_request(req, 1);
}
****************************************************************************************************************************
static void sbull_transfer(struct sbull_dev *dev, unsigned long sector,
unsigned long nsect, char *buffer, int write)
{
unsigned long offset = sector*KERNEL_SECTOR_SIZE;
unsigned long nbytes = nsect*KERNEL_SECTOR_SIZE;
if ((offset + nbytes) > dev->size) {
printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes);
return;
}
if (write)
memcpy(dev->data + offset, buffer, nbytes);
else
memcpy(buffer, dev->data + offset, nbytes);
}
****************************************************************************************************************************
Now my question is '
when current_nr_sectors ==== is the number of sectors left to be transferres in the current segment
THEN HOW IS IT THAT WE TRANSFER JUST current_nr_sectors AND CONSIDER THAT
WHOLE REQUEST DATA IS TRANSFERRED AND END THE REQUEST ...!!!!!!!
and i know it gives correct result and its done like that everywhere ...
but i am unable to comply with its meaning ....
similarly req->buffer --- is also the data of current bio as it was written
in LDD
"this field is
simply the result of calling bio_data on the current bio.where bio_data(bio) Returns a kernel logical address pointing to the data to be transferre"
therefore it seems it is only pointing to the data buffer of current bio only.....
i read kernel documentation for bio structure and got this text ----may be it is explaining the reason ----
"*****************************************************************************************
Implications for drivers that do not interpret bios (don't handle multiple segments)
Drivers that do not interpret bios e.g those which do not handle multiple
segments and do not support i/o into high memory addresses (require bounce
buffers) and expect only virtually mapped buffers, can access the rq->buffer
field. As before the driver should use current_nr_sectors to determine the
size of remaining data in the current segment (that is the maximum it can
transfer in one go unless it interprets segments), and rely on the block layer
end_request, or end_that_request_first/last to take care of all accounting
and transparent mapping of the next bio segment when a segment boundary
is crossed on completion of a transfer. (The end*request* functions should
be used if only if the request has come down from block/bio path, not for
direct access requests which only specify rq->buffer without a valid rq->bio
*************************************************************************************************************************************
pl help me to deduce something out of it .....
--
Thanks & Regards
Nidhi