David McCullough wrote:
>
> * Lots of fixes for IXP driver
> - builds for 1.4 and 2.0 access libs
> - task queues to handle possible blocking calls
You need to use work queues for 2.6. I think recent 2.4 kernels have a
linux/workqueue.h compatibility header.
The attached patch also fixes up a few other bits and pieces.
David Vrabel
--
David Vrabel, Design Engineer
Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/
Index: linux-2.6-working/crypto/ocf/Makefile
===================================================================
--- linux-2.6-working.orig/crypto/ocf/Makefile 2005-07-11 10:32:40.000000000 +0100
+++ linux-2.6-working/crypto/ocf/Makefile 2005-07-11 11:03:07.000000000 +0100
@@ -14,7 +14,7 @@
obj-$(CONFIG_OCF_HIFN) += $(obj-base)hifn/hifn7751.o
obj-$(CONFIG_OCF_IXP4XX) += $(obj-base)ixp4xx/ixp4xx.o
-obj-m += $(obj-base)ocf-bench.o
+obj-$(CONFIG_OCF_BENCH) += $(obj-base)ocf-bench.o
ifndef obj
list-multi += ocf.o
@@ -84,7 +47,7 @@
IXP_CFLAGS += -D__ixp42X
endif
-CFLAGS_ixp4xx/ixp4xx.o += $(IXP_CFLAGS)
+CFLAGS_ixp4xx.o += $(IXP_CFLAGS)
CFLAGS_ocf-bench.o += $(IXP_CFLAGS)
ifdef TOPDIR
Index: linux-2.6-working/crypto/ocf/ixp4xx/ixp4xx.c
===================================================================
--- linux-2.6-working.orig/crypto/ocf/ixp4xx/ixp4xx.c 2005-07-11 10:32:40.000000000 +0100
+++ linux-2.6-working/crypto/ocf/ixp4xx/ixp4xx.c 2005-07-11 11:53:22.000000000 +0100
@@ -40,7 +40,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/crypto.h>
-#include <linux/tqueue.h>
+#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <asm/scatterlist.h>
@@ -83,7 +83,8 @@
IX_MBUF ixp_pri_mbuf;
IX_MBUF ixp_sec_mbuf;
- struct tq_struct ixp_tq; /* registration task */
+ struct work_struct process_pending_work;
+ struct work_struct registration_work;
struct list_head ixp_q; /* unprocessed requests */
};
@@ -107,6 +108,8 @@
MODULE_PARM(init_crypto, "i");
MODULE_PARM_DESC(init_crypto, "Call ixCryptoAccInit (default is 1)");
+static void ixp_process_pending(void *arg);
+static void ixp_registration(void *arg);
/*
* Generate a new software session.
@@ -249,6 +252,10 @@
}
cri = cri->cri_next;
}
+
+ INIT_WORK(&ixp->process_pending_work, ixp_process_pending, ixp);
+ INIT_WORK(&ixp->registration_work, ixp_registration, ixp);
+
return 0;
}
@@ -277,6 +284,9 @@
ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
ixp_sessions[sid]->ixp_ctx_id = -1;
}
+
+ flush_scheduled_work();
+
kfree(ixp_sessions[sid]);
}
ixp_sessions[sid] = NULL;
@@ -476,11 +486,8 @@
* Run the Q processing on the immediate task queue.
*/
ixp->ixp_registered = 1;
- ixp->ixp_tq.sync = 0;
- ixp->ixp_tq.routine = ixp_process_pending;
- ixp->ixp_tq.data = ixp;
- queue_task(&ixp->ixp_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+
+ schedule_work(&ixp->process_pending_work);
}
@@ -727,13 +734,8 @@
status = list_empty(&ixp->ixp_q);
list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
- if (status) {
- ixp->ixp_tq.sync = 0;
- ixp->ixp_tq.routine = ixp_registration;
- ixp->ixp_tq.data = ixp;
- queue_task(&ixp->ixp_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- }
+ if (status)
+ schedule_work(&ixp->registration_work);
return 0;
done:
@@ -766,8 +768,6 @@
return -ENOENT;
}
- spin_lock_init(&ixp_pkq_lock);
-
ixp_id = crypto_get_driverid(0);
if (ixp_id < 0)
panic("IXP/OCF crypto device cannot initialize!");
Index: linux-2.6-working/crypto/ocf/ocf-bench.c
===================================================================
--- linux-2.6-working.orig/crypto/ocf/ocf-bench.c 2005-07-11 10:32:40.000000000 +0100
+++ linux-2.6-working/crypto/ocf/ocf-bench.c 2005-07-11 12:45:08.000000000 +0100
@@ -12,7 +12,7 @@
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/version.h>
-#include <linux/tqueue.h>
+#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <cryptodev.h>
@@ -59,7 +59,7 @@
* a structure for each request
*/
typedef struct {
- struct tq_struct tq;
+ struct work_struct work;
#ifdef BENCH_IXP_ACCESS_LIB
IX_MBUF mbuf;
#endif
@@ -106,11 +106,16 @@
error = crypto_newsession(&ocf_cryptoid, &crie, 0);
if (error) {
printk("crypto_newsession failed %d\n", error);
- return 1;
+ return -1;
}
return 0;
}
+static void ocf_request_work(void *r)
+{
+ ocf_request((request_t *)r);
+}
+
static int
ocf_cb(struct cryptop *crp)
{
@@ -125,11 +130,8 @@
return 0;
}
- r->tq.sync = 0;
- r->tq.routine = (void (*)(void *)) ocf_request;
- r->tq.data = (void *) r;
- queue_task(&r->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ INIT_WORK(&r->work, ocf_request_work, r);
+ schedule_work(&r->work);
return 0;
}
@@ -142,7 +144,7 @@
if (!crp) {
outstanding--;
- return ENOMEM;
+ return -ENOMEM;
}
crda = crp->crp_desc;
@@ -225,11 +227,11 @@
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
while (!ixp_registered)
schedule();
- return ixp_registered < 0 ? 1 : 0;
+ return ixp_registered < 0 ? -1 : 0;
}
printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
- return 1;
+ return -1;
}
static void
@@ -249,6 +251,11 @@
ixp_registered = -1;
}
+static void ixp_request_work(void *r)
+{
+ ixp_request((request_t *)r);
+}
+
static void
ixp_perform_cb(
UINT32 ctx_id,
@@ -270,12 +277,8 @@
return;
}
- r->tq.sync = 0;
- r->tq.routine = ixp_request;
- r->tq.data = (void *) r;
- queue_task(&r->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- return;
+ INIT_WORK(&r->work, ixp_request_work, r);
+ schedule_work(&r->work);
}
static int
@@ -292,7 +295,7 @@
if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
printk("status1 = %d\n", status);
outstanding--;
- return 1;
+ return -1;
}
return 0;
}
@@ -311,7 +314,7 @@
requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
if (!requests) {
printk("malloc failed\n");
- return EINVAL;
+ return -EINVAL;
}
for (i = 0; i < request_q_len; i++) {
@@ -319,7 +322,7 @@
requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
if (!requests[i].buffer) {
printk("malloc failed\n");
- return EINVAL;
+ return -EINVAL;
}
}
@@ -364,7 +367,7 @@
for (i = 0; i < request_q_len; i++)
kfree(requests[i].buffer);
kfree(requests);
- return EINVAL; /* always fail to load so it can be re-run quickly ;-) */
+ return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
}
module_init(ocfbench_init);