Commit 1a85b4b1 authored by Ben Collins's avatar Ben Collins

IEEE1394(r1157): Create a kernel thread to handle all run_packet_complete() calls.

parent 924d42af
...@@ -77,18 +77,8 @@ static void dump_packet(const char *text, quadlet_t *data, int size) ...@@ -77,18 +77,8 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
#define dump_packet(x,y,z) #define dump_packet(x,y,z)
#endif #endif
static void run_packet_complete(struct hpsb_packet *packet) static void queue_packet_complete(struct hpsb_packet *packet);
{
if (packet->complete_routine != NULL) {
void (*complete_routine)(void*) = packet->complete_routine;
void *complete_data = packet->complete_data;
packet->complete_routine = NULL;
packet->complete_data = NULL;
complete_routine(complete_data);
}
return;
}
/** /**
* hpsb_set_packet_complete_task - set the task that runs when a packet * hpsb_set_packet_complete_task - set the task that runs when a packet
...@@ -424,7 +414,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, ...@@ -424,7 +414,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
if (ackcode != ACK_PENDING || !packet->expect_response) { if (ackcode != ACK_PENDING || !packet->expect_response) {
packet->state = hpsb_complete; packet->state = hpsb_complete;
run_packet_complete(packet); queue_packet_complete(packet);
return; return;
} }
...@@ -669,7 +659,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, ...@@ -669,7 +659,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
} }
packet->state = hpsb_complete; packet->state = hpsb_complete;
run_packet_complete(packet); queue_packet_complete(packet);
} }
...@@ -949,7 +939,7 @@ void abort_requests(struct hpsb_host *host) ...@@ -949,7 +939,7 @@ void abort_requests(struct hpsb_host *host)
list_del(&packet->list); list_del(&packet->list);
packet->state = hpsb_complete; packet->state = hpsb_complete;
packet->ack_code = ACKX_ABORTED; packet->ack_code = ACKX_ABORTED;
run_packet_complete(packet); queue_packet_complete(packet);
} }
} }
...@@ -983,15 +973,74 @@ void abort_timedouts(unsigned long __opaque) ...@@ -983,15 +973,74 @@ void abort_timedouts(unsigned long __opaque)
list_del(&packet->list); list_del(&packet->list);
packet->state = hpsb_complete; packet->state = hpsb_complete;
packet->ack_code = ACKX_TIMEOUT; packet->ack_code = ACKX_TIMEOUT;
run_packet_complete(packet); queue_packet_complete(packet);
} }
} }
static int khpsbpkt_pid = -1;
static DECLARE_COMPLETION(khpsbpkt_complete);
static LIST_HEAD(hpsbpkt_list);
static DECLARE_MUTEX_LOCKED(khpsbpkt_sig);
static spinlock_t khpsbpkt_lock = SPIN_LOCK_UNLOCKED;
static void run_packet_complete(struct hpsb_packet *packet)
{
void (*complete_routine)(void*) = packet->complete_routine;
void *complete_data = packet->complete_data;
packet->complete_routine = NULL;
packet->complete_data = NULL;
complete_routine(complete_data);
return;
}
static void queue_packet_complete(struct hpsb_packet *packet)
{
if (packet->complete_routine != NULL) {
unsigned long flags;
spin_lock_irqsave(&khpsbpkt_lock, flags);
list_add_tail(&packet->list, &hpsbpkt_list);
spin_unlock_irqrestore(&khpsbpkt_lock, flags);
/* Signal the kernel thread to handle this */
up(&khpsbpkt_sig);
}
return;
}
static int hpsbpkt_thread(void *__hi)
{
struct hpsb_packet *packet, *next;
unsigned long flags;
daemonize("khpsbpkt");
allow_signal(SIGTERM);
while (!down_interruptible(&khpsbpkt_sig)) {
spin_lock_irqsave(&khpsbpkt_lock, flags);
list_for_each_entry_safe(packet, next, &hpsbpkt_list, list) {
list_del(&packet->list);
run_packet_complete(packet);
}
spin_unlock_irqrestore(&khpsbpkt_lock, flags);
}
complete_and_exit(&khpsbpkt_complete, 0);
}
static int __init ieee1394_init(void) static int __init ieee1394_init(void)
{ {
int i; int i;
khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL);
if (khpsbpkt_pid < 0) {
HPSB_ERR("Failed to start hpsbpkt thread!\n");
return -ENOMEM;
}
devfs_mk_dir("ieee1394"); devfs_mk_dir("ieee1394");
if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) { if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) {
...@@ -1034,6 +1083,11 @@ static void __exit ieee1394_cleanup(void) ...@@ -1034,6 +1083,11 @@ static void __exit ieee1394_cleanup(void)
bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
bus_unregister(&ieee1394_bus_type); bus_unregister(&ieee1394_bus_type);
if (khpsbpkt_pid >= 0) {
kill_proc(khpsbpkt_pid, SIGTERM, 1);
wait_for_completion(&khpsbpkt_complete);
}
kmem_cache_destroy(hpsb_packet_cache); kmem_cache_destroy(hpsb_packet_cache);
unregister_chrdev_region(IEEE1394_CORE_DEV, 256); unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment