colinux64/patch/cobd-2.6.33.diff
2025-02-13 19:09:34 -07:00

259 lines
7.4 KiB
Diff
Executable File

Index: linux-2.6.33-source/include/linux/major.h
===================================================================
--- linux-2.6.33-source.orig/include/linux/major.h
+++ linux-2.6.33-source/include/linux/major.h
@@ -131,6 +131,7 @@
#define VIOCD_MAJOR 113
#define ATARAID_MAJOR 114
+#define COLINUX_MAJOR 117
#define SCSI_DISK8_MAJOR 128
#define SCSI_DISK9_MAJOR 129
Index: linux-2.6.33-source/drivers/block/Kconfig
===================================================================
--- linux-2.6.33-source.orig/drivers/block/Kconfig
+++ linux-2.6.33-source/drivers/block/Kconfig
@@ -383,6 +383,15 @@
will prevent RAM block device backing store memory from being
allocated from highmem (only a problem for highmem systems).
+config BLK_DEV_COBD
+ tristate 'Cooperative block device support'
+ default y
+ depends on COOPERATIVE
+ help
+ Virtual block device support for cooperative kernels.
+
+ If unsure, say Y.
+
config CDROM_PKTCDVD
tristate "Packet writing on CD/DVD media"
depends on !UML
Index: linux-2.6.33-source/drivers/block/Makefile
===================================================================
--- linux-2.6.33-source.orig/drivers/block/Makefile
+++ linux-2.6.33-source/drivers/block/Makefile
@@ -14,6 +14,7 @@
obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
obj-$(CONFIG_BLK_DEV_RAM) += brd.o
+obj-$(CONFIG_BLK_DEV_COBD) += cobd.o
obj-$(CONFIG_BLK_DEV_LOOP) += loop.o
obj-$(CONFIG_BLK_DEV_XD) += xd.o
obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o
Index: linux-2.6.33-source/drivers/block/cobd.c
===================================================================
--- linux-2.6.33-source.orig/drivers/block/cobd.c
+++ linux-2.6.33-source/drivers/block/cobd.c
@@ -44,7 +44,6 @@
long rc;
co_passage_page_assert_valid();
-
co_passage_page_acquire(&flags);
co_passage_page->operation = CO_OPERATION_DEVICE;
co_passage_page->params[0] = CO_DEVICE_BLOCK;
@@ -70,21 +69,21 @@
return cobd_request(cobd, CO_BLOCK_GET_ALIAS, out_request);
}
-static int cobd_ioctl(struct inode * inode, struct file * file,
+static int cobd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
return -ENOTTY; /* unknown command */
}
-static int cobd_open(struct inode *inode, struct file *file)
+static int cobd_open(struct block_device *bdev, fmode_t mode)
{
- struct cobd_device *cobd = (struct cobd_device *)(inode->i_bdev->bd_disk->private_data);
+ struct cobd_device *cobd = bdev->bd_disk->private_data;
co_block_request_t *co_request;
co_block_request_t stat_request;
unsigned long flags;
int result;
- if (cobd->device && cobd->device != inode->i_bdev)
+ if (cobd->device && cobd->device != bdev)
return -EBUSY;
if (cobd->refcount == 0) {
@@ -96,7 +95,6 @@
result = 0;
co_passage_page_assert_valid();
-
co_passage_page_acquire(&flags);
co_passage_page->operation = CO_OPERATION_DEVICE;
co_passage_page->params[0] = CO_DEVICE_BLOCK;
@@ -114,22 +112,21 @@
return result;
if (cobd->refcount == 1) {
- set_capacity(inode->i_bdev->bd_disk, stat_request.disk_size >> hardsect_size_shift);
- cobd->device = inode->i_bdev;
+ set_capacity(bdev->bd_disk, stat_request.disk_size >> hardsect_size_shift);
+ cobd->device = bdev;
}
return 0;
}
-static int cobd_release(struct inode *inode, struct file *file)
+static int cobd_release(struct gendisk *disk, fmode_t mode)
{
- struct cobd_device *cobd = (struct cobd_device *)(inode->i_bdev->bd_disk->private_data);
+ struct cobd_device *cobd = disk->private_data;
co_block_request_t *co_request;
unsigned long flags;
int ret = 0;
co_passage_page_assert_valid();
-
co_passage_page_acquire(&flags);
co_passage_page->operation = CO_OPERATION_DEVICE;
co_passage_page->params[0] = CO_DEVICE_BLOCK;
@@ -151,14 +148,17 @@
/*
* Handle an I/O request.
*/
-static int cobd_transfer(struct cobd_device *cobd, struct request *req, int *async)
+static void cobd_transfer(struct request_queue *q, struct request *req)
{
+ struct cobd_device *cobd = (struct cobd_device *)(req->rq_disk->private_data);
co_block_request_t *co_request;
unsigned long flags;
+ int async;
int ret;
- co_passage_page_assert_valid();
+next_segment:
+ co_passage_page_assert_valid();
co_passage_page_acquire(&flags);
co_passage_page->operation = CO_OPERATION_DEVICE;
co_passage_page->params[0] = CO_DEVICE_BLOCK;
@@ -166,47 +166,43 @@
co_request = (co_block_request_t *)&co_passage_page->params[2];
co_request->type = (rq_data_dir(req) == READ) ? CO_BLOCK_READ : CO_BLOCK_WRITE;
co_request->irq_request = req;
- co_request->offset = ((unsigned long long)(req->sector)) << hardsect_size_shift;
- co_request->size = req->current_nr_sectors << hardsect_size_shift;
+ co_request->offset = ((unsigned long long)blk_rq_pos(req)) << hardsect_size_shift;
+ co_request->size = blk_rq_cur_bytes(req);
co_request->address = req->buffer;
co_request->rc = 0;
co_request->async = 0;
co_switch_wrapper();
- *async = co_request->async;
+ async = co_request->async;
ret = co_request->rc;
-
co_passage_page_release(flags);
- return ret;
+
+ /*
+ * OK: ret == 0
+ * FAIL: ret == -1
+ */
+ if (ret == CO_BLOCK_REQUEST_RETCODE_OK) {
+ if (async)
+ return; /* wait for interrupt */
+
+ if (__blk_end_request_cur(req, 0))
+ goto next_segment;
+
+ } else {
+ __blk_end_request_all(req, -EIO);
+ }
}
-static void do_cobd_request(request_queue_t *q)
+static void do_cobd_request(struct request_queue *q)
{
struct request *req;
- struct cobd_device *cobd;
-
- while ((req = elv_next_request(q)) != NULL) {
- int ret;
- int async;
+ while ((req = blk_fetch_request(q)) != NULL) {
if (!blk_fs_request(req)) {
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
continue;
}
- cobd = (struct cobd_device *)(req->rq_disk->private_data);
-
- ret = cobd_transfer(cobd, req, &async);
- /*
- * OK: ret == 0 --> uptodate = 1
- * FAIL: ret == -1 --> uptodate = 0
- */
- if (ret == CO_BLOCK_REQUEST_RETCODE_OK) {
- if (async)
- break; /* wait for interrupt */
- end_request(req, 1);
- } else {
- end_request(req, 0);
- }
+ cobd_transfer(q, req);
}
}
@@ -231,8 +227,10 @@
BUG_ON(!req);
spin_lock(&cobd_lock);
- end_request(req, intr->uptodate);
- do_cobd_request(req->q);
+ if (__blk_end_request_cur(req, intr->uptodate ? 0 : -EIO))
+ cobd_transfer(req->q, req); /* next segment */
+ else
+ do_cobd_request(req->q);
spin_unlock(&cobd_lock);
goto_next_message:
@@ -284,7 +282,7 @@
if (!disk->queue)
goto fail_malloc4;
- blk_queue_hardsect_size(disk->queue, hardsect_size);
+ blk_queue_logical_block_size(disk->queue, hardsect_size);
cobd->unit = i;
disk->major = COLINUX_MAJOR;
@@ -314,8 +312,7 @@
kfree(cobd_disks);
fail_malloc:
- if (unregister_blkdev(COLINUX_MAJOR, "cobd"))
- printk(KERN_WARNING "cobd: cannot unregister blkdev\n");
+ unregister_blkdev(COLINUX_MAJOR, "cobd");
fail_irq:
free_irq(BLOCKDEV_IRQ, NULL);
@@ -460,7 +457,7 @@
}
cobd = &cobd_devs[cobd_unit];
- blk_queue_hardsect_size(disk->queue, hardsect_size);
+ blk_queue_logical_block_size(disk->queue, hardsect_size);
disk->major = alias->major->number;
disk->first_minor = alias->minor_start + index;
disk->fops = &cobd_fops;
@@ -514,8 +511,7 @@
put_disk(cobd_disks[i]);
}
- if (unregister_blkdev(COLINUX_MAJOR, "cobd"))
- printk(KERN_WARNING "cobd: cannot unregister blkdev\n");
+ unregister_blkdev(COLINUX_MAJOR, "cobd");
free_irq(BLOCKDEV_IRQ, NULL);
kfree(cobd_disks);