Commit b4b7f2a6 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/firewire' into for-linus

Pull FireWire fixes
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 5f5d8890 a7ecbe92
...@@ -668,6 +668,7 @@ EXPORT_SYMBOL_GPL(fw_card_release); ...@@ -668,6 +668,7 @@ EXPORT_SYMBOL_GPL(fw_card_release);
void fw_core_remove_card(struct fw_card *card) void fw_core_remove_card(struct fw_card *card)
{ {
struct fw_card_driver dummy_driver = dummy_driver_template; struct fw_card_driver dummy_driver = dummy_driver_template;
unsigned long flags;
card->driver->update_phy_reg(card, 4, card->driver->update_phy_reg(card, 4,
PHY_LINK_ACTIVE | PHY_CONTENDER, 0); PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
...@@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_card *card) ...@@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_card *card)
dummy_driver.stop_iso = card->driver->stop_iso; dummy_driver.stop_iso = card->driver->stop_iso;
card->driver = &dummy_driver; card->driver = &dummy_driver;
spin_lock_irqsave(&card->lock, flags);
fw_destroy_nodes(card); fw_destroy_nodes(card);
spin_unlock_irqrestore(&card->lock, flags);
/* Wait for all users, especially device workqueue jobs, to finish. */ /* Wait for all users, especially device workqueue jobs, to finish. */
fw_card_put(card); fw_card_put(card);
......
...@@ -1500,6 +1500,7 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, ...@@ -1500,6 +1500,7 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
{ {
struct outbound_phy_packet_event *e = struct outbound_phy_packet_event *e =
container_of(packet, struct outbound_phy_packet_event, p); container_of(packet, struct outbound_phy_packet_event, p);
struct client *e_client;
switch (status) { switch (status) {
/* expected: */ /* expected: */
...@@ -1516,9 +1517,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, ...@@ -1516,9 +1517,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
} }
e->phy_packet.data[0] = packet->timestamp; e->phy_packet.data[0] = packet->timestamp;
e_client = e->client;
queue_event(e->client, &e->event, &e->phy_packet, queue_event(e->client, &e->event, &e->phy_packet,
sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
client_put(e->client); client_put(e_client);
} }
static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
......
...@@ -375,16 +375,13 @@ static void report_found_node(struct fw_card *card, ...@@ -375,16 +375,13 @@ static void report_found_node(struct fw_card *card,
card->bm_retries = 0; card->bm_retries = 0;
} }
/* Must be called with card->lock held */
void fw_destroy_nodes(struct fw_card *card) void fw_destroy_nodes(struct fw_card *card)
{ {
unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
card->color++; card->color++;
if (card->local_node != NULL) if (card->local_node != NULL)
for_each_fw_node(card, card->local_node, report_lost_node); for_each_fw_node(card, card->local_node, report_lost_node);
card->local_node = NULL; card->local_node = NULL;
spin_unlock_irqrestore(&card->lock, flags);
} }
static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
...@@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, ...@@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
struct fw_node *local_node; struct fw_node *local_node;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
/* /*
* If the selfID buffer is not the immediate successor of the * If the selfID buffer is not the immediate successor of the
* previously processed one, we cannot reliably compare the * previously processed one, we cannot reliably compare the
...@@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, ...@@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
card->bm_retries = 0; card->bm_retries = 0;
} }
spin_lock_irqsave(&card->lock, flags);
card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated;
card->node_id = node_id; card->node_id = node_id;
/* /*
......
...@@ -73,24 +73,25 @@ static int try_cancel_split_timeout(struct fw_transaction *t) ...@@ -73,24 +73,25 @@ static int try_cancel_split_timeout(struct fw_transaction *t)
static int close_transaction(struct fw_transaction *transaction, static int close_transaction(struct fw_transaction *transaction,
struct fw_card *card, int rcode) struct fw_card *card, int rcode)
{ {
struct fw_transaction *t; struct fw_transaction *t = NULL, *iter;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) { list_for_each_entry(iter, &card->transaction_list, link) {
if (t == transaction) { if (iter == transaction) {
if (!try_cancel_split_timeout(t)) { if (!try_cancel_split_timeout(iter)) {
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
goto timed_out; goto timed_out;
} }
list_del_init(&t->link); list_del_init(&iter->link);
card->tlabel_mask &= ~(1ULL << t->tlabel); card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
break; break;
} }
} }
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
if (&t->link != &card->transaction_list) { if (t) {
t->callback(card, rcode, NULL, 0, t->callback_data); t->callback(card, rcode, NULL, 0, t->callback_data);
return 0; return 0;
} }
...@@ -935,7 +936,7 @@ EXPORT_SYMBOL(fw_core_handle_request); ...@@ -935,7 +936,7 @@ EXPORT_SYMBOL(fw_core_handle_request);
void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
{ {
struct fw_transaction *t; struct fw_transaction *t = NULL, *iter;
unsigned long flags; unsigned long flags;
u32 *data; u32 *data;
size_t data_length; size_t data_length;
...@@ -947,20 +948,21 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) ...@@ -947,20 +948,21 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
rcode = HEADER_GET_RCODE(p->header[1]); rcode = HEADER_GET_RCODE(p->header[1]);
spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags);
list_for_each_entry(t, &card->transaction_list, link) { list_for_each_entry(iter, &card->transaction_list, link) {
if (t->node_id == source && t->tlabel == tlabel) { if (iter->node_id == source && iter->tlabel == tlabel) {
if (!try_cancel_split_timeout(t)) { if (!try_cancel_split_timeout(iter)) {
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
goto timed_out; goto timed_out;
} }
list_del_init(&t->link); list_del_init(&iter->link);
card->tlabel_mask &= ~(1ULL << t->tlabel); card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
break; break;
} }
} }
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
if (&t->link == &card->transaction_list) { if (!t) {
timed_out: timed_out:
fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", fw_notice(card, "unsolicited response (source %x, tlabel %x)\n",
source, tlabel); source, tlabel);
......
...@@ -408,7 +408,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, ...@@ -408,7 +408,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
void *payload, size_t length, void *callback_data) void *payload, size_t length, void *callback_data)
{ {
struct sbp2_logical_unit *lu = callback_data; struct sbp2_logical_unit *lu = callback_data;
struct sbp2_orb *orb; struct sbp2_orb *orb = NULL, *iter;
struct sbp2_status status; struct sbp2_status status;
unsigned long flags; unsigned long flags;
...@@ -433,17 +433,18 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, ...@@ -433,17 +433,18 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
/* Lookup the orb corresponding to this status write. */ /* Lookup the orb corresponding to this status write. */
spin_lock_irqsave(&lu->tgt->lock, flags); spin_lock_irqsave(&lu->tgt->lock, flags);
list_for_each_entry(orb, &lu->orb_list, link) { list_for_each_entry(iter, &lu->orb_list, link) {
if (STATUS_GET_ORB_HIGH(status) == 0 && if (STATUS_GET_ORB_HIGH(status) == 0 &&
STATUS_GET_ORB_LOW(status) == orb->request_bus) { STATUS_GET_ORB_LOW(status) == iter->request_bus) {
orb->rcode = RCODE_COMPLETE; iter->rcode = RCODE_COMPLETE;
list_del(&orb->link); list_del(&iter->link);
orb = iter;
break; break;
} }
} }
spin_unlock_irqrestore(&lu->tgt->lock, flags); spin_unlock_irqrestore(&lu->tgt->lock, flags);
if (&orb->link != &lu->orb_list) { if (orb) {
orb->callback(orb, &status); orb->callback(orb, &status);
kref_put(&orb->kref, free_orb); /* orb callback reference */ kref_put(&orb->kref, free_orb); /* orb callback reference */
} else { } else {
......
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