Commit 2e59e6aa authored by Ben Collins's avatar Ben Collins

Merge

parents 5e681ee3 ea123a24
...@@ -251,8 +251,7 @@ static void add_host(struct hpsb_host *host) ...@@ -251,8 +251,7 @@ static void add_host(struct hpsb_host *host)
csr1212_init_local_csr(host->csr.rom, bus_info, host->csr.max_rom); csr1212_init_local_csr(host->csr.rom, bus_info, host->csr.max_rom);
host->csr.rom->max_rom = host->csr.max_rom; static const int mr_map[] = { 4, 64, 1024, 0 };
root = host->csr.rom->root_kv; root = host->csr.rom->root_kv;
if(csr1212_attach_keyval_to_directory(root, node_cap) != CSR1212_SUCCESS) { if(csr1212_attach_keyval_to_directory(root, node_cap) != CSR1212_SUCCESS) {
......
...@@ -206,7 +206,9 @@ struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops, ...@@ -206,7 +206,9 @@ struct csr1212_csr *csr1212_create_csr(struct csr1212_bus_ops *ops,
void csr1212_init_local_csr(struct csr1212_csr *csr, void csr1212_init_local_csr(struct csr1212_csr *csr,
const u_int32_t *bus_info_data, int max_rom) const u_int32_t *bus_info_data, int max_rom)
{ {
csr->max_rom = max_rom; static const int mr_map[] = { 4, 64, 1024, 0 };
csr->max_rom = mr_map[max_rom];
memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len); memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
} }
......
...@@ -187,6 +187,9 @@ int hpsb_add_host(struct hpsb_host *host) ...@@ -187,6 +187,9 @@ int hpsb_add_host(struct hpsb_host *host)
void hpsb_remove_host(struct hpsb_host *host) void hpsb_remove_host(struct hpsb_host *host)
{ {
host->is_shutdown = 1; host->is_shutdown = 1;
del_timer_sync(&host->delayed_reset);
host->driver = &dummy_driver; host->driver = &dummy_driver;
highlevel_remove_host(host); highlevel_remove_host(host);
......
...@@ -400,31 +400,35 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) ...@@ -400,31 +400,35 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
int ackcode) int ackcode)
{ {
unsigned long flags;
spin_lock_irqsave(&host->pending_packet_queue.lock, flags);
packet->ack_code = ackcode; packet->ack_code = ackcode;
if (packet->no_waiter) { if (packet->no_waiter || packet->state == hpsb_complete) {
/* must not have a tlabel allocated */ /* if packet->no_waiter, must not have a tlabel allocated */
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
hpsb_free_packet(packet); hpsb_free_packet(packet);
return; return;
} }
atomic_dec(&packet->refcnt); /* drop HC's reference */
/* here the packet must be on the host->pending_packet_queue */
if (ackcode != ACK_PENDING || !packet->expect_response) { if (ackcode != ACK_PENDING || !packet->expect_response) {
atomic_dec(&packet->refcnt);
skb_unlink(packet->skb);
packet->state = hpsb_complete; packet->state = hpsb_complete;
__skb_unlink(packet->skb, &host->pending_packet_queue);
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
queue_packet_complete(packet); queue_packet_complete(packet);
return; return;
} }
if (packet->state == hpsb_complete) {
hpsb_free_packet(packet);
return;
}
atomic_dec(&packet->refcnt);
packet->state = hpsb_pending; packet->state = hpsb_pending;
packet->sendtime = jiffies; packet->sendtime = jiffies;
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
mod_timer(&host->timeout, jiffies + host->timeout_interval); mod_timer(&host->timeout, jiffies + host->timeout_interval);
} }
...@@ -658,14 +662,13 @@ static void handle_packet_response(struct hpsb_host *host, int tcode, ...@@ -658,14 +662,13 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
} }
if (!tcode_match) { if (!tcode_match) {
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
HPSB_INFO("unsolicited response packet received - tcode mismatch"); HPSB_INFO("unsolicited response packet received - tcode mismatch");
dump_packet("contents:", data, 16); dump_packet("contents:", data, 16);
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
return; return;
} }
__skb_unlink(skb, skb->list); __skb_unlink(skb, skb->list);
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
if (packet->state == hpsb_queued) { if (packet->state == hpsb_queued) {
packet->sendtime = jiffies; packet->sendtime = jiffies;
...@@ -673,6 +676,8 @@ static void handle_packet_response(struct hpsb_host *host, int tcode, ...@@ -673,6 +676,8 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
} }
packet->state = hpsb_complete; packet->state = hpsb_complete;
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
queue_packet_complete(packet); queue_packet_complete(packet);
} }
...@@ -1002,6 +1007,10 @@ static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); ...@@ -1002,6 +1007,10 @@ static DECLARE_MUTEX_LOCKED(khpsbpkt_sig);
static void queue_packet_complete(struct hpsb_packet *packet) static void queue_packet_complete(struct hpsb_packet *packet)
{ {
if (packet->no_waiter) {
hpsb_free_packet(packet);
return;
}
if (packet->complete_routine != NULL) { if (packet->complete_routine != NULL) {
skb_queue_tail(&hpsbpkt_queue, packet->skb); skb_queue_tail(&hpsbpkt_queue, packet->skb);
...@@ -1042,10 +1051,11 @@ static int hpsbpkt_thread(void *__hi) ...@@ -1042,10 +1051,11 @@ static int hpsbpkt_thread(void *__hi)
static int __init ieee1394_init(void) static int __init ieee1394_init(void)
{ {
int i; int i, ret;
skb_queue_head_init(&hpsbpkt_queue); skb_queue_head_init(&hpsbpkt_queue);
/* non-fatal error */
if (hpsb_init_config_roms()) { if (hpsb_init_config_roms()) {
HPSB_ERR("Failed to initialize some config rom entries.\n"); HPSB_ERR("Failed to initialize some config rom entries.\n");
HPSB_ERR("Some features may not be available\n"); HPSB_ERR("Some features may not be available\n");
...@@ -1054,32 +1064,85 @@ static int __init ieee1394_init(void) ...@@ -1054,32 +1064,85 @@ static int __init ieee1394_init(void)
khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL); khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL);
if (khpsbpkt_pid < 0) { if (khpsbpkt_pid < 0) {
HPSB_ERR("Failed to start hpsbpkt thread!\n"); HPSB_ERR("Failed to start hpsbpkt thread!\n");
return -ENOMEM; ret = -ENOMEM;
goto exit_cleanup_config_roms;
} }
devfs_mk_dir("ieee1394");
if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) { if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) {
HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR); HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
return -ENODEV; ret = -ENODEV;
goto exit_release_kernel_thread;
}
/* actually this is a non-fatal error */
ret = devfs_mk_dir("ieee1394");
if (ret < 0) {
HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR);
goto release_chrdev;
} }
devfs_mk_dir("ieee1394"); ret = bus_register(&ieee1394_bus_type);
if (ret < 0) {
HPSB_INFO("bus register failed");
goto release_devfs;
}
bus_register(&ieee1394_bus_type); for (i = 0; fw_bus_attrs[i]; i++) {
for (i = 0; fw_bus_attrs[i]; i++) ret = bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]);
bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]); if (ret < 0) {
class_register(&hpsb_host_class); while (i >= 0) {
bus_remove_file(&ieee1394_bus_type,
fw_bus_attrs[i--]);
}
bus_unregister(&ieee1394_bus_type);
goto release_devfs;
}
}
if (init_csr()) ret = class_register(&hpsb_host_class);
return -ENOMEM; if (ret < 0)
goto release_all_bus;
if (!disable_nodemgr) ret = init_csr();
init_ieee1394_nodemgr(); if (ret) {
else HPSB_INFO("init csr failed");
ret = -ENOMEM;
goto release_class;
}
if (disable_nodemgr) {
HPSB_INFO("nodemgr functionality disabled"); HPSB_INFO("nodemgr functionality disabled");
return 0;
}
ret = init_ieee1394_nodemgr();
if (ret < 0) {
HPSB_INFO("init nodemgr failed");
goto cleanup_csr;
}
return 0; return 0;
cleanup_csr:
cleanup_csr();
release_class:
class_unregister(&hpsb_host_class);
release_all_bus:
for (i = 0; fw_bus_attrs[i]; i++)
bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
bus_unregister(&ieee1394_bus_type);
release_devfs:
devfs_remove("ieee1394");
release_chrdev:
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
exit_release_kernel_thread:
if (khpsbpkt_pid >= 0) {
kill_proc(khpsbpkt_pid, SIGTERM, 1);
wait_for_completion(&khpsbpkt_complete);
}
exit_cleanup_config_roms:
hpsb_cleanup_config_roms();
return ret;
} }
static void __exit ieee1394_cleanup(void) static void __exit ieee1394_cleanup(void)
......
...@@ -101,8 +101,6 @@ void hpsb_free_packet(struct hpsb_packet *packet); ...@@ -101,8 +101,6 @@ void hpsb_free_packet(struct hpsb_packet *packet);
* *
* Use the functions, not the variable. * Use the functions, not the variable.
*/ */
#include <asm/atomic.h>
static inline unsigned int get_hpsb_generation(struct hpsb_host *host) static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
{ {
return atomic_read(&host->generation); return atomic_read(&host->generation);
......
...@@ -1502,6 +1502,10 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1502,6 +1502,10 @@ static int nodemgr_host_thread(void *__hi)
* start the the waiting over again */ * start the the waiting over again */
while (!down_trylock(&hi->reset_sem)) while (!down_trylock(&hi->reset_sem))
i = 0; i = 0;
/* Check the kill_me again */
if (hi->kill_me)
goto caught_signal;
} }
if (!nodemgr_check_irm_capability(host, reset_cycles)) { if (!nodemgr_check_irm_capability(host, reset_cycles)) {
...@@ -1702,12 +1706,23 @@ static struct hpsb_highlevel nodemgr_highlevel = { ...@@ -1702,12 +1706,23 @@ static struct hpsb_highlevel nodemgr_highlevel = {
.remove_host = nodemgr_remove_host, .remove_host = nodemgr_remove_host,
}; };
void init_ieee1394_nodemgr(void) int init_ieee1394_nodemgr(void)
{ {
class_register(&nodemgr_ne_class); int ret;
class_register(&nodemgr_ud_class);
ret = class_register(&nodemgr_ne_class);
if (ret < 0)
return ret;
ret = class_register(&nodemgr_ud_class);
if (ret < 0) {
class_unregister(&nodemgr_ne_class);
return ret;
}
hpsb_register_highlevel(&nodemgr_highlevel); hpsb_register_highlevel(&nodemgr_highlevel);
return 0;
} }
void cleanup_ieee1394_nodemgr(void) void cleanup_ieee1394_nodemgr(void)
......
...@@ -192,7 +192,7 @@ int hpsb_node_lock(struct node_entry *ne, u64 addr, ...@@ -192,7 +192,7 @@ int hpsb_node_lock(struct node_entry *ne, u64 addr,
int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)); int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
void init_ieee1394_nodemgr(void); int init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void); void cleanup_ieee1394_nodemgr(void);
......
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