i have written a very simple ram based block device driver
processing request asynchronously
wherein
in request function -- dequeue the req from req queue and add it to the linked list
then in the function triggered by timer
handle each req from the linked list
then blk_end_requets is called upon completion of request .
what i guess is prob is in calculating page_address from bv->bv_page
pl guide me the correct way ..i m not able to come out of this prob .....
pl help
(i have to send code coz otherwise i wont be able to tell my problem )
but my program hangs doing nothing ....will u pl see my code once highlighted lines are the ones of some use ..
static void blkdev_req_fn(struct request_queue *q)
{
struct request *req;
unsigned long flags;
struct filtered_request * my_req=NULL;
while((req = elv_next_request(q)) != NULL){
if(!blk_fs_request(req)){
printk(KERN_ALERT"this is not read write type request");
end_request(req, 0);
continue;
}
blkdev_dequeue_request(req);
my_req = (struct filtered_request*)kzalloc(sizeof(struct filtered_request),GFP_KERNEL);
my_req->req=req;
INIT_LIST_HEAD(&(my_req->link));
spin_lock_irqsave(&(frqp->lock),flags);
list_add_tail(&(my_req->link),&(frqp->queue_head));
spin_unlock_irqrestore(&(frqp->lock),flags);
}
return;
}
static void set_timer_req_process(void)
{
/*Function to initialize timer*/
init_timer(&timer);
timer.function=handle_timer;
t.frqp=frqp;
t.dev_struct=dev_struct;
timer.data="" long)(&t);
timer.expires=jiffies+(1*HZ);
add_timer(&timer);
}
static void handle_timer(unsigned long data)
{
struct filtered_request *pos;
struct request* my_req= NULL;
struct bio_vec *bv=NULL;
struct req_iterator iter;
char *buffer = NULL;
char *buffer_start = NULL;
unsigned long offset,nrbytes=0;
unsigned long flags,flags2;
struct filtered_request_queue *frqp;
struct temp* tp = (struct temp*)data;
struct blkdev_device *dev;
frqp=tp->frqp;
dev = tp->dev_struct;
spin_lock_irqsave(&(frqp->
lock),flags);
if(!list_empty(&(frqp->queue_head)))
{
list_for_each_entry(pos,&(frqp->queue_head),link)
{
my_req = pos->req;
blk_dump_rq_flags(my_req, "\nBEFORENIDHI");
rq_for_each_segment(bv, my_req, iter)
{
//local_irq_save(flags2);
//buffer_start=kmap_atomic(bv->bv_page,KM_BIO_SRC_IRQ);
buffer_start=(char*)page_address(bv->bv_page);
buffer = buffer_start+bv->bv_offset;
offset = (my_req->sector)<<9;
nrbytes = bv->bv_len;
if(rq_data_dir(my_req)){
// Write request
memcpy(dev->buffer+offset,buffer,nrbytes);
}else { //Read request
memcpy(buffer,dev->buffer+offset,nrbytes);
}
my_req->sector += (bv->bv_len) >> 9;
//kunmap_atomic(bv->bv_page,KM_BIO_SRC_IRQ);
//local_irq_restore(flags2);
}//rq_for_each
blk_dump_rq_flags(my_req, "\nAFTERNIDHI");
blk_end_request(my_req,0,my_req->nr_sectors<<9);
}
}//!list_empty
spin_unlock_irqrestore(&(frqp->lock),flags);
}//function
--
if(!list_empty(&(frqp->queue_head)))
{
list_for_each_entry(pos,&(frqp->queue_head),link)
{
my_req = pos->req;
blk_dump_rq_flags(my_req, "\nBEFORENIDHI");
rq_for_each_segment(bv, my_req, iter)
{
//local_irq_save(flags2);
//buffer_start=kmap_atomic(bv->bv_page,KM_BIO_SRC_IRQ);
buffer_start=(char*)page_address(bv->bv_page);
buffer = buffer_start+bv->bv_offset;
offset = (my_req->sector)<<9;
nrbytes = bv->bv_len;
if(rq_data_dir(my_req)){
// Write request
memcpy(dev->buffer+offset,buffer,nrbytes);
}else { //Read request
memcpy(buffer,dev->buffer+offset,nrbytes);
}
my_req->sector += (bv->bv_len) >> 9;
//kunmap_atomic(bv->bv_page,KM_BIO_SRC_IRQ);
//local_irq_restore(flags2);
}//rq_for_each
blk_dump_rq_flags(my_req, "\nAFTERNIDHI");
blk_end_request(my_req,0,my_req->nr_sectors<<9);
}
}//!list_empty
spin_unlock_irqrestore(&(frqp->lock),flags);
}//function
--
--
Thanks & Regards
Nidhi