I'm using the block driver provided by <<Linux Device Driver, 2ed>>, on Chapter 12. And I'm using kernel 2.4.27.
I'm trying to use let the driver deal with each buffer_head directly,
rather than using a request_queue. Everytime I load the driver into the
kernel and staring to transfer some sectors, I always get the same Oops
message(provided below). It looks like something wrong with the way the
function make_request works (also provided below). Can anyone point out
what's wrong with the function and how should I fix it. Thanks!!!
Fei
Mar 10 16:58:47 milhouse kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000000
Mar 10 16:58:47 milhouse kernel: printing eip:
Mar 10 16:58:47 milhouse kernel: c01ad340
Mar 10 16:58:47 milhouse kernel: *pde = 00000000
Mar 10 16:58:47 milhouse kernel: Oops: 0000
Mar 10 16:58:47 milhouse kernel: CPU: 0
Mar 10 16:58:47 milhouse kernel: EIP: 0010:[__blk_cleanup_queue+32/112] Not tainted
Mar 10 16:58:47 milhouse kernel: EFLAGS: 00210213
Mar 10 16:58:47 milhouse kernel: eax: 00000000 ebx: c02eceb4 ecx: 00000000 edx: 000000fe
Mar 10 16:58:47 milhouse kernel: esi: 00000000 edi: c02ecea8 ebp: c27d3f8c esp: c27d3f48
Mar 10 16:58:47 milhouse kernel: ds: 0018 es: 0018 ss: 0018
Mar 10 16:58:47 milhouse kernel: Process rmmod (pid: 1868, stackpage=c27d3000)
Mar 10 16:58:47 milhouse kernel: Stack: c013f62b 0000fe00 00000000 fffffff0 c02ecea8 c01ad3aa c02ecea8 0000fe00
Mar 10 16:58:47 milhouse
kernel: 00000001 00000000
d4a50f7b c02ecea8 d4a51157 c025ec38 c025ec38 c1030020
Mar 10 16:58:47 milhouse
kernel: d4a4f000 bfffeb68
c011e10a d4a4f000 d4a4f000 fffffff0 c63b3000 c011d47f
Mar 10 16:58:47 milhouse kernel: Call Trace:
[sync_buffers+107/112] [blk_cleanup_queue+26/112]
[bttv:__insmod_bttv_S.data_L19772+523131/48618029]
[bttv:__insmod_bttv_S.data_L19772+523607/48617553] [free_module+170/192]
Mar 10 16:58:47 milhouse kernel: [sys_delete_module+159/464] [system_call+51/56]
Mar 10 16:58:47 milhouse kernel:
Mar 10 16:58:47 milhouse kernel: Code: 8b 01 46 8b 51 04 89 50 04 89 02 c7 41 04 00 00 00 00 c7 01
/*
* Transfer a buffer directly, without going through the request queue.
*/
int npswap_make_request(request_queue_t *queue, int rw, struct buffer_head *bh) {
u8 *ptr;
// Figure out what we are doing
Sbull_Dev *device = npswap_devices + MINOR(bh->b_rdev);
ptr = device->data + bh->b_rsector * npswap_hardsect;
// Paranoid check, this apparently can really happen
if (ptr + bh->b_size > device->data + npswap_blksize*npswap_size) {
static int count = 0;
if (count++ < 5)
printk(KERN_WARNING "npswap: request past end of device\n");
bh->b_end_io(bh, 0);
return 0;
}
// This could be a high memory buffer, shift it down
#if CONFIG_HIGHMEM
bh = create_bounce(rw, bh);
#endif
// Do the transfer
switch(rw) {
case READ:
case READA: // Readahead
memcpy(bh->b_data, ptr, bh->b_size); // from npswap to buffer
bh->b_end_io(bh, 1);
break;
case WRITE:
refile_buffer(bh);
memcpy(ptr, bh->b_data, bh->b_size); // from buffer to npswap
mark_buffer_uptodate(bh, 1);
bh->b_end_io(bh, 1);
break;
default:
// can't happen
bh->b_end_io(bh, 0);
break;
}
// Nonzero return means we're done
return 0;
}