Commit 9683c74d authored by Ben Collins's avatar Ben Collins

[PATCH] Update IEEE1394 (r946)

 ETH1394: Use 64bit EUI as the hardware address.
 ETH1394: Support broadcast packets.
 SBP2   : Fix max_payload for > S400
 CORE   : Fix iso.c compilation by including linux/sched.h directly.
parent 58552705
...@@ -29,12 +29,11 @@ ...@@ -29,12 +29,11 @@
* *
* TODO: * TODO:
* RFC 2734 related: * RFC 2734 related:
* - Add support for broadcast messages
* - Use EUI instead of node id in internal ARP tables
* - Add Config ROM entry * - Add Config ROM entry
* - Add MCAP and multicast * - Add MCAP and multicast
* *
* Non-RFC 2734 related: * Non-RFC 2734 related:
* - Fix bug related to fragmented broadcast datagrams
* - Move generic GASP reception to core 1394 code * - Move generic GASP reception to core 1394 code
* - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead * - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
* - Stability improvements * - Stability improvements
...@@ -73,6 +72,7 @@ ...@@ -73,6 +72,7 @@
#include "ieee1394.h" #include "ieee1394.h"
#include "highlevel.h" #include "highlevel.h"
#include "iso.h" #include "iso.h"
#include "nodemgr.h"
#include "eth1394.h" #include "eth1394.h"
#define ETH1394_PRINT_G(level, fmt, args...) \ #define ETH1394_PRINT_G(level, fmt, args...) \
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__) #define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 938 $ Ben Collins <bcollins@debian.org>"; "$Rev: 945 $ Ben Collins <bcollins@debian.org>";
struct fragment_info { struct fragment_info {
struct list_head list; struct list_head list;
...@@ -119,22 +119,39 @@ static const int hdr_type_len[] = { ...@@ -119,22 +119,39 @@ static const int hdr_type_len[] = {
sizeof (struct eth1394_sf_hdr) sizeof (struct eth1394_sf_hdr)
}; };
static const u16 eth1394_speedto_maxpayload[] = {
/* S100, S200, S400, S800, S1600, S3200 */
512, 1024, 2048, 4096, 8192, 16384
};
MODULE_AUTHOR("Ben Collins (bcollins@debian.org)"); MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"); MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* The max_partial_datagrams parameter is the maximum number of fragmented datagrams /* The max_partial_datagrams parameter is the maximum number of fragmented
* per node that eth1394 will keep in memory. Providing an upper bound allows us to * datagrams per node that eth1394 will keep in memory. Providing an upper
* limit the amount of memory that partial datagrams consume in the event that some * bound allows us to limit the amount of memory that partial datagrams
* partial datagrams are never completed. This should probably change to a sysctl * consume in the event that some partial datagrams are never completed. This
* item or the like if possible. * should probably change to a sysctl item or the like if possible.
*/ */
MODULE_PARM(max_partial_datagrams, "i"); MODULE_PARM(max_partial_datagrams, "i");
MODULE_PARM_DESC(max_partial_datagrams, MODULE_PARM_DESC(max_partial_datagrams,
"Maximum number of partially received fragmented datagrams (default = 25)."); "Maximum number of partially received fragmented datagrams "
"(default = 25).");
static int max_partial_datagrams = 25; static int max_partial_datagrams = 25;
static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, void *daddr, void *saddr,
unsigned len);
static int ether1394_rebuild_header(struct sk_buff *skb);
static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr);
static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh);
static void ether1394_header_cache_update(struct hh_cache *hh,
struct net_device *dev,
unsigned char * haddr);
static int ether1394_mac_addr(struct net_device *dev, void *p);
static inline void purge_partial_datagram(struct list_head *old); static inline void purge_partial_datagram(struct list_head *old);
static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
static void ether1394_iso(struct hpsb_iso *iso); static void ether1394_iso(struct hpsb_iso *iso);
...@@ -258,73 +275,34 @@ static void ether1394_tx_timeout (struct net_device *dev) ...@@ -258,73 +275,34 @@ static void ether1394_tx_timeout (struct net_device *dev)
netif_wake_queue (dev); netif_wake_queue (dev);
} }
/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the
* entire arphdr) is the same format as the ip1394 header, so they
* overlap. The rest needs to be munged a bit. The remainder of the
* arphdr is formatted based on hwaddr len and ipaddr len. We know what
* they'll be, so it's easy to judge. */
static inline void ether1394_arp_to_1394arp (struct sk_buff *skb, struct net_device *dev)
{
struct eth1394_priv *priv =
(struct eth1394_priv *)(dev->priv);
u16 phy_id = NODEID_TO_NODE(priv->host->node_id);
unsigned char *arp_ptr = (unsigned char *)skb->data;
struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
unsigned char arp_data[2*(dev->addr_len+4)];
/* Copy the main data that we need */
memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data));
/* Extend the buffer enough for our new header */
skb_put (skb, sizeof (struct eth1394_arp) -
(sizeof (arp_data) + sizeof (struct arphdr)));
#define PROCESS_MEMBER(ptr,val,len) \
memcpy (val, ptr, len); ptr += len
arp_ptr = arp_data + arp1394->hw_addr_len;
PROCESS_MEMBER (arp_ptr, &arp1394->sip, arp1394->ip_addr_len);
arp_ptr += arp1394->hw_addr_len;
PROCESS_MEMBER (arp_ptr, &arp1394->tip, arp1394->ip_addr_len);
#undef PROCESS_MEMBER
/* Now add our own flavor of arp header fields to the orig one */
arp1394->hw_addr_len = IP1394_HW_ADDR_LEN;
arp1394->hw_type = __constant_htons (ARPHRD_IEEE1394);
arp1394->s_uniq_id = cpu_to_le64 (priv->eui[phy_id]);
arp1394->max_rec = priv->max_rec[phy_id];
arp1394->sspd = priv->sspd[phy_id];
arp1394->fifo_hi = htons (priv->fifo_hi[phy_id]);
arp1394->fifo_lo = htonl (priv->fifo_lo[phy_id]);
return;
}
static int ether1394_change_mtu(struct net_device *dev, int new_mtu) static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
{ {
if ((new_mtu < 68) || (new_mtu > ETHER1394_REGION_ADDR_LEN)) struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
int phy_id = NODEID_TO_NODE(priv->host->node_id);
if ((new_mtu < 68) || (new_mtu > (priv->maxpayload[phy_id] -
(sizeof(union eth1394_hdr) +
ETHER1394_GASP_OVERHEAD))))
return -EINVAL; return -EINVAL;
dev->mtu = new_mtu; dev->mtu = new_mtu;
return 0; return 0;
} }
static inline void ether1394_register_limits (int nodeid, unsigned char max_rec, static inline void ether1394_register_limits(int nodeid, u16 maxpayload,
unsigned char sspd, u64 eui, u16 fifo_hi, unsigned char sspd, u64 eui, u64 fifo,
u32 fifo_lo, struct eth1394_priv *priv) struct eth1394_priv *priv)
{ {
if (nodeid < 0 || nodeid >= ALL_NODES) { if (nodeid < 0 || nodeid >= ALL_NODES) {
ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid); ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid);
return; return;
} }
priv->max_rec[nodeid] = max_rec; priv->maxpayload[nodeid] = maxpayload;
priv->sspd[nodeid] = sspd; priv->sspd[nodeid] = sspd;
priv->fifo_hi[nodeid] = fifo_hi; priv->fifo[nodeid] = fifo;
priv->fifo_lo[nodeid] = fifo_lo; priv->eui[nodeid] = eui;
priv->eui[nodeid] = eui;
priv->max_rec[ALL_NODES] = min(priv->max_rec[ALL_NODES], max_rec); priv->maxpayload[ALL_NODES] = min(priv->maxpayload[ALL_NODES], maxpayload);
priv->sspd[ALL_NODES] = min(priv->sspd[ALL_NODES], sspd); priv->sspd[ALL_NODES] = min(priv->sspd[ALL_NODES], sspd);
return; return;
...@@ -335,34 +313,44 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) ...@@ -335,34 +313,44 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
unsigned long flags; unsigned long flags;
int i; int i;
struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
int phy_id = NODEID_TO_NODE(priv->host->node_id);
struct hpsb_host *host = priv->host; struct hpsb_host *host = priv->host;
int phy_id = NODEID_TO_NODE(host->node_id);
u64 guid = *((u64*)&(host->csr.rom[3]));
u16 maxpayload = 1 << (((be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf) + 1);
spin_lock_irqsave (&priv->lock, flags); spin_lock_irqsave (&priv->lock, flags);
/* Clear the speed/payload/offset tables */ /* Clear the speed/payload/offset tables */
memset (priv->max_rec, 8, sizeof (priv->max_rec)); memset (priv->maxpayload, 0, sizeof (priv->maxpayload));
memset (priv->sspd, 0, sizeof (priv->sspd)); memset (priv->sspd, 0, sizeof (priv->sspd));
memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi)); memset (priv->fifo, 0, sizeof (priv->fifo));
memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo));
#if 0
/* Compile this out to make testing of fragmented broadcast datagrams
* easier. */
priv->sspd[ALL_NODES] = SPEED_MAX;
priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[SPEED_MAX];
#else
priv->sspd[ALL_NODES] = SPEED_100;
priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[SPEED_100];
#endif
priv->bc_state = ETHER1394_BC_CHECK; priv->bc_state = ETHER1394_BC_CHECK;
/* Register our limits now */ /* Register our limits now */
ether1394_register_limits (phy_id, (be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf, ether1394_register_limits(phy_id, maxpayload,
host->speed_map[(phy_id << 6) + phy_id], host->speed_map[(phy_id << 6) + phy_id],
(u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) | guid, ETHER1394_REGION_ADDR, priv);
be32_to_cpu(host->csr.rom[4])),
ETHER1394_REGION_ADDR >> 32, /* We'll use our maxpayload as the default mtu */
ETHER1394_REGION_ADDR & 0xffffffff, priv); if (set_mtu) {
dev->mtu = priv->maxpayload[phy_id] - (sizeof(union eth1394_hdr) +
/* We'll use our max_rec as the default mtu */ ETHER1394_GASP_OVERHEAD);
if (set_mtu)
dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - /* Set our hardware address while we're at it */
(sizeof (union eth1394_hdr) + ETHER1394_OVERHEAD); *(u64*)dev->dev_addr = guid;
*(u64*)dev->broadcast = ~0x0ULL;
/* Set our hardware address while we're at it */ }
*(nodeid_t *)dev->dev_addr = htons (host->node_id);
spin_unlock_irqrestore (&priv->lock, flags); spin_unlock_irqrestore (&priv->lock, flags);
...@@ -392,11 +380,20 @@ static int ether1394_init_dev (struct net_device *dev) ...@@ -392,11 +380,20 @@ static int ether1394_init_dev (struct net_device *dev)
dev->tx_timeout = ether1394_tx_timeout; dev->tx_timeout = ether1394_tx_timeout;
dev->change_mtu = ether1394_change_mtu; dev->change_mtu = ether1394_change_mtu;
dev->hard_header = ether1394_header;
dev->rebuild_header = ether1394_rebuild_header;
dev->hard_header_cache = ether1394_header_cache;
dev->header_cache_update= ether1394_header_cache_update;
dev->hard_header_parse = ether1394_header_parse;
dev->set_mac_address = ether1394_mac_addr;
/* Some constants */ /* Some constants */
dev->watchdog_timeo = ETHER1394_TIMEOUT; dev->watchdog_timeo = ETHER1394_TIMEOUT;
dev->flags = IFF_BROADCAST; /* TODO: Support MCAP */ dev->flags = IFF_BROADCAST; /* | IFF_MULTICAST someday */
dev->features = NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST; dev->features = NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST;
dev->addr_len = 2; dev->addr_len = ETH1394_ALEN;
dev->hard_header_len = ETH1394_HLEN;
dev->type = ARPHRD_IEEE1394;
ether1394_reset_priv (dev, 1); ether1394_reset_priv (dev, 1);
...@@ -419,6 +416,9 @@ static void ether1394_add_host (struct hpsb_host *host) ...@@ -419,6 +416,9 @@ static void ether1394_add_host (struct hpsb_host *host)
if (version_printed++ == 0) if (version_printed++ == 0)
ETH1394_PRINT_G (KERN_INFO, "%s\n", version); ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
/* We should really have our own alloc_hpsbdev() function in
* net_init.c instead of calling the one for ethernet then hijacking
* it for ourselves. That way we'd be a real networking device. */
dev = alloc_etherdev(sizeof (struct eth1394_priv)); dev = alloc_etherdev(sizeof (struct eth1394_priv));
if (dev == NULL) if (dev == NULL)
...@@ -468,7 +468,7 @@ static void ether1394_add_host (struct hpsb_host *host) ...@@ -468,7 +468,7 @@ static void ether1394_add_host (struct hpsb_host *host)
out: out:
if (dev != NULL) if (dev != NULL)
kfree (dev); dev = NULL; kfree(dev);
if (hi) if (hi)
hpsb_destroy_hostinfo(&eth1394_highlevel, host); hpsb_destroy_hostinfo(&eth1394_highlevel, host);
...@@ -489,7 +489,7 @@ static void ether1394_remove_host (struct hpsb_host *host) ...@@ -489,7 +489,7 @@ static void ether1394_remove_host (struct hpsb_host *host)
unregister_netdev (hi->dev); unregister_netdev (hi->dev);
hpsb_iso_shutdown(priv->iso); hpsb_iso_shutdown(priv->iso);
kfree (hi->dev); hi->dev = NULL; kfree(hi->dev);
} }
return; return;
...@@ -513,31 +513,140 @@ static void ether1394_host_reset (struct hpsb_host *host) ...@@ -513,31 +513,140 @@ static void ether1394_host_reset (struct hpsb_host *host)
netif_wake_queue (dev); netif_wake_queue (dev);
} }
/******************************************
* HW Header net device functions
******************************************/
/* These functions have been adapted from net/ethernet/eth.c */
/* Create a fake MAC header for an arbitrary protocol layer.
* saddr=NULL means use device source address
* daddr=NULL means leave destination address (eg unresolved arp). */
static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
struct eth1394hdr *eth = (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN);
eth->h_proto = htons(type);
if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
{
memset(eth->h_dest, 0, dev->addr_len);
return(dev->hard_header_len);
}
if(daddr)
{
memcpy(eth->h_dest,daddr,dev->addr_len);
return dev->hard_header_len;
}
return -dev->hard_header_len;
}
/* Rebuild the faked MAC header. This is called after an ARP
* (or in future other address resolution) has completed on this
* sk_buff. We now let ARP fill in the other fields.
*
* This routine CANNOT use cached dst->neigh!
* Really, it is used only when dst->neigh is wrong.
*/
static int ether1394_rebuild_header(struct sk_buff *skb)
{
struct eth1394hdr *eth = (struct eth1394hdr *)skb->data;
struct net_device *dev = skb->dev;
switch (eth->h_proto)
{
#ifdef CONFIG_INET
case __constant_htons(ETH_P_IP):
return arp_find((unsigned char*)&eth->h_dest, skb);
#endif
default:
printk(KERN_DEBUG
"%s: unable to resolve type %X addresses.\n",
dev->name, (int)eth->h_proto);
break;
}
return 0;
}
static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr)
{
struct net_device *dev = skb->dev;
memcpy(haddr, dev->dev_addr, ETH1394_ALEN);
return ETH_ALEN;
}
static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{
unsigned short type = hh->hh_type;
struct eth1394hdr *eth = (struct eth1394hdr*)(((u8*)hh->hh_data) + 6);
struct net_device *dev = neigh->dev;
if (type == __constant_htons(ETH_P_802_3)) {
return -1;
}
eth->h_proto = type;
memcpy(eth->h_dest, neigh->ha, dev->addr_len);
hh->hh_len = ETH1394_HLEN;
return 0;
}
/* Called by Address Resolution module to notify changes in address. */
static void ether1394_header_cache_update(struct hh_cache *hh,
struct net_device *dev,
unsigned char * haddr)
{
memcpy(((u8*)hh->hh_data) + 6, haddr, dev->addr_len);
}
static int ether1394_mac_addr(struct net_device *dev, void *p)
{
if (netif_running(dev))
return -EBUSY;
/* Not going to allow setting the MAC address, we really need to use
* the real one suppliled by the hardware */
return -EINVAL;
}
/****************************************** /******************************************
* Datagram reception code * Datagram reception code
******************************************/ ******************************************/
/* Copied from net/ethernet/eth.c */ /* Copied from net/ethernet/eth.c */
static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct net_device *dev) static inline u16 ether1394_type_trans(struct sk_buff *skb,
struct net_device *dev)
{ {
struct ethhdr *eth; struct eth1394hdr *eth;
unsigned char *rawp; unsigned char *rawp;
skb->mac.raw = skb->data; skb->mac.raw = skb->data;
skb_pull (skb, ETH_HLEN); skb_pull (skb, ETH1394_HLEN);
eth = skb->mac.ethernet; eth = (struct eth1394hdr*)skb->mac.raw;
#if 0
if(*eth->h_dest & 1) { if(*eth->h_dest & 1) {
if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0)
skb->pkt_type = PACKET_BROADCAST; skb->pkt_type = PACKET_BROADCAST;
#if 0
else else
skb->pkt_type = PACKET_MULTICAST; skb->pkt_type = PACKET_MULTICAST;
#endif
} else { } else {
if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len))
skb->pkt_type = PACKET_OTHERHOST; skb->pkt_type = PACKET_OTHERHOST;
} }
#endif
if (ntohs (eth->h_proto) >= 1536) if (ntohs (eth->h_proto) >= 1536)
return eth->h_proto; return eth->h_proto;
...@@ -551,56 +660,72 @@ static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct ne ...@@ -551,56 +660,72 @@ static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct ne
/* Parse an encapsulated IP1394 header into an ethernet frame packet. /* Parse an encapsulated IP1394 header into an ethernet frame packet.
* We also perform ARP translation here, if need be. */ * We also perform ARP translation here, if need be. */
static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct net_device *dev, static inline u16 ether1394_parse_encap(struct sk_buff *skb,
nodeid_t srcid, nodeid_t destid, u16 ether_type) struct net_device *dev,
nodeid_t srcid, nodeid_t destid,
u16 ether_type)
{ {
unsigned char src_hw[ETH_ALEN], dest_hw[ETH_ALEN]; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
u64 dest_hw;
unsigned short ret = 0; unsigned short ret = 0;
/* Setup our hw addresses. We use these to build the /* Setup our hw addresses. We use these to build the
* ethernet header. */ * ethernet header. */
*(u16 *)dest_hw = htons(destid); if(destid == (LOCAL_BUS | ALL_NODES))
*(u16 *)src_hw = htons(srcid); dest_hw = ~0ULL; /* broadcast */
else
dest_hw = priv->eui[NODEID_TO_NODE(destid)];
/* If this is an ARP packet, convert it. First, we want to make /* 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 * use of some of the fields, since they tell us a little bit
* about the sending machine. */ * about the sending machine. */
if (ether_type == __constant_htons (ETH_P_ARP)) { if (ether_type == __constant_htons (ETH_P_ARP)) {
unsigned long flags; unsigned long flags;
u16 phy_id = NODEID_TO_NODE(srcid); struct eth1394_arp *arp1394 = (struct eth1394_arp*)skb->data;
struct eth1394_priv *priv =
(struct eth1394_priv *)dev->priv;
struct eth1394_arp arp1394;
struct arphdr *arp = (struct arphdr *)skb->data; struct arphdr *arp = (struct arphdr *)skb->data;
unsigned char *arp_ptr = (unsigned char *)(arp + 1); unsigned char *arp_ptr = (unsigned char *)(arp + 1);
u64 fifo_addr = (u64)ntohs(arp1394->fifo_hi) << 32 |
ntohl(arp1394->fifo_lo);
u8 host_max_rec = (be32_to_cpu(priv->host->csr.rom[2]) >>
12) & 0xf;
u8 max_rec = min(host_max_rec, (u8)(arp1394->max_rec));
u16 maxpayload = min(eth1394_speedto_maxpayload[arp1394->sspd],
(u16)(1 << (max_rec + 1)));
memcpy (&arp1394, arp, sizeof (struct eth1394_arp));
/* Update our speed/payload/fifo_offset table */ /* Update our speed/payload/fifo_offset table */
spin_lock_irqsave (&priv->lock, flags); spin_lock_irqsave (&priv->lock, flags);
ether1394_register_limits (phy_id, arp1394.max_rec, arp1394.sspd, ether1394_register_limits(NODEID_TO_NODE(srcid), maxpayload,
le64_to_cpu (arp1394.s_uniq_id), arp1394->sspd, arp1394->s_uniq_id,
ntohs (arp1394.fifo_hi), fifo_addr, priv);
ntohl (arp1394.fifo_lo), priv);
spin_unlock_irqrestore (&priv->lock, flags); spin_unlock_irqrestore (&priv->lock, flags);
#define PROCESS_MEMBER(ptr,val,len) \ /* Now that we're done with the 1394 specific stuff, we'll
memcpy (ptr, val, len); ptr += len * need to alter some of the data. Believe it or not, all
PROCESS_MEMBER (arp_ptr, src_hw, dev->addr_len); * that needs to be done is sender_IP_address needs to be
PROCESS_MEMBER (arp_ptr, &arp1394.sip, 4); * moved, the destination hardware address get stuffed
PROCESS_MEMBER (arp_ptr, dest_hw, dev->addr_len); * in and the hardware address length set to 8.
PROCESS_MEMBER (arp_ptr, &arp1394.tip, 4); *
#undef PROCESS_MEMBER * IMPORTANT: The code below overwrites 1394 specific data
* needed above data so keep the call to
arp->ar_hln = dev->addr_len; * ether1394_register_limits() before munging the data for the
arp->ar_hrd = __constant_htons (ARPHRD_ETHER); * higher level IP stack. */
skb_trim (skb, sizeof (struct arphdr) + 2*(dev->addr_len+4)); arp->ar_hln = 8;
arp_ptr += arp->ar_hln; /* skip over sender unique id */
*(u32*)arp_ptr = arp1394->sip; /* move sender IP addr */
arp_ptr += arp->ar_pln; /* skip over sender IP addr */
if(arp->ar_op == 1)
/* just set ARP req target unique ID to 0 */
memset(arp_ptr, 0, ETH1394_ALEN);
else
memcpy(arp_ptr, dev->dev_addr, ETH1394_ALEN);
} }
/* Now add the ethernet header. */ /* Now add the ethernet header. */
if (dev->hard_header (skb, dev, __constant_ntohs (ether_type), if (dev->hard_header (skb, dev, __constant_ntohs (ether_type),
dest_hw, src_hw, skb->len) >= 0) &dest_hw, NULL, skb->len) >= 0)
ret = ether1394_type_trans(skb, dev); ret = ether1394_type_trans(skb, dev);
return ret; return ret;
...@@ -651,7 +776,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len) ...@@ -651,7 +776,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */ /* glue fragments together */
fi->len += fi2->len; fi->len += fi2->len;
list_del(lh->next); list_del(lh->next);
kfree(fi2); fi2 = NULL; kfree(fi2);
} }
return 0; return 0;
} else if((offset + len) == fi->offset) { } else if((offset + len) == fi->offset) {
...@@ -664,7 +789,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len) ...@@ -664,7 +789,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
/* glue fragments together */ /* glue fragments together */
fi2->len += fi->len; fi2->len += fi->len;
list_del(lh); list_del(lh);
kfree(fi); fi = NULL; kfree(fi);
} }
return 0; return 0;
} else if(offset > (fi->offset + fi->len)) { } else if(offset > (fi->offset + fi->len)) {
...@@ -701,7 +826,7 @@ static inline int new_partial_datagram(struct net_device *dev, ...@@ -701,7 +826,7 @@ static inline int new_partial_datagram(struct net_device *dev,
INIT_LIST_HEAD(&new->frag_info); INIT_LIST_HEAD(&new->frag_info);
if(new_fragment(&new->frag_info, frag_off, frag_len) < 0) { if(new_fragment(&new->frag_info, frag_off, frag_len) < 0) {
kfree(new); new = NULL; kfree(new);
return -ENOMEM; return -ENOMEM;
} }
...@@ -713,8 +838,8 @@ static inline int new_partial_datagram(struct net_device *dev, ...@@ -713,8 +838,8 @@ static inline int new_partial_datagram(struct net_device *dev,
struct fragment_info *fi = list_entry(new->frag_info.next, struct fragment_info *fi = list_entry(new->frag_info.next,
struct fragment_info, struct fragment_info,
list); list);
kfree(fi); fi = NULL; kfree(fi);
kfree(new); new = NULL; kfree(new);
return -ENOMEM; return -ENOMEM;
} }
...@@ -754,11 +879,11 @@ static inline void purge_partial_datagram(struct list_head *old) ...@@ -754,11 +879,11 @@ static inline void purge_partial_datagram(struct list_head *old)
list_for_each_safe(lh, n, &pd->frag_info) { list_for_each_safe(lh, n, &pd->frag_info) {
struct fragment_info *fi = list_entry(lh, struct fragment_info, list); struct fragment_info *fi = list_entry(lh, struct fragment_info, list);
list_del(lh); list_del(lh);
kfree(fi); fi = NULL; kfree(fi);
} }
list_del(old); list_del(old);
kfree_skb(pd->skb); pd->skb = NULL; kfree_skb(pd->skb);
kfree(pd); pd = NULL; kfree(pd);
} }
static inline int is_datagram_complete(struct list_head *lh, int dg_size) static inline int is_datagram_complete(struct list_head *lh, int dg_size)
...@@ -805,11 +930,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, ...@@ -805,11 +930,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len); memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len);
ether_type = hdr->uf.ether_type; ether_type = hdr->uf.ether_type;
} else { } else {
#if 0
return 0;
}
if(0) {
#endif
/* A datagram fragment has been received, now the fun begins. */ /* A datagram fragment has been received, now the fun begins. */
struct list_head *pdgl, *lh; struct list_head *pdgl, *lh;
...@@ -836,7 +956,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, ...@@ -836,7 +956,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
dg_size = hdr->sf.dg_size; dg_size = hdr->sf.dg_size;
fg_off = hdr->sf.fg_off; fg_off = hdr->sf.fg_off;
} }
spin_lock_irqsave(&pdg->lock, flags); spin_lock_irqsave(&pdg->lock, flags);
pdgl = &(pdg->list); pdgl = &(pdg->list);
...@@ -1010,7 +1129,8 @@ static void ether1394_iso(struct hpsb_iso *iso) ...@@ -1010,7 +1129,8 @@ static void ether1394_iso(struct hpsb_iso *iso)
/* This packet is not for us */ /* This packet is not for us */
continue; continue;
} }
ether1394_data_handler(dev, source_id, iso->host->node_id, buf, len); ether1394_data_handler(dev, source_id, LOCAL_BUS | ALL_NODES,
buf, len);
} }
hpsb_iso_recv_release_packets(iso, i); hpsb_iso_recv_release_packets(iso, i);
...@@ -1022,6 +1142,39 @@ static void ether1394_iso(struct hpsb_iso *iso) ...@@ -1022,6 +1142,39 @@ static void ether1394_iso(struct hpsb_iso *iso)
* Datagram transmission code * Datagram transmission code
******************************************/ ******************************************/
/* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the entire
* arphdr) is the same format as the ip1394 header, so they overlap. The rest
* needs to be munged a bit. The remainder of the arphdr is formatted based
* on hwaddr len and ipaddr len. We know what they'll be, so it's easy to
* judge.
*
* Now that the EUI is used for the hardware address all we need to do to make
* this work for 1394 is to insert 2 quadlets that contain max_rec size,
* speed, and unicast FIFO address information between the sender_unique_id
* and the IP addresses.
*/
static inline void ether1394_arp_to_1394arp(struct sk_buff *skb,
struct net_device *dev)
{
struct eth1394_priv *priv = (struct eth1394_priv *)(dev->priv);
u16 phy_id = NODEID_TO_NODE(priv->host->node_id);
struct arphdr *arp = (struct arphdr *)skb->data;
unsigned char *arp_ptr = (unsigned char *)(arp + 1);
struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
/* Believe it or not, all that need to happen is sender IP get moved
* and set hw_addr_len, max_rec, sspd, fifo_hi and fifo_lo. */
arp1394->hw_addr_len = 16;
arp1394->sip = *(u32*)(arp_ptr + ETH1394_ALEN);
arp1394->max_rec = (be32_to_cpu(priv->host->csr.rom[2]) >> 12) & 0xf;
arp1394->sspd = priv->sspd[phy_id];
arp1394->fifo_hi = htons (priv->fifo[phy_id] >> 32);
arp1394->fifo_lo = htonl (priv->fifo[phy_id] & ~0x0);
return;
}
/* We need to encapsulate the standard header with our own. We use the /* We need to encapsulate the standard header with our own. We use the
* ethernet header's proto for our own. */ * ethernet header's proto for our own. */
static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload, static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
...@@ -1042,7 +1195,6 @@ static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload, ...@@ -1042,7 +1195,6 @@ static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
hdr->ff.dgl = dgl; hdr->ff.dgl = dgl;
adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF]; adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
} }
return((dg_size + (adj_max_payload - 1)) / adj_max_payload); return((dg_size + (adj_max_payload - 1)) / adj_max_payload);
} }
...@@ -1132,27 +1284,33 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p, ...@@ -1132,27 +1284,33 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
} }
static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p, static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p,
struct hpsb_host *host, struct eth1394_priv *priv,
struct sk_buff *skb, int length) struct sk_buff *skb, int length)
{ {
p->header_size = 4; p->header_size = 4;
p->tcode = TCODE_STREAM_DATA; p->tcode = TCODE_STREAM_DATA;
p->header[0] = (length << 16) | (3 << 14) p->header[0] = (length << 16) | (3 << 14)
| ((host->csr.broadcast_channel & 0x3f) << 8) | ((priv->broadcast_channel) << 8)
| (TCODE_STREAM_DATA << 4); | (TCODE_STREAM_DATA << 4);
p->data_size = length; p->data_size = length;
p->data = (quadlet_t*)skb_push(skb, 2 * sizeof(quadlet_t)); p->data = ((quadlet_t*)skb->data) - 2;
p->data[0] = cpu_to_be32((host->node_id << 16) | p->data[0] = cpu_to_be32((priv->host->node_id << 16) |
ETHER1394_GASP_SPECIFIER_ID_HI); ETHER1394_GASP_SPECIFIER_ID_HI);
p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) | p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) |
ETHER1394_GASP_VERSION); ETHER1394_GASP_VERSION);
/* Setting the node id to ALL_NODES (not LOCAL_BUS | ALL_NODES)
* prevents hpsb_send_packet() from setting the speed to an arbitrary
* value based on packet->node_id if packet->node_id is not set. */
p->node_id = ALL_NODES;
p->speed_code = priv->sspd[ALL_NODES];
} }
static inline void ether1394_free_packet(struct hpsb_packet *packet) static inline void ether1394_free_packet(struct hpsb_packet *packet)
{ {
packet->data = NULL; packet->data = NULL;
free_hpsb_packet(packet); packet = NULL; free_hpsb_packet(packet);
} }
static void ether1394_complete_cb(void *__ptask); static void ether1394_complete_cb(void *__ptask);
...@@ -1168,8 +1326,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ...@@ -1168,8 +1326,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
if(ptask->tx_type == ETH1394_GASP) { if(ptask->tx_type == ETH1394_GASP) {
int length = tx_len + (2 * sizeof(quadlet_t)); int length = tx_len + (2 * sizeof(quadlet_t));
ether1394_prep_gasp_packet(packet, priv->host, ether1394_prep_gasp_packet(packet, priv, ptask->skb, length);
ptask->skb, length);
} else { } else {
if(ether1394_prep_write_packet(packet, priv->host, if(ether1394_prep_write_packet(packet, priv->host,
...@@ -1212,8 +1369,8 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail) ...@@ -1212,8 +1369,8 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
dev_kfree_skb_any(skb); skb = NULL; dev_kfree_skb_any(skb);
kmem_cache_free(packet_task_cache, ptask); ptask = NULL; kmem_cache_free(packet_task_cache, ptask);
} }
...@@ -1230,7 +1387,7 @@ static void ether1394_complete_cb(void *__ptask) ...@@ -1230,7 +1387,7 @@ static void ether1394_complete_cb(void *__ptask)
hpsb_free_tlabel(packet); hpsb_free_tlabel(packet);
} }
ether1394_free_packet(packet); packet = ptask->packet = NULL; ether1394_free_packet(packet);
ptask->outstanding_pkts--; ptask->outstanding_pkts--;
if(ptask->outstanding_pkts > 0 && !fail) if(ptask->outstanding_pkts > 0 && !fail)
...@@ -1253,7 +1410,7 @@ static void ether1394_complete_cb(void *__ptask) ...@@ -1253,7 +1410,7 @@ static void ether1394_complete_cb(void *__ptask)
static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
{ {
int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
struct ethhdr *eth; struct eth1394hdr *eth;
struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
int proto; int proto;
unsigned long flags; unsigned long flags;
...@@ -1265,6 +1422,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -1265,6 +1422,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
u16 dg_size; u16 dg_size;
u16 dgl; u16 dgl;
struct packet_task *ptask; struct packet_task *ptask;
struct node_entry *ne;
ptask = kmem_cache_alloc(packet_task_cache, kmflags); ptask = kmem_cache_alloc(packet_task_cache, kmflags);
if(ptask == NULL) { if(ptask == NULL) {
...@@ -1295,34 +1453,44 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -1295,34 +1453,44 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
goto fail; goto fail;
} }
/* Get rid of the ethernet header, but save a pointer */ /* Get rid of the fake eth1394 header, but save a pointer */
eth = (struct ethhdr *)skb->data; eth = (struct eth1394hdr*)skb->data;
skb_pull (skb, ETH_HLEN); skb_pull(skb, ETH1394_HLEN);
ne = hpsb_guid_get_entry(be64_to_cpu(*(u64*)eth->h_dest));
if(!ne)
dest_node = LOCAL_BUS | ALL_NODES;
else
dest_node = ne->nodeid;
/* Save the destination id, and proto for our encapsulation, then
* toss the ethernet header aside like the cheap whore it is. */
dest_node = ntohs (*(nodeid_t *)(eth->h_dest));
proto = eth->h_proto; proto = eth->h_proto;
/* If this is an ARP packet, convert it */ /* If this is an ARP packet, convert it */
if (proto == __constant_htons (ETH_P_ARP)) if (proto == __constant_htons (ETH_P_ARP))
ether1394_arp_to_1394arp (skb, dev); ether1394_arp_to_1394arp (skb, dev);
max_payload = 1 << (min(priv->max_rec[NODEID_TO_NODE(priv->host->node_id)], max_payload = priv->maxpayload[NODEID_TO_NODE(dest_node)];
priv->max_rec[NODEID_TO_NODE(dest_node)]) + 1);
if(max_payload < 512) /* This check should be unnecessary, but we'll keep it for safety for
* a while longer. */
if(max_payload < 512) {
ETH1394_PRINT(KERN_WARNING, dev->name,
"max_payload too small: %d (setting to 512)\n",
max_payload);
max_payload = 512; max_payload = 512;
}
/* Set the transmission type for the packet. Right now only ARP /* Set the transmission type for the packet. ARP packets and IP
* packets are sent via GASP. IP broadcast and IP multicast are not * broadcast packets are sent via GASP, however, we cheat a little bit
* yet supported properly, they too should use GASP. */ * when detecting IP broadcast packets. This will need to change when
switch(proto) { * we switch from using node id for the hardware address to the EUI
case __constant_htons(ETH_P_ARP): * which we should be using instead. IP multicast is not yet
* supported. */
if((memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0) ||
(proto == __constant_htons(ETH_P_ARP))) {
tx_type = ETH1394_GASP; tx_type = ETH1394_GASP;
max_payload -= ETHER1394_OVERHEAD; max_payload -= ETHER1394_GASP_OVERHEAD;
break; } else {
default:
tx_type = ETH1394_WRREQ; tx_type = ETH1394_WRREQ;
} }
...@@ -1345,9 +1513,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -1345,9 +1513,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
if(tx_type != ETH1394_GASP) { if(tx_type != ETH1394_GASP) {
u64 addr; u64 addr;
/* This test is just temporary until ConfigROM support has
* been added to eth1394. Until then, we need an ARP packet
* after a bus reset from the current destination node so that
* we can get FIFO information. */
if(priv->fifo[NODEID_TO_NODE(dest_node)] == 0ULL) {
ret = -EAGAIN;
goto fail;
}
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 | addr = priv->fifo[NODEID_TO_NODE(dest_node)];
priv->fifo_lo[NODEID_TO_NODE(dest_node)];
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
ptask->addr = addr; ptask->addr = addr;
...@@ -1370,11 +1546,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -1370,11 +1546,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
return 0; return 0;
fail: fail:
if(ptask->packet) if(ptask->packet)
ether1394_free_packet(ptask->packet); ptask->packet = NULL; ether1394_free_packet(ptask->packet);
if(ptask) if(ptask)
kmem_cache_free(packet_task_cache, ptask); ptask = NULL; kmem_cache_free(packet_task_cache, ptask);
if(skb != NULL) { if(skb != NULL) {
dev_kfree_skb(skb); skb = NULL; dev_kfree_skb(skb);
} }
spin_lock_irqsave (&priv->lock, flags); spin_lock_irqsave (&priv->lock, flags);
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff) #define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#define ETHER1394_GASP_VERSION 1 #define ETHER1394_GASP_VERSION 1
#define ETHER1394_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */ #define ETHER1394_GASP_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */
/* Node set == 64 */ /* Node set == 64 */
#define NODE_SET (ALL_NODES + 1) #define NODE_SET (ALL_NODES + 1)
...@@ -56,10 +56,9 @@ struct pdg_list { ...@@ -56,10 +56,9 @@ struct pdg_list {
struct eth1394_priv { struct eth1394_priv {
struct net_device_stats stats; /* Device stats */ struct net_device_stats stats; /* Device stats */
struct hpsb_host *host; /* The card for this dev */ struct hpsb_host *host; /* The card for this dev */
unsigned char max_rec[NODE_SET];/* Max payload per node */ u16 maxpayload[NODE_SET]; /* Max payload per node */
unsigned char sspd[NODE_SET]; /* Max speed per node */ unsigned char sspd[NODE_SET]; /* Max speed per node */
u16 fifo_hi[ALL_NODES]; /* 16bit hi fifo offset per node */ u64 fifo[ALL_NODES]; /* FIFO offset per node */
u32 fifo_lo[ALL_NODES]; /* 32bit lo fifo offset per node */
u64 eui[ALL_NODES]; /* EUI-64 per node */ u64 eui[ALL_NODES]; /* EUI-64 per node */
spinlock_t lock; /* Private lock */ spinlock_t lock; /* Private lock */
int broadcast_channel; /* Async stream Broadcast Channel */ int broadcast_channel; /* Async stream Broadcast Channel */
...@@ -74,6 +73,21 @@ struct host_info { ...@@ -74,6 +73,21 @@ struct host_info {
struct net_device *dev; struct net_device *dev;
}; };
/* Define a fake hardware header format for the networking core. Note that
* header size cannot exceed 16 bytes as that is the size of the header cache.
* Also, we do not need the source address in the header so we omit it and
* keep the header to under 16 bytes */
#define ETH1394_ALEN (8)
#define ETH1394_HLEN (10)
struct eth1394hdr {
unsigned char h_dest[ETH1394_ALEN]; /* destination eth1394 addr */
unsigned short h_proto; /* packet type ID field */
} __attribute__((packed));
typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type; typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
/* IP1394 headers */ /* IP1394 headers */
......
...@@ -57,7 +57,6 @@ ...@@ -57,7 +57,6 @@
/* Maps speed values above to a string representation */ /* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[]; extern const char *hpsb_speedto_str[];
extern const u8 hpsb_speedto_maxrec[];
#define SELFID_PWRCL_NO_POWER 0x0 #define SELFID_PWRCL_NO_POWER 0x0
......
...@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache; ...@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */ /* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
const u8 hpsb_speedto_maxrec[] = { 0x7, 0x8, 0x9, 0x10, 0x11, 0x12 };
static void dump_packet(const char *text, quadlet_t *data, int size) static void dump_packet(const char *text, quadlet_t *data, int size)
{ {
...@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host); ...@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host);
/** ieee1394_core.c **/ /** ieee1394_core.c **/
EXPORT_SYMBOL(hpsb_speedto_str); EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_speedto_maxrec);
EXPORT_SYMBOL(hpsb_set_packet_complete_task); EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(alloc_hpsb_packet); EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet); EXPORT_SYMBOL(free_hpsb_packet);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sched.h>
#include "iso.h" #include "iso.h"
void hpsb_iso_stop(struct hpsb_iso *iso) void hpsb_iso_stop(struct hpsb_iso *iso)
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
#include "sbp2.h" #include "sbp2.h"
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 938 $ Ben Collins <bcollins@debian.org>"; "$Rev: 942 $ Ben Collins <bcollins@debian.org>";
/* /*
* Module load parameter definitions * Module load parameter definitions
...@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static Scsi_Host_Template scsi_driver_template; static Scsi_Host_Template scsi_driver_template;
const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
static struct hpsb_highlevel sbp2_highlevel = { static struct hpsb_highlevel sbp2_highlevel = {
.name = SBP2_DEVICE_NAME, .name = SBP2_DEVICE_NAME,
.remove_host = sbp2_remove_host, .remove_host = sbp2_remove_host,
...@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u ...@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u
scsi_id->ne = ud->ne; scsi_id->ne = ud->ne;
scsi_id->hi = hi; scsi_id->hi = hi;
scsi_id->speed_code = SPEED_100; scsi_id->speed_code = SPEED_100;
scsi_id->max_payload_size = hpsb_speedto_maxrec[SPEED_100]; scsi_id->max_payload_size = sbp2_speedto_max_payload[SPEED_100];
atomic_set(&scsi_id->sbp2_login_complete, 0); atomic_set(&scsi_id->sbp2_login_complete, 0);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
...@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) ...@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
/* Payload size is the lesser of what our speed supports and what /* Payload size is the lesser of what our speed supports and what
* our host supports. */ * our host supports. */
scsi_id->max_payload_size = min(hpsb_speedto_maxrec[scsi_id->speed_code], scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code],
(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1)); (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]", SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]",
......
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