summaryrefslogtreecommitdiff
path: root/drivers/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/Kconfig6
-rw-r--r--drivers/firewire/core-cdev.c27
-rw-r--r--drivers/firewire/core-device.c4
-rw-r--r--drivers/firewire/net.c469
-rw-r--r--drivers/firewire/ohci.c270
-rw-r--r--drivers/firewire/sbp2.c10
6 files changed, 401 insertions, 385 deletions
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 7224533e8ca6..7a701a58bbf0 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -47,9 +47,9 @@ config FIREWIRE_NET
tristate "IP networking over 1394"
depends on FIREWIRE && INET
help
- This enables IPv4 over IEEE 1394, providing IP connectivity with
- other implementations of RFC 2734 as found on several operating
- systems. Multicast support is currently limited.
+ This enables IPv4/IPv6 over IEEE 1394, providing IP connectivity
+ with other implementations of RFC 2734/3146 as found on several
+ operating systems. Multicast support is currently limited.
To compile this driver as a module, say M here: The module will be
called firewire-net.
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 27ac423ab25e..7ef316fdc4d9 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -389,10 +389,8 @@ static void queue_bus_reset_event(struct client *client)
struct bus_reset_event *e;
e = kzalloc(sizeof(*e), GFP_KERNEL);
- if (e == NULL) {
- fw_notice(client->device->card, "out of memory when allocating event\n");
+ if (e == NULL)
return;
- }
fill_bus_reset_event(&e->reset, client);
@@ -693,10 +691,9 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
r = kmalloc(sizeof(*r), GFP_ATOMIC);
e = kmalloc(sizeof(*e), GFP_ATOMIC);
- if (r == NULL || e == NULL) {
- fw_notice(card, "out of memory when allocating event\n");
+ if (r == NULL || e == NULL)
goto failed;
- }
+
r->card = card;
r->request = request;
r->data = payload;
@@ -930,10 +927,9 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle,
struct iso_interrupt_event *e;
e = kmalloc(sizeof(*e) + header_length, GFP_ATOMIC);
- if (e == NULL) {
- fw_notice(context->card, "out of memory when allocating event\n");
+ if (e == NULL)
return;
- }
+
e->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
e->interrupt.closure = client->iso_closure;
e->interrupt.cycle = cycle;
@@ -950,10 +946,9 @@ static void iso_mc_callback(struct fw_iso_context *context,
struct iso_interrupt_mc_event *e;
e = kmalloc(sizeof(*e), GFP_ATOMIC);
- if (e == NULL) {
- fw_notice(context->card, "out of memory when allocating event\n");
+ if (e == NULL)
return;
- }
+
e->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL;
e->interrupt.closure = client->iso_closure;
e->interrupt.completed = fw_iso_buffer_lookup(&client->buffer,
@@ -1366,8 +1361,7 @@ static int init_iso_resource(struct client *client,
int ret;
if ((request->channels == 0 && request->bandwidth == 0) ||
- request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
- request->bandwidth < 0)
+ request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL)
return -EINVAL;
r = kmalloc(sizeof(*r), GFP_KERNEL);
@@ -1582,10 +1576,9 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p)
list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) {
e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
- if (e == NULL) {
- fw_notice(card, "out of memory when allocating event\n");
+ if (e == NULL)
break;
- }
+
e->phy_packet.closure = client->phy_receiver_closure;
e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED;
e->phy_packet.rcode = RCODE_COMPLETE;
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 03ce7d980c6a..664a6ff0a823 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -692,10 +692,8 @@ static void create_units(struct fw_device *device)
* match the drivers id_tables against it.
*/
unit = kzalloc(sizeof(*unit), GFP_KERNEL);
- if (unit == NULL) {
- fw_err(device->card, "out of memory for unit\n");
+ if (unit == NULL)
continue;
- }
unit->directory = ci.p + value - 1;
unit->device.bus = &fw_bus_type;
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 2b27bff2591a..815b0fcbe918 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1,5 +1,6 @@
/*
* IPv4 over IEEE 1394, per RFC 2734
+ * IPv6 over IEEE 1394, per RFC 3146
*
* Copyright (C) 2009 Jay Fenlason <fenlason@redhat.com>
*
@@ -28,6 +29,7 @@
#include <asm/unaligned.h>
#include <net/arp.h>
+#include <net/firewire.h>
/* rx limits */
#define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */
@@ -45,6 +47,7 @@
#define IANA_SPECIFIER_ID 0x00005eU
#define RFC2734_SW_VERSION 0x000001U
+#define RFC3146_SW_VERSION 0x000002U
#define IEEE1394_GASP_HDR_SIZE 8
@@ -57,32 +60,10 @@
#define RFC2374_HDR_LASTFRAG 2 /* last fragment */
#define RFC2374_HDR_INTFRAG 3 /* interior fragment */
-#define RFC2734_HW_ADDR_LEN 16
-
-struct rfc2734_arp {
- __be16 hw_type; /* 0x0018 */
- __be16 proto_type; /* 0x0806 */
- u8 hw_addr_len; /* 16 */
- u8 ip_addr_len; /* 4 */
- __be16 opcode; /* ARP Opcode */
- /* Above is exactly the same format as struct arphdr */
-
- __be64 s_uniq_id; /* Sender's 64bit EUI */
- u8 max_rec; /* Sender's max packet size */
- u8 sspd; /* Sender's max speed */
- __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
- __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
- __be32 sip; /* Sender's IP Address */
- __be32 tip; /* IP Address of requested hw addr */
-} __packed;
-
-/* This header format is specific to this driver implementation. */
-#define FWNET_ALEN 8
-#define FWNET_HLEN 10
-struct fwnet_header {
- u8 h_dest[FWNET_ALEN]; /* destination address */
- __be16 h_proto; /* packet type ID field */
-} __packed;
+static bool fwnet_hwaddr_is_multicast(u8 *ha)
+{
+ return !!(*ha & 1);
+}
/* IPv4 and IPv6 encapsulation header */
struct rfc2734_header {
@@ -191,8 +172,6 @@ struct fwnet_peer {
struct list_head peer_link;
struct fwnet_device *dev;
u64 guid;
- u64 fifo;
- __be32 ip;
/* guarded by dev->lock */
struct list_head pd_list; /* received partial datagrams */
@@ -222,6 +201,15 @@ struct fwnet_packet_task {
};
/*
+ * Get fifo address embedded in hwaddr
+ */
+static __u64 fwnet_hwaddr_fifo(union fwnet_hwaddr *ha)
+{
+ return (u64)get_unaligned_be16(&ha->uc.fifo_hi) << 32
+ | get_unaligned_be32(&ha->uc.fifo_lo);
+}
+
+/*
* saddr == NULL means use device source address.
* daddr == NULL means leave destination address (eg unresolved arp).
*/
@@ -368,10 +356,8 @@ static struct fwnet_fragment_info *fwnet_frag_new(
}
new = kmalloc(sizeof(*new), GFP_ATOMIC);
- if (!new) {
- dev_err(&pd->skb->dev->dev, "out of memory\n");
+ if (!new)
return NULL;
- }
new->offset = offset;
new->len = len;
@@ -414,8 +400,6 @@ fail_w_fi:
fail_w_new:
kfree(new);
fail:
- dev_err(&net->dev, "out of memory\n");
-
return NULL;
}
@@ -513,10 +497,20 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
bool is_broadcast, u16 ether_type)
{
struct fwnet_device *dev;
- static const __be64 broadcast_hw = cpu_to_be64(~0ULL);
int status;
__be64 guid;
+ switch (ether_type) {
+ case ETH_P_ARP:
+ case ETH_P_IP:
+#if IS_ENABLED(CONFIG_IPV6)
+ case ETH_P_IPV6:
+#endif
+ break;
+ default:
+ goto err;
+ }
+
dev = netdev_priv(net);
/* Write metadata, and then pass to the receive level */
skb->dev = net;
@@ -524,92 +518,11 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
/*
* Parse the encapsulation header. This actually does the job of
- * converting to an ethernet frame header, as well as arp
- * conversion if needed. ARP conversion is easier in this
- * direction, since we are using ethernet as our backend.
+ * converting to an ethernet-like pseudo frame header.
*/
- /*
- * If this is an ARP packet, convert it. First, we want to make
- * use of some of the fields, since they tell us a little bit
- * about the sending machine.
- */
- if (ether_type == ETH_P_ARP) {
- struct rfc2734_arp *arp1394;
- struct arphdr *arp;
- unsigned char *arp_ptr;
- u64 fifo_addr;
- u64 peer_guid;
- unsigned sspd;
- u16 max_payload;
- struct fwnet_peer *peer;
- unsigned long flags;
-
- arp1394 = (struct rfc2734_arp *)skb->data;
- arp = (struct arphdr *)skb->data;
- arp_ptr = (unsigned char *)(arp + 1);
- peer_guid = get_unaligned_be64(&arp1394->s_uniq_id);
- fifo_addr = (u64)get_unaligned_be16(&arp1394->fifo_hi) << 32
- | get_unaligned_be32(&arp1394->fifo_lo);
-
- sspd = arp1394->sspd;
- /* Sanity check. OS X 10.3 PPC reportedly sends 131. */
- if (sspd > SCODE_3200) {
- dev_notice(&net->dev, "sspd %x out of range\n", sspd);
- sspd = SCODE_3200;
- }
- max_payload = fwnet_max_payload(arp1394->max_rec, sspd);
-
- spin_lock_irqsave(&dev->lock, flags);
- peer = fwnet_peer_find_by_guid(dev, peer_guid);
- if (peer) {
- peer->fifo = fifo_addr;
-
- if (peer->speed > sspd)
- peer->speed = sspd;
- if (peer->max_payload > max_payload)
- peer->max_payload = max_payload;
-
- peer->ip = arp1394->sip;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (!peer) {
- dev_notice(&net->dev,
- "no peer for ARP packet from %016llx\n",
- (unsigned long long)peer_guid);
- goto no_peer;
- }
-
- /*
- * Now that we're done with the 1394 specific stuff, we'll
- * need to alter some of the data. Believe it or not, all
- * that needs to be done is sender_IP_address needs to be
- * moved, the destination hardware address get stuffed
- * in and the hardware address length set to 8.
- *
- * IMPORTANT: The code below overwrites 1394 specific data
- * needed above so keep the munging of the data for the
- * higher level IP stack last.
- */
-
- arp->ar_hln = 8;
- /* skip over sender unique id */
- arp_ptr += arp->ar_hln;
- /* move sender IP addr */
- put_unaligned(arp1394->sip, (u32 *)arp_ptr);
- /* skip over sender IP addr */
- arp_ptr += arp->ar_pln;
-
- if (arp->ar_op == htons(ARPOP_REQUEST))
- memset(arp_ptr, 0, sizeof(u64));
- else
- memcpy(arp_ptr, net->dev_addr, sizeof(u64));
- }
-
- /* Now add the ethernet header. */
guid = cpu_to_be64(dev->card->guid);
if (dev_hard_header(skb, net, ether_type,
- is_broadcast ? &broadcast_hw : &guid,
+ is_broadcast ? net->broadcast : net->dev_addr,
NULL, skb->len) >= 0) {
struct fwnet_header *eth;
u16 *rawp;
@@ -618,7 +531,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
skb_reset_mac_header(skb);
skb_pull(skb, sizeof(*eth));
eth = (struct fwnet_header *)skb_mac_header(skb);
- if (*eth->h_dest & 1) {
+ if (fwnet_hwaddr_is_multicast(eth->h_dest)) {
if (memcmp(eth->h_dest, net->broadcast,
net->addr_len) == 0)
skb->pkt_type = PACKET_BROADCAST;
@@ -630,7 +543,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
if (memcmp(eth->h_dest, net->dev_addr, net->addr_len))
skb->pkt_type = PACKET_OTHERHOST;
}
- if (ntohs(eth->h_proto) >= 1536) {
+ if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) {
protocol = eth->h_proto;
} else {
rawp = (u16 *)skb->data;
@@ -652,7 +565,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
return 0;
- no_peer:
+ err:
net->stats.rx_errors++;
net->stats.rx_dropped++;
@@ -692,7 +605,6 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
skb = dev_alloc_skb(len + LL_RESERVED_SPACE(net));
if (unlikely(!skb)) {
- dev_err(&net->dev, "out of memory\n");
net->stats.rx_dropped++;
return -ENOMEM;
@@ -856,7 +768,12 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
- if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
+ if (specifier_id == IANA_SPECIFIER_ID &&
+ (ver == RFC2734_SW_VERSION
+#if IS_ENABLED(CONFIG_IPV6)
+ || ver == RFC3146_SW_VERSION
+#endif
+ )) {
buf_ptr += 2;
length -= IEEE1394_GASP_HDR_SIZE;
fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
@@ -1059,16 +976,27 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
u8 *p;
int generation;
int node_id;
+ unsigned int sw_version;
/* ptask->generation may not have been set yet */
generation = dev->card->generation;
smp_rmb();
node_id = dev->card->node_id;
+ switch (ptask->skb->protocol) {
+ default:
+ sw_version = RFC2734_SW_VERSION;
+ break;
+#if IS_ENABLED(CONFIG_IPV6)
+ case htons(ETH_P_IPV6):
+ sw_version = RFC3146_SW_VERSION;
+#endif
+ }
+
p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE);
put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p);
put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24
- | RFC2734_SW_VERSION, &p[4]);
+ | sw_version, &p[4]);
/* We should not transmit if broadcast_channel.valid == 0. */
fw_send_request(dev->card, &ptask->transaction,
@@ -1116,6 +1044,62 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
return 0;
}
+static void fwnet_fifo_stop(struct fwnet_device *dev)
+{
+ if (dev->local_fifo == FWNET_NO_FIFO_ADDR)
+ return;
+
+ fw_core_remove_address_handler(&dev->handler);
+ dev->local_fifo = FWNET_NO_FIFO_ADDR;
+}
+
+static int fwnet_fifo_start(struct fwnet_device *dev)
+{
+ int retval;
+
+ if (dev->local_fifo != FWNET_NO_FIFO_ADDR)
+ return 0;
+
+ dev->handler.length = 4096;
+ dev->handler.address_callback = fwnet_receive_packet;
+ dev->handler.callback_data = dev;
+
+ retval = fw_core_add_address_handler(&dev->handler,
+ &fw_high_memory_region);
+ if (retval < 0)
+ return retval;
+
+ dev->local_fifo = dev->handler.offset;
+
+ return 0;
+}
+
+static void __fwnet_broadcast_stop(struct fwnet_device *dev)
+{
+ unsigned u;
+
+ if (dev->broadcast_state != FWNET_BROADCAST_ERROR) {
+ for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++)
+ kunmap(dev->broadcast_rcv_buffer.pages[u]);
+ fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card);
+ }
+ if (dev->broadcast_rcv_context) {
+ fw_iso_context_destroy(dev->broadcast_rcv_context);
+ dev->broadcast_rcv_context = NULL;
+ }
+ kfree(dev->broadcast_rcv_buffer_ptrs);
+ dev->broadcast_rcv_buffer_ptrs = NULL;
+ dev->broadcast_state = FWNET_BROADCAST_ERROR;
+}
+
+static void fwnet_broadcast_stop(struct fwnet_device *dev)
+{
+ if (dev->broadcast_state == FWNET_BROADCAST_ERROR)
+ return;
+ fw_iso_context_stop(dev->broadcast_rcv_context);
+ __fwnet_broadcast_stop(dev);
+}
+
static int fwnet_broadcast_start(struct fwnet_device *dev)
{
struct fw_iso_context *context;
@@ -1124,60 +1108,47 @@ static int fwnet_broadcast_start(struct fwnet_device *dev)
unsigned max_receive;
struct fw_iso_packet packet;
unsigned long offset;
+ void **ptrptr;
unsigned u;
- if (dev->local_fifo == FWNET_NO_FIFO_ADDR) {
- dev->handler.length = 4096;
- dev->handler.address_callback = fwnet_receive_packet;
- dev->handler.callback_data = dev;
-
- retval = fw_core_add_address_handler(&dev->handler,
- &fw_high_memory_region);
- if (retval < 0)
- goto failed_initial;
-
- dev->local_fifo = dev->handler.offset;
- }
+ if (dev->broadcast_state != FWNET_BROADCAST_ERROR)
+ return 0;
max_receive = 1U << (dev->card->max_receive + 1);
num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive;
- if (!dev->broadcast_rcv_context) {
- void **ptrptr;
-
- context = fw_iso_context_create(dev->card,
- FW_ISO_CONTEXT_RECEIVE, IEEE1394_BROADCAST_CHANNEL,
- dev->card->link_speed, 8, fwnet_receive_broadcast, dev);
- if (IS_ERR(context)) {
- retval = PTR_ERR(context);
- goto failed_context_create;
- }
+ ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL);
+ if (!ptrptr) {
+ retval = -ENOMEM;
+ goto failed;
+ }
+ dev->broadcast_rcv_buffer_ptrs = ptrptr;
+
+ context = fw_iso_context_create(dev->card, FW_ISO_CONTEXT_RECEIVE,
+ IEEE1394_BROADCAST_CHANNEL,
+ dev->card->link_speed, 8,
+ fwnet_receive_broadcast, dev);
+ if (IS_ERR(context)) {
+ retval = PTR_ERR(context);
+ goto failed;
+ }
- retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer,
- dev->card, FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE);
- if (retval < 0)
- goto failed_buffer_init;
+ retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card,
+ FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE);
+ if (retval < 0)
+ goto failed;
- ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL);
- if (!ptrptr) {
- retval = -ENOMEM;
- goto failed_ptrs_alloc;
- }
+ dev->broadcast_state = FWNET_BROADCAST_STOPPED;
- dev->broadcast_rcv_buffer_ptrs = ptrptr;
- for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) {
- void *ptr;
- unsigned v;
+ for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) {
+ void *ptr;
+ unsigned v;
- ptr = kmap(dev->broadcast_rcv_buffer.pages[u]);
- for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++)
- *ptrptr++ = (void *)
- ((char *)ptr + v * max_receive);
- }
- dev->broadcast_rcv_context = context;
- } else {
- context = dev->broadcast_rcv_context;
+ ptr = kmap(dev->broadcast_rcv_buffer.pages[u]);
+ for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++)
+ *ptrptr++ = (void *) ((char *)ptr + v * max_receive);
}
+ dev->broadcast_rcv_context = context;
packet.payload_length = max_receive;
packet.interrupt = 1;
@@ -1191,7 +1162,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev)
retval = fw_iso_context_queue(context, &packet,
&dev->broadcast_rcv_buffer, offset);
if (retval < 0)
- goto failed_rcv_queue;
+ goto failed;
offset += max_receive;
}
@@ -1201,7 +1172,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev)
retval = fw_iso_context_start(context, -1, 0,
FW_ISO_CONTEXT_MATCH_ALL_TAGS); /* ??? sync */
if (retval < 0)
- goto failed_rcv_queue;
+ goto failed;
/* FIXME: adjust it according to the min. speed of all known peers? */
dev->broadcast_xmt_max_payload = IEEE1394_MAX_PAYLOAD_S100
@@ -1210,19 +1181,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev)
return 0;
- failed_rcv_queue:
- kfree(dev->broadcast_rcv_buffer_ptrs);
- dev->broadcast_rcv_buffer_ptrs = NULL;
- failed_ptrs_alloc:
- fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card);
- failed_buffer_init:
- fw_iso_context_destroy(context);
- dev->broadcast_rcv_context = NULL;
- failed_context_create:
- fw_core_remove_address_handler(&dev->handler);
- failed_initial:
- dev->local_fifo = FWNET_NO_FIFO_ADDR;
-
+ failed:
+ __fwnet_broadcast_stop(dev);
return retval;
}
@@ -1240,11 +1200,10 @@ static int fwnet_open(struct net_device *net)
struct fwnet_device *dev = netdev_priv(net);
int ret;
- if (dev->broadcast_state == FWNET_BROADCAST_ERROR) {
- ret = fwnet_broadcast_start(dev);
- if (ret)
- return ret;
- }
+ ret = fwnet_broadcast_start(dev);
+ if (ret)
+ return ret;
+
netif_start_queue(net);
spin_lock_irq(&dev->lock);
@@ -1257,9 +1216,10 @@ static int fwnet_open(struct net_device *net)
/* ifdown */
static int fwnet_stop(struct net_device *net)
{
- netif_stop_queue(net);
+ struct fwnet_device *dev = netdev_priv(net);
- /* Deallocate iso context for use by other applications? */
+ netif_stop_queue(net);
+ fwnet_broadcast_stop(dev);
return 0;
}
@@ -1299,19 +1259,27 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
* We might need to rebuild the header on tx failure.
*/
memcpy(&hdr_buf, skb->data, sizeof(hdr_buf));
- skb_pull(skb, sizeof(hdr_buf));
-
proto = hdr_buf.h_proto;
+
+ switch (proto) {
+ case htons(ETH_P_ARP):
+ case htons(ETH_P_IP):
+#if IS_ENABLED(CONFIG_IPV6)
+ case htons(ETH_P_IPV6):
+#endif
+ break;
+ default:
+ goto fail;
+ }
+
+ skb_pull(skb, sizeof(hdr_buf));
dg_size = skb->len;
/*
* Set the transmission type for the packet. ARP packets and IP
* broadcast packets are sent via GASP.
*/
- if (memcmp(hdr_buf.h_dest, net->broadcast, FWNET_ALEN) == 0
- || proto == htons(ETH_P_ARP)
- || (proto == htons(ETH_P_IP)
- && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
+ if (fwnet_hwaddr_is_multicast(hdr_buf.h_dest)) {
max_payload = dev->broadcast_xmt_max_payload;
datagram_label_ptr = &dev->broadcast_xmt_datagramlabel;
@@ -1320,11 +1288,12 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
ptask->dest_node = IEEE1394_ALL_NODES;
ptask->speed = SCODE_100;
} else {
- __be64 guid = get_unaligned((__be64 *)hdr_buf.h_dest);
+ union fwnet_hwaddr *ha = (union fwnet_hwaddr *)hdr_buf.h_dest;
+ __be64 guid = get_unaligned(&ha->uc.uniq_id);
u8 generation;
peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid));
- if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR)
+ if (!peer)
goto fail;
generation = peer->generation;
@@ -1332,32 +1301,12 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
max_payload = peer->max_payload;
datagram_label_ptr = &peer->datagram_label;
- ptask->fifo_addr = peer->fifo;
+ ptask->fifo_addr = fwnet_hwaddr_fifo(ha);
ptask->generation = generation;
ptask->dest_node = dest_node;
ptask->speed = peer->speed;
}
- /* If this is an ARP packet, convert it */
- if (proto == htons(ETH_P_ARP)) {
- struct arphdr *arp = (struct arphdr *)skb->data;
- unsigned char *arp_ptr = (unsigned char *)(arp + 1);
- struct rfc2734_arp *arp1394 = (struct rfc2734_arp *)skb->data;
- __be32 ipaddr;
-
- ipaddr = get_unaligned((__be32 *)(arp_ptr + FWNET_ALEN));
-
- arp1394->hw_addr_len = RFC2734_HW_ADDR_LEN;
- arp1394->max_rec = dev->card->max_receive;
- arp1394->sspd = dev->card->link_speed;
-
- put_unaligned_be16(dev->local_fifo >> 32,
- &arp1394->fifo_hi);
- put_unaligned_be32(dev->local_fifo & 0xffffffff,
- &arp1394->fifo_lo);
- put_unaligned(ipaddr, &arp1394->sip);
- }
-
ptask->hdr.w0 = 0;
ptask->hdr.w1 = 0;
ptask->skb = skb;
@@ -1472,8 +1421,6 @@ static int fwnet_add_peer(struct fwnet_device *dev,
peer->dev = dev;
peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
- peer->fifo = FWNET_NO_FIFO_ADDR;
- peer->ip = 0;
INIT_LIST_HEAD(&peer->pd_list);
peer->pdg_size = 0;
peer->datagram_label = 0;
@@ -1503,6 +1450,7 @@ static int fwnet_probe(struct device *_dev)
struct fwnet_device *dev;
unsigned max_mtu;
int ret;
+ union fwnet_hwaddr *ha;
mutex_lock(&fwnet_device_mutex);
@@ -1533,6 +1481,11 @@ static int fwnet_probe(struct device *_dev)
dev->card = card;
dev->netdev = net;
+ ret = fwnet_fifo_start(dev);
+ if (ret < 0)
+ goto out;
+ dev->local_fifo = dev->handler.offset;
+
/*
* Use the RFC 2734 default 1500 octets or the maximum payload
* as initial MTU
@@ -1542,24 +1495,31 @@ static int fwnet_probe(struct device *_dev)
net->mtu = min(1500U, max_mtu);
/* Set our hardware address while we're at it */
- put_unaligned_be64(card->guid, net->dev_addr);
- put_unaligned_be64(~0ULL, net->broadcast);
+ ha = (union fwnet_hwaddr *)net->dev_addr;
+ put_unaligned_be64(card->guid, &ha->uc.uniq_id);
+ ha->uc.max_rec = dev->card->max_receive;
+ ha->uc.sspd = dev->card->link_speed;
+ put_unaligned_be16(dev->local_fifo >> 32, &ha->uc.fifo_hi);
+ put_unaligned_be32(dev->local_fifo & 0xffffffff, &ha->uc.fifo_lo);
+
+ memset(net->broadcast, -1, net->addr_len);
+
ret = register_netdev(net);
if (ret)
goto out;
list_add_tail(&dev->dev_link, &fwnet_device_list);
- dev_notice(&net->dev, "IPv4 over IEEE 1394 on card %s\n",
+ dev_notice(&net->dev, "IP over IEEE 1394 on card %s\n",
dev_name(card->device));
have_dev:
ret = fwnet_add_peer(dev, unit, device);
if (ret && allocated_netdev) {
unregister_netdev(net);
list_del(&dev->dev_link);
- }
out:
- if (ret && allocated_netdev)
+ fwnet_fifo_stop(dev);
free_netdev(net);
+ }
mutex_unlock(&fwnet_device_mutex);
@@ -1592,22 +1552,14 @@ static int fwnet_remove(struct device *_dev)
mutex_lock(&fwnet_device_mutex);
net = dev->netdev;
- if (net && peer->ip)
- arp_invalidate(net, peer->ip);
fwnet_remove_peer(peer, dev);
if (list_empty(&dev->peer_list)) {
unregister_netdev(net);
- if (dev->local_fifo != FWNET_NO_FIFO_ADDR)
- fw_core_remove_address_handler(&dev->handler);
- if (dev->broadcast_rcv_context) {
- fw_iso_context_stop(dev->broadcast_rcv_context);
- fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer,
- dev->card);
- fw_iso_context_destroy(dev->broadcast_rcv_context);
- }
+ fwnet_fifo_stop(dev);
+
for (i = 0; dev->queued_datagrams && i < 5; i++)
ssleep(1);
WARN_ON(dev->queued_datagrams);
@@ -1646,6 +1598,14 @@ static const struct ieee1394_device_id fwnet_id_table[] = {
.specifier_id = IANA_SPECIFIER_ID,
.version = RFC2734_SW_VERSION,
},
+#if IS_ENABLED(CONFIG_IPV6)
+ {
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
+ IEEE1394_MATCH_VERSION,
+ .specifier_id = IANA_SPECIFIER_ID,
+ .version = RFC3146_SW_VERSION,
+ },
+#endif
{ }
};
@@ -1683,6 +1643,30 @@ static struct fw_descriptor rfc2374_unit_directory = {
.data = rfc2374_unit_directory_data
};
+#if IS_ENABLED(CONFIG_IPV6)
+static const u32 rfc3146_unit_directory_data[] = {
+ 0x00040000, /* directory_length */
+ 0x1200005e, /* unit_specifier_id: IANA */
+ 0x81000003, /* textual descriptor offset */
+ 0x13000002, /* unit_sw_version: RFC 3146 */
+ 0x81000005, /* textual descriptor offset */
+ 0x00030000, /* descriptor_length */
+ 0x00000000, /* text */
+ 0x00000000, /* minimal ASCII, en */
+ 0x49414e41, /* I A N A */
+ 0x00030000, /* descriptor_length */
+ 0x00000000, /* text */
+ 0x00000000, /* minimal ASCII, en */
+ 0x49507636, /* I P v 6 */
+};
+
+static struct fw_descriptor rfc3146_unit_directory = {
+ .length = ARRAY_SIZE(rfc3146_unit_directory_data),
+ .key = (CSR_DIRECTORY | CSR_UNIT) << 24,
+ .data = rfc3146_unit_directory_data
+};
+#endif
+
static int __init fwnet_init(void)
{
int err;
@@ -1691,11 +1675,17 @@ static int __init fwnet_init(void)
if (err)
return err;
+#if IS_ENABLED(CONFIG_IPV6)
+ err = fw_core_add_descriptor(&rfc3146_unit_directory);
+ if (err)
+ goto out;
+#endif
+
fwnet_packet_task_cache = kmem_cache_create("packet_task",
sizeof(struct fwnet_packet_task), 0, 0, NULL);
if (!fwnet_packet_task_cache) {
err = -ENOMEM;
- goto out;
+ goto out2;
}
err = driver_register(&fwnet_driver.driver);
@@ -1703,7 +1693,11 @@ static int __init fwnet_init(void)
return 0;
kmem_cache_destroy(fwnet_packet_task_cache);
+out2:
+#if IS_ENABLED(CONFIG_IPV6)
+ fw_core_remove_descriptor(&rfc3146_unit_directory);
out:
+#endif
fw_core_remove_descriptor(&rfc2374_unit_directory);
return err;
@@ -1714,11 +1708,14 @@ static void __exit fwnet_cleanup(void)
{
driver_unregister(&fwnet_driver.driver);
kmem_cache_destroy(fwnet_packet_task_cache);
+#if IS_ENABLED(CONFIG_IPV6)
+ fw_core_remove_descriptor(&rfc3146_unit_directory);
+#endif
fw_core_remove_descriptor(&rfc2374_unit_directory);
}
module_exit(fwnet_cleanup);
MODULE_AUTHOR("Jay Fenlason <fenlason@redhat.com>");
-MODULE_DESCRIPTION("IPv4 over IEEE1394 as per RFC 2734");
+MODULE_DESCRIPTION("IP over IEEE1394 as per RFC 2734/3146");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(ieee1394, fwnet_id_table);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 45912e6e0ac2..9e1db6490b9a 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -54,6 +54,10 @@
#include "core.h"
#include "ohci.h"
+#define ohci_info(ohci, f, args...) dev_info(ohci->card.device, f, ##args)
+#define ohci_notice(ohci, f, args...) dev_notice(ohci->card.device, f, ##args)
+#define ohci_err(ohci, f, args...) dev_err(ohci->card.device, f, ##args)
+
#define DESCRIPTOR_OUTPUT_MORE 0
#define DESCRIPTOR_OUTPUT_LAST (1 << 12)
#define DESCRIPTOR_INPUT_MORE (2 << 12)
@@ -68,6 +72,8 @@
#define DESCRIPTOR_BRANCH_ALWAYS (3 << 2)
#define DESCRIPTOR_WAIT (3 << 0)
+#define DESCRIPTOR_CMD (0xf << 12)
+
struct descriptor {
__le16 req_count;
__le16 control;
@@ -149,10 +155,11 @@ struct context {
struct descriptor *last;
/*
- * The last descriptor in the DMA program. It contains the branch
+ * The last descriptor block in the DMA program. It contains the branch
* address that must be updated upon appending a new descriptor.
*/
struct descriptor *prev;
+ int prev_z;
descriptor_callback_t callback;
@@ -270,7 +277,9 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025
+#define PCI_DEVICE_ID_VIA_VT630X 0x3044
#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
+#define PCI_REV_ID_VIA_VT6306 0x46
#define QUIRK_CYCLE_TIMER 1
#define QUIRK_RESET_PACKET 2
@@ -278,6 +287,8 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define QUIRK_NO_1394A 8
#define QUIRK_NO_MSI 16
#define QUIRK_TI_SLLZ059 32
+#define QUIRK_IR_WAKE 64
+#define QUIRK_PHY_LCTRL_TIMEOUT 128
/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
@@ -290,7 +301,10 @@ static const struct {
QUIRK_BE_HEADERS},
{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
- QUIRK_NO_MSI},
+ QUIRK_PHY_LCTRL_TIMEOUT | QUIRK_NO_MSI},
+
+ {PCI_VENDOR_ID_ATT, PCI_ANY_ID, PCI_ANY_ID,
+ QUIRK_PHY_LCTRL_TIMEOUT},
{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
QUIRK_RESET_PACKET},
@@ -319,6 +333,9 @@ static const struct {
{PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_RESET_PACKET},
+ {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT630X, PCI_REV_ID_VIA_VT6306,
+ QUIRK_CYCLE_TIMER | QUIRK_IR_WAKE},
+
{PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
};
@@ -333,6 +350,8 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
", no 1394a enhancements = " __stringify(QUIRK_NO_1394A)
", disable MSI = " __stringify(QUIRK_NO_MSI)
", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059)
+ ", IR wake unreliable = " __stringify(QUIRK_IR_WAKE)
+ ", phy LCtrl timeout = " __stringify(QUIRK_PHY_LCTRL_TIMEOUT)
")");
#define OHCI_PARAM_DEBUG_AT_AR 1
@@ -359,8 +378,7 @@ static void log_irqs(struct fw_ohci *ohci, u32 evt)
!(evt & OHCI1394_busReset))
return;
- dev_notice(ohci->card.device,
- "IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+ ohci_notice(ohci, "IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
evt & OHCI1394_selfIDComplete ? " selfID" : "",
evt & OHCI1394_RQPkt ? " AR_req" : "",
evt & OHCI1394_RSPkt ? " AR_resp" : "",
@@ -406,21 +424,19 @@ static void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count)
if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS)))
return;
- dev_notice(ohci->card.device,
- "%d selfIDs, generation %d, local node ID %04x\n",
- self_id_count, generation, ohci->node_id);
+ ohci_notice(ohci, "%d selfIDs, generation %d, local node ID %04x\n",
+ self_id_count, generation, ohci->node_id);
for (s = ohci->self_id_buffer; self_id_count--; ++s)
if ((*s & 1 << 23) == 0)
- dev_notice(ohci->card.device,
- "selfID 0: %08x, phy %d [%c%c%c] "
- "%s gc=%d %s %s%s%s\n",
+ ohci_notice(ohci,
+ "selfID 0: %08x, phy %d [%c%c%c] %s gc=%d %s %s%s%s\n",
*s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
speed[*s >> 14 & 3], *s >> 16 & 63,
power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
*s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "");
else
- dev_notice(ohci->card.device,
+ ohci_notice(ohci,
"selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n",
*s, *s >> 24 & 63,
_p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
@@ -470,9 +486,8 @@ static void log_ar_at_event(struct fw_ohci *ohci,
evt = 0x1f;
if (evt == OHCI1394_evt_bus_reset) {
- dev_notice(ohci->card.device,
- "A%c evt_bus_reset, generation %d\n",
- dir, (header[2] >> 16) & 0xff);
+ ohci_notice(ohci, "A%c evt_bus_reset, generation %d\n",
+ dir, (header[2] >> 16) & 0xff);
return;
}
@@ -491,32 +506,26 @@ static void log_ar_at_event(struct fw_ohci *ohci,
switch (tcode) {
case 0xa:
- dev_notice(ohci->card.device,
- "A%c %s, %s\n",
- dir, evts[evt], tcodes[tcode]);
+ ohci_notice(ohci, "A%c %s, %s\n",
+ dir, evts[evt], tcodes[tcode]);
break;
case 0xe:
- dev_notice(ohci->card.device,
- "A%c %s, PHY %08x %08x\n",
- dir, evts[evt], header[1], header[2]);
+ ohci_notice(ohci, "A%c %s, PHY %08x %08x\n",
+ dir, evts[evt], header[1], header[2]);
break;
case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
- dev_notice(ohci->card.device,
- "A%c spd %x tl %02x, "
- "%04x -> %04x, %s, "
- "%s, %04x%08x%s\n",
- dir, speed, header[0] >> 10 & 0x3f,
- header[1] >> 16, header[0] >> 16, evts[evt],
- tcodes[tcode], header[1] & 0xffff, header[2], specific);
+ ohci_notice(ohci,
+ "A%c spd %x tl %02x, %04x -> %04x, %s, %s, %04x%08x%s\n",
+ dir, speed, header[0] >> 10 & 0x3f,
+ header[1] >> 16, header[0] >> 16, evts[evt],
+ tcodes[tcode], header[1] & 0xffff, header[2], specific);
break;
default:
- dev_notice(ohci->card.device,
- "A%c spd %x tl %02x, "
- "%04x -> %04x, %s, "
- "%s%s\n",
- dir, speed, header[0] >> 10 & 0x3f,
- header[1] >> 16, header[0] >> 16, evts[evt],
- tcodes[tcode], specific);
+ ohci_notice(ohci,
+ "A%c spd %x tl %02x, %04x -> %04x, %s, %s%s\n",
+ dir, speed, header[0] >> 10 & 0x3f,
+ header[1] >> 16, header[0] >> 16, evts[evt],
+ tcodes[tcode], specific);
}
}
@@ -563,7 +572,8 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr)
if (i >= 3)
msleep(1);
}
- dev_err(ohci->card.device, "failed to read phy reg\n");
+ ohci_err(ohci, "failed to read phy reg %d\n", addr);
+ dump_stack();
return -EBUSY;
}
@@ -585,7 +595,8 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val)
if (i >= 3)
msleep(1);
}
- dev_err(ohci->card.device, "failed to write phy reg\n");
+ ohci_err(ohci, "failed to write phy reg %d, val %u\n", addr, val);
+ dump_stack();
return -EBUSY;
}
@@ -690,8 +701,7 @@ static void ar_context_abort(struct ar_context *ctx, const char *error_msg)
reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
flush_writes(ohci);
- dev_err(ohci->card.device, "AR error: %s; DMA stopped\n",
- error_msg);
+ ohci_err(ohci, "AR error: %s; DMA stopped\n", error_msg);
}
/* FIXME: restart? */
}
@@ -1157,6 +1167,7 @@ static int context_init(struct context *ctx, struct fw_ohci *ohci,
ctx->buffer_tail->used += sizeof(*ctx->buffer_tail->buffer);
ctx->last = ctx->buffer_tail->buffer;
ctx->prev = ctx->buffer_tail->buffer;
+ ctx->prev_z = 1;
return 0;
}
@@ -1221,14 +1232,35 @@ static void context_append(struct context *ctx,
{
dma_addr_t d_bus;
struct descriptor_buffer *desc = ctx->buffer_tail;
+ struct descriptor *d_branch;
d_bus = desc->buffer_bus + (d - desc->buffer) * sizeof(*d);
desc->used += (z + extra) * sizeof(*d);
wmb(); /* finish init of new descriptors before branch_address update */
- ctx->prev->branch_address = cpu_to_le32(d_bus | z);
- ctx->prev = find_branch_descriptor(d, z);
+
+ d_branch = find_branch_descriptor(ctx->prev, ctx->prev_z);
+ d_branch->branch_address = cpu_to_le32(d_bus | z);
+
+ /*
+ * VT6306 incorrectly checks only the single descriptor at the
+ * CommandPtr when the wake bit is written, so if it's a
+ * multi-descriptor block starting with an INPUT_MORE, put a copy of
+ * the branch address in the first descriptor.
+ *
+ * Not doing this for transmit contexts since not sure how it interacts
+ * with skip addresses.
+ */
+ if (unlikely(ctx->ohci->quirks & QUIRK_IR_WAKE) &&
+ d_branch != ctx->prev &&
+ (ctx->prev->control & cpu_to_le16(DESCRIPTOR_CMD)) ==
+ cpu_to_le16(DESCRIPTOR_INPUT_MORE)) {
+ ctx->prev->branch_address = cpu_to_le32(d_bus | z);
+ }
+
+ ctx->prev = d;
+ ctx->prev_z = z;
}
static void context_stop(struct context *ctx)
@@ -1248,7 +1280,7 @@ static void context_stop(struct context *ctx)
if (i)
udelay(10);
}
- dev_err(ohci->card.device, "DMA context still active (0x%08x)\n", reg);
+ ohci_err(ohci, "DMA context still active (0x%08x)\n", reg);
}
struct driver_data {
@@ -1557,7 +1589,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
goto out;
}
- dev_err(ohci->card.device, "swap not done (CSR lock timeout)\n");
+ ohci_err(ohci, "swap not done (CSR lock timeout)\n");
fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
out:
@@ -1632,8 +1664,7 @@ static void detect_dead_context(struct fw_ohci *ohci,
ctl = reg_read(ohci, CONTROL_SET(regs));
if (ctl & CONTEXT_DEAD)
- dev_err(ohci->card.device,
- "DMA context %s has stopped, error code: %s\n",
+ ohci_err(ohci, "DMA context %s has stopped, error code: %s\n",
name, evts[ctl & 0x1f]);
}
@@ -1815,8 +1846,8 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
reg = reg_read(ohci, OHCI1394_NodeID);
if (!(reg & OHCI1394_NodeID_idValid)) {
- dev_notice(ohci->card.device,
- "node ID not valid, new bus reset in progress\n");
+ ohci_notice(ohci,
+ "node ID not valid, new bus reset in progress\n");
return -EBUSY;
}
self_id |= ((reg & 0x3f) << 24); /* phy ID */
@@ -1863,12 +1894,12 @@ static void bus_reset_work(struct work_struct *work)
reg = reg_read(ohci, OHCI1394_NodeID);
if (!(reg & OHCI1394_NodeID_idValid)) {
- dev_notice(ohci->card.device,
- "node ID not valid, new bus reset in progress\n");
+ ohci_notice(ohci,
+ "node ID not valid, new bus reset in progress\n");
return;
}
if ((reg & OHCI1394_NodeID_nodeNumber) == 63) {
- dev_notice(ohci->card.device, "malconfigured bus\n");
+ ohci_notice(ohci, "malconfigured bus\n");
return;
}
ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
@@ -1882,7 +1913,7 @@ static void bus_reset_work(struct work_struct *work)
reg = reg_read(ohci, OHCI1394_SelfIDCount);
if (reg & OHCI1394_SelfIDCount_selfIDError) {
- dev_notice(ohci->card.device, "inconsistent self IDs\n");
+ ohci_notice(ohci, "self ID receive error\n");
return;
}
/*
@@ -1894,7 +1925,7 @@ static void bus_reset_work(struct work_struct *work)
self_id_count = (reg >> 3) & 0xff;
if (self_id_count > 252) {
- dev_notice(ohci->card.device, "inconsistent self IDs\n");
+ ohci_notice(ohci, "bad selfIDSize (%08x)\n", reg);
return;
}
@@ -1902,7 +1933,10 @@ static void bus_reset_work(struct work_struct *work)
rmb();
for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
- if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) {
+ u32 id = cond_le32_to_cpu(ohci->self_id_cpu[i]);
+ u32 id2 = cond_le32_to_cpu(ohci->self_id_cpu[i + 1]);
+
+ if (id != ~id2) {
/*
* If the invalid data looks like a cycle start packet,
* it's likely to be the result of the cycle master
@@ -1910,33 +1944,30 @@ static void bus_reset_work(struct work_struct *work)
* so far are valid and should be processed so that the
* bus manager can then correct the gap count.
*/
- if (cond_le32_to_cpu(ohci->self_id_cpu[i])
- == 0xffff008f) {
- dev_notice(ohci->card.device,
- "ignoring spurious self IDs\n");
+ if (id == 0xffff008f) {
+ ohci_notice(ohci, "ignoring spurious self IDs\n");
self_id_count = j;
break;
- } else {
- dev_notice(ohci->card.device,
- "inconsistent self IDs\n");
- return;
}
+
+ ohci_notice(ohci, "bad self ID %d/%d (%08x != ~%08x)\n",
+ j, self_id_count, id, id2);
+ return;
}
- ohci->self_id_buffer[j] =
- cond_le32_to_cpu(ohci->self_id_cpu[i]);
+ ohci->self_id_buffer[j] = id;
}
if (ohci->quirks & QUIRK_TI_SLLZ059) {
self_id_count = find_and_insert_self_id(ohci, self_id_count);
if (self_id_count < 0) {
- dev_notice(ohci->card.device,
- "could not construct local self ID\n");
+ ohci_notice(ohci,
+ "could not construct local self ID\n");
return;
}
}
if (self_id_count == 0) {
- dev_notice(ohci->card.device, "inconsistent self IDs\n");
+ ohci_notice(ohci, "no self IDs\n");
return;
}
rmb();
@@ -1957,8 +1988,7 @@ static void bus_reset_work(struct work_struct *work)
new_generation = (reg_read(ohci, OHCI1394_SelfIDCount) >> 16) & 0xff;
if (new_generation != generation) {
- dev_notice(ohci->card.device,
- "new bus reset, discarding self ids\n");
+ ohci_notice(ohci, "new bus reset, discarding self ids\n");
return;
}
@@ -2096,7 +2126,7 @@ static irqreturn_t irq_handler(int irq, void *data)
}
if (unlikely(event & OHCI1394_regAccessFail))
- dev_err(ohci->card.device, "register access failure\n");
+ ohci_err(ohci, "register access failure\n");
if (unlikely(event & OHCI1394_postedWriteErr)) {
reg_read(ohci, OHCI1394_PostedWriteAddressHi);
@@ -2104,13 +2134,12 @@ static irqreturn_t irq_handler(int irq, void *data)
reg_write(ohci, OHCI1394_IntEventClear,
OHCI1394_postedWriteErr);
if (printk_ratelimit())
- dev_err(ohci->card.device, "PCI posted write error\n");
+ ohci_err(ohci, "PCI posted write error\n");
}
if (unlikely(event & OHCI1394_cycleTooLong)) {
if (printk_ratelimit())
- dev_notice(ohci->card.device,
- "isochronous cycle too long\n");
+ ohci_notice(ohci, "isochronous cycle too long\n");
reg_write(ohci, OHCI1394_LinkControlSet,
OHCI1394_LinkControl_cycleMaster);
}
@@ -2123,8 +2152,7 @@ static irqreturn_t irq_handler(int irq, void *data)
* them at least two cycles later. (FIXME?)
*/
if (printk_ratelimit())
- dev_notice(ohci->card.device,
- "isochronous cycle inconsistent\n");
+ ohci_notice(ohci, "isochronous cycle inconsistent\n");
}
if (unlikely(event & OHCI1394_unrecoverableError))
@@ -2246,12 +2274,11 @@ static int ohci_enable(struct fw_card *card,
const __be32 *config_rom, size_t length)
{
struct fw_ohci *ohci = fw_ohci(card);
- struct pci_dev *dev = to_pci_dev(card->device);
u32 lps, version, irqs;
int i, ret;
if (software_reset(ohci)) {
- dev_err(card->device, "failed to reset ohci card\n");
+ ohci_err(ohci, "failed to reset ohci card\n");
return -EBUSY;
}
@@ -2262,20 +2289,31 @@ static int ohci_enable(struct fw_card *card,
* will lock up the machine. Wait 50msec to make sure we have
* full link enabled. However, with some cards (well, at least
* a JMicron PCIe card), we have to try again sometimes.
+ *
+ * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but
+ * cannot actually use the phy at that time. These need tens of
+ * millisecods pause between LPS write and first phy access too.
+ *
+ * But do not wait for 50msec on Agere/LSI cards. Their phy
+ * arbitration state machine may time out during such a long wait.
*/
+
reg_write(ohci, OHCI1394_HCControlSet,
OHCI1394_HCControl_LPS |
OHCI1394_HCControl_postedWriteEnable);
flush_writes(ohci);
- for (lps = 0, i = 0; !lps && i < 3; i++) {
+ if (!(ohci->quirks & QUIRK_PHY_LCTRL_TIMEOUT))
msleep(50);
+
+ for (lps = 0, i = 0; !lps && i < 150; i++) {
+ msleep(1);
lps = reg_read(ohci, OHCI1394_HCControlSet) &
OHCI1394_HCControl_LPS;
}
if (!lps) {
- dev_err(card->device, "failed to set Link Power Status\n");
+ ohci_err(ohci, "failed to set Link Power Status\n");
return -EIO;
}
@@ -2284,7 +2322,7 @@ static int ohci_enable(struct fw_card *card,
if (ret < 0)
return ret;
if (ret)
- dev_notice(card->device, "local TSB41BA3D phy\n");
+ ohci_notice(ohci, "local TSB41BA3D phy\n");
else
ohci->quirks &= ~QUIRK_TI_SLLZ059;
}
@@ -2382,24 +2420,6 @@ static int ohci_enable(struct fw_card *card,
reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
- if (!(ohci->quirks & QUIRK_NO_MSI))
- pci_enable_msi(dev);
- if (request_irq(dev->irq, irq_handler,
- pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED,
- ohci_driver_name, ohci)) {
- dev_err(card->device, "failed to allocate interrupt %d\n",
- dev->irq);
- pci_disable_msi(dev);
-
- if (config_rom) {
- dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
- ohci->next_config_rom,
- ohci->next_config_rom_bus);
- ohci->next_config_rom = NULL;
- }
- return -EIO;
- }
-
irqs = OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
OHCI1394_RQPkt | OHCI1394_RSPkt |
OHCI1394_isochTx | OHCI1394_isochRx |
@@ -3578,20 +3598,20 @@ static int pci_probe(struct pci_dev *dev,
if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM) ||
pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) {
- dev_err(&dev->dev, "invalid MMIO resource\n");
+ ohci_err(ohci, "invalid MMIO resource\n");
err = -ENXIO;
goto fail_disable;
}
err = pci_request_region(dev, 0, ohci_driver_name);
if (err) {
- dev_err(&dev->dev, "MMIO resource unavailable\n");
+ ohci_err(ohci, "MMIO resource unavailable\n");
goto fail_disable;
}
ohci->registers = pci_iomap(dev, 0, OHCI1394_REGISTER_SIZE);
if (ohci->registers == NULL) {
- dev_err(&dev->dev, "failed to remap registers\n");
+ ohci_err(ohci, "failed to remap registers\n");
err = -ENXIO;
goto fail_iomem;
}
@@ -3675,19 +3695,33 @@ static int pci_probe(struct pci_dev *dev,
guid = ((u64) reg_read(ohci, OHCI1394_GUIDHi) << 32) |
reg_read(ohci, OHCI1394_GUIDLo);
+ if (!(ohci->quirks & QUIRK_NO_MSI))
+ pci_enable_msi(dev);
+ if (request_irq(dev->irq, irq_handler,
+ pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED,
+ ohci_driver_name, ohci)) {
+ ohci_err(ohci, "failed to allocate interrupt %d\n", dev->irq);
+ err = -EIO;
+ goto fail_msi;
+ }
+
err = fw_card_add(&ohci->card, max_receive, link_speed, guid);
if (err)
- goto fail_contexts;
+ goto fail_irq;
version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
- dev_notice(&dev->dev,
- "added OHCI v%x.%x device as card %d, "
- "%d IR + %d IT contexts, quirks 0x%x\n",
- version >> 16, version & 0xff, ohci->card.index,
- ohci->n_ir, ohci->n_it, ohci->quirks);
+ ohci_notice(ohci,
+ "added OHCI v%x.%x device as card %d, "
+ "%d IR + %d IT contexts, quirks 0x%x\n",
+ version >> 16, version & 0xff, ohci->card.index,
+ ohci->n_ir, ohci->n_it, ohci->quirks);
return 0;
+ fail_irq:
+ free_irq(dev->irq, ohci);
+ fail_msi:
+ pci_disable_msi(dev);
fail_contexts:
kfree(ohci->ir_context_list);
kfree(ohci->it_context_list);
@@ -3711,19 +3745,21 @@ static int pci_probe(struct pci_dev *dev,
kfree(ohci);
pmac_ohci_off(dev);
fail:
- if (err == -ENOMEM)
- dev_err(&dev->dev, "out of memory\n");
-
return err;
}
static void pci_remove(struct pci_dev *dev)
{
- struct fw_ohci *ohci;
+ struct fw_ohci *ohci = pci_get_drvdata(dev);
- ohci = pci_get_drvdata(dev);
- reg_write(ohci, OHCI1394_IntMaskClear, ~0);
- flush_writes(ohci);
+ /*
+ * If the removal is happening from the suspend state, LPS won't be
+ * enabled and host registers (eg., IntMaskClear) won't be accessible.
+ */
+ if (reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_LPS) {
+ reg_write(ohci, OHCI1394_IntMaskClear, ~0);
+ flush_writes(ohci);
+ }
cancel_work_sync(&ohci->bus_reset_work);
fw_core_remove_card(&ohci->card);
@@ -3766,16 +3802,14 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state)
int err;
software_reset(ohci);
- free_irq(dev->irq, ohci);
- pci_disable_msi(dev);
err = pci_save_state(dev);
if (err) {
- dev_err(&dev->dev, "pci_save_state failed\n");
+ ohci_err(ohci, "pci_save_state failed\n");
return err;
}
err = pci_set_power_state(dev, pci_choose_state(dev, state));
if (err)
- dev_err(&dev->dev, "pci_set_power_state failed with %d\n", err);
+ ohci_err(ohci, "pci_set_power_state failed with %d\n", err);
pmac_ohci_off(dev);
return 0;
@@ -3791,7 +3825,7 @@ static int pci_resume(struct pci_dev *dev)
pci_restore_state(dev);
err = pci_enable_device(dev);
if (err) {
- dev_err(&dev->dev, "pci_enable_device failed\n");
+ ohci_err(ohci, "pci_enable_device failed\n");
return err;
}
@@ -3837,6 +3871,4 @@ MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers");
MODULE_LICENSE("GPL");
/* Provide a module alias so root-on-sbp2 initrds don't break. */
-#ifndef CONFIG_IEEE1394_OHCI1394_MODULE
MODULE_ALIAS("ohci1394");
-#endif
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 1162d6b3bf85..47674b913843 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1144,8 +1144,8 @@ static int sbp2_probe(struct device *dev)
return -ENODEV;
if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
- BUG_ON(dma_set_max_seg_size(device->card->device,
- SBP2_MAX_SEG_SIZE));
+ WARN_ON(dma_set_max_seg_size(device->card->device,
+ SBP2_MAX_SEG_SIZE));
shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
if (shost == NULL)
@@ -1475,10 +1475,8 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
}
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
- if (orb == NULL) {
- dev_notice(lu_dev(lu), "failed to alloc ORB\n");
+ if (orb == NULL)
return SCSI_MLQUEUE_HOST_BUSY;
- }
/* Initialize rcode to something not RCODE_COMPLETE. */
orb->base.rcode = -1;
@@ -1636,9 +1634,7 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
/* Provide a module alias so root-on-sbp2 initrds don't break. */
-#ifndef CONFIG_IEEE1394_SBP2_MODULE
MODULE_ALIAS("sbp2");
-#endif
static int __init sbp2_init(void)
{