LinuxForum.Fans
Тема

block device driver fails

Автор: alexalexalex03 6 сообщений 5901 просмотров
#182204

Всем привет :)
Я пишу драйвер блочного устройства. Но он упорно отказывается работать. Вот код:

text
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <linux/genhd.h>
#include <linux/string.h>
#include <linux/hdreg.h>
#include <linux/slab.h>

#define USB_TMP_MJ 239

DEFINE_SPINLOCK(usb_tmp_queue_lock);

#define usb_tmp_capacity 4*32*64

char *usb_tmp_buf;

static int usb_tmp_read(unsigned sector, unsigned len, char *buffer) { // memset(usb_tmp_buf, 1, count); /* * *****ОШИБКА ПО МОИМ ПОДСЧЕТАМ В ЭТОЙ СТРОКЕ************************** * вроде определил что ошибка возникает из за переполнения "buffer" (могу ошибаться) */ memcpy(buffer, usb_tmp_buf+sector*512, len);

printk("%x %x %x %x %x\n", buffer, usb_tmp_buf,usb_tmp_buf+sector*512, sector, len);

return 0; }

static int usb_tmp_write(unsigned sector, unsigned len, char *buffer) { memcpy(usb_tmp_buf+sector*512, buffer, len);

// printk("%x %x %x %x\n", buffer, usb_tmp_buf, usb_tmp_buf+sector*512, count);

return 0; }

static int usb_tmp_open(struct block_device *bd, fmode_t fm) { printk("Open!!!\n"; return 0; }

static int usb_tmp_getgeo(struct block_device *bd,struct hd_geometry *hg) { hg->heads = 4; hg->cylinders = 64; hg->sectors = 32; return 0; }

struct request_queue *usb_tmp_rq;

struct gendisk *usb_tmp_gd;

struct block_device_operations usb_tmp_ops = { .owner = THIS_MODULE, // .open = &usb_tmp_open, .getgeo = &usb_tmp_getgeo, };

void usb_tmp_request(struct request_queue *rq) { struct request *req; unsigned sector, count, len;

while ((req = blk_fetch_request(rq)) != NULL) { sector = blk_rq_pos(req); count = blk_rq_sectors(req); len = blk_rq_bytes(req);

if (sector + count >= usb_tmp_capacity) goto end_req;

if (req->cmd_type == REQ_TYPE_FS) { switch (rq_data_dir(req)) { case READ: printk("READ: sect=%d, count=%d\n", sector, len); usb_tmp_read(sector, len, req->buffer); break; case WRITE: printk("WRITE: sect=%d, count=%d\n", sector, len); usb_tmp_write(sector, len, req->buffer); break; } }

end_req: blk_end_request_all(req, 0); } }

static int __init usb_tmp_init(void) { int res;

if ((usb_tmp_buf = vmalloc(usb_tmp_capacity*512)) == NULL) { printk("error vmalloc()\n"; return -1; }

if (res = register_blkdev(USB_TMP_MJ, "usb_tmp") { printk("Error: res=%d\n", (int) res); return -1; }

if (!(usb_tmp_rq = blk_init_queue(&usb_tmp_request, &usb_tmp_queue_lock))) { printk("Error: rq=%d\n", (int) usb_tmp_rq); return -1; }

usb_tmp_gd = alloc_disk(1);

usb_tmp_gd->major = USB_TMP_MJ; usb_tmp_gd->first_minor = 0; usb_tmp_gd->minors = 4; strcpy(&usb_tmp_gd->disk_name,"usb_tmp"; usb_tmp_gd->fops = &usb_tmp_ops; usb_tmp_gd->queue = usb_tmp_rq;

set_capacity(usb_tmp_gd, usb_tmp_capacity);

add_disk(usb_tmp_gd);

return 0; } module_init(usb_tmp_init);

static void __exit usb_tmp_exit(void) { del_gendisk(usb_tmp_gd); blk_cleanup_queue(usb_tmp_rq); unregister_blkdev(USB_TMP_MJ, "usb_tmp";

printk("exit\n"; } module_exit(usb_tmp_exit);

Драйвер - так называемый ram-device driver
Где же здесь может быть ошибка:

text
memcpy(buffer, usb_tmp_buf+sector*512, len);

Вроде передаю правильный размер и правильные адреса в функцию...
Помогите плз кто может...

kernel-2.6.39.2

#182211

req->buffer точно инициализирован?

#182233
Fat-Zer написал:
req->buffer точно инициализирован?

не, как я понял req->buffer передает мне система для записи\чтения от туда данных... т.е. система сама выделяет для него память...

#182237
blkdev.h написал:
char *buffer; /* kaddr of the current segment if available */

я бы распечатал его для полной уверенности...
сектор не больше положенного? и какая ошибка? сегфолт?

#182262

Вобщем, если заменить len = blk_rq_bytes(req); на len = blk_rq_cur_bytes(req);, то всё работает за исключением одного: устройство не хочет монтироваться (разумеется, после fdisk'a и mkfs -t ext2 /dev/usb1), ошибка при монтировании "Stale NFS file handle", что, видимо, означает неполное выполнение "реквеста", так сказать...

я бы распечатал его для полной уверенности...
это вряд ли что нибудь даст... там кроме мусора ничего не найдешь...

сектор не больше положенного?
неа...

и какая ошибка? сегфолт?
нет, просто система зависает и все... тока reset на блоке питания работает...
#182270

Решил проблему, помогла эта статья. Патч: len = blk_rq_bytes(req); -> len = blk_rq_cur_bytes(req); и blk_end_request_all(req, 0); -> if (!blk_end_request_cur(req, 0))
req = blk_fetch_request(rq);

Войдите или зарегистрируйтесь, чтобы ответить.