Commit 9fc6726f authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[PATCH] Update IEEE1394 (r939)

- Adds fragementation support to eth1394
- Fix race conditition in packet completion task call
- Fix lack of proper logic in tlabel allocation
- Fix brokeness introduced by "stanford checker fixes for memset" in
  ohci1394
- Add trivial PM resume callback in ohci1394 to support sleep/resume.
parent 4fe33674
This diff is collapsed.
......@@ -24,6 +24,8 @@
#ifndef __ETH1394_H
#define __ETH1394_H
#include "ieee1394.h"
/* Register for incoming packets. This is 8192 bytes, which supports up to
* 1600mbs. We'll need to change this if that ever becomes "small" :) */
#define ETHER1394_REGION_ADDR_LEN 8192
......@@ -32,14 +34,24 @@
/* GASP identifier numbers for IPv4 over IEEE 1394 */
#define ETHER1394_GASP_SPECIFIER_ID 0x00005E
#define ETHER1394_GASP_SPECIFIER_ID_HI ((ETHER1394_GASP_SPECIFIER_ID >> 8) & 0xffff)
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#define ETHER1394_GASP_VERSION 1
#define ETHER1394_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */
/* Node set == 64 */
#define NODE_SET (ALL_NODES + 1)
enum eth1394_bc_states { ETHER1394_BC_CLOSED, ETHER1394_BC_OPENED,
ETHER1394_BC_CHECK };
struct pdg_list {
struct list_head list; /* partial datagram list per node */
unsigned int sz; /* partial datagram list size per node */
spinlock_t lock; /* partial datagram lock */
};
/* Private structure for our ethernet driver */
struct eth1394_priv {
struct net_device_stats stats; /* Device stats */
......@@ -53,6 +65,8 @@ struct eth1394_priv {
int broadcast_channel; /* Async stream Broadcast Channel */
enum eth1394_bc_states bc_state; /* broadcast channel state */
struct hpsb_iso *iso; /* Async stream recv handle */
struct pdg_list pdg[ALL_NODES]; /* partial RX datagram lists */
int dgl[NODE_SET]; /* Outgoing datagram label per node */
};
struct host_info {
......@@ -62,29 +76,20 @@ struct host_info {
typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
/* This is our task struct. It's used for the packet complete callback. */
struct packet_task {
struct sk_buff *skb; /* Socket buffer we are sending */
nodeid_t dest_node; /* Destination of the packet */
u64 addr; /* Address */
struct work_struct tq; /* The task */
eth1394_tx_type tx_type; /* Send data via GASP or Write Req. */
};
/* IP1394 headers */
#include <asm/byteorder.h>
/* Unfragmented */
#if defined __BIG_ENDIAN_BITFIELD
struct eth1394_uf_hdr {
u8 lf:2;
u16 lf:2;
u16 res:14;
u16 ether_type; /* Ethernet packet type */
} __attribute__((packed));
#elif defined __LITTLE_ENDIAN_BITFIELD
struct eth1394_uf_hdr {
u16 res:14;
u8 lf:2;
u16 lf:2;
u16 ether_type;
} __attribute__((packed));
#else
......@@ -94,8 +99,8 @@ struct eth1394_uf_hdr {
/* First fragment */
#if defined __BIG_ENDIAN_BITFIELD
struct eth1394_ff_hdr {
u8 lf:2;
u8 res1:2;
u16 lf:2;
u16 res1:2;
u16 dg_size:12; /* Datagram size */
u16 ether_type; /* Ethernet packet type */
u16 dgl; /* Datagram label */
......@@ -104,8 +109,8 @@ struct eth1394_ff_hdr {
#elif defined __LITTLE_ENDIAN_BITFIELD
struct eth1394_ff_hdr {
u16 dg_size:12;
u8 res1:2;
u8 lf:2;
u16 res1:2;
u16 lf:2;
u16 ether_type;
u16 dgl;
u16 res2;
......@@ -117,21 +122,21 @@ struct eth1394_ff_hdr {
/* XXX: Subsequent fragments, including last */
#if defined __BIG_ENDIAN_BITFIELD
struct eth1394_sf_hdr {
u8 lf:2;
u8 res1:2;
u16 lf:2;
u16 res1:2;
u16 dg_size:12; /* Datagram size */
u8 res2:6;
u16 fg_off:10; /* Fragment offset */
u16 res2:4;
u16 fg_off:12; /* Fragment offset */
u16 dgl; /* Datagram label */
u16 res3;
} __attribute__((packed));
#elif defined __LITTLE_ENDIAN_BITFIELD
struct eth1394_sf_hdr {
u16 dg_size:12;
u8 res1:2;
u8 lf:2;
u16 fg_off:10;
u8 res2:6;
u16 res1:2;
u16 lf:2;
u16 fg_off:12;
u16 res2:4;
u16 dgl;
u16 res3;
} __attribute__((packed));
......@@ -141,13 +146,13 @@ struct eth1394_sf_hdr {
#if defined __BIG_ENDIAN_BITFIELD
struct eth1394_common_hdr {
u8 lf:2;
u16 lf:2;
u16 pad1:14;
} __attribute__((packed));
#elif defined __LITTLE_ENDIAN_BITFIELD
struct eth1394_common_hdr {
u16 pad1:14;
u8 lf:2;
u16 lf:2;
} __attribute__((packed));
#else
#error Unknown bit field type
......@@ -199,4 +204,17 @@ struct eth1394_arp {
/* Network timeout */
#define ETHER1394_TIMEOUT 100000
/* This is our task struct. It's used for the packet complete callback. */
struct packet_task {
struct sk_buff *skb;
int outstanding_pkts;
eth1394_tx_type tx_type;
int max_payload;
struct hpsb_packet *packet;
struct eth1394_priv *priv;
union eth1394_hdr hdr;
u64 addr;
u16 dest_node;
};
#endif /* __ETH1394_H */
......@@ -80,9 +80,12 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
static void run_packet_complete(struct hpsb_packet *packet)
{
if (packet->complete_routine != NULL) {
packet->complete_routine(packet->complete_data);
void (*complete_routine)(void*) = packet->complete_routine;
void *complete_data = packet->complete_data;
packet->complete_routine = NULL;
packet->complete_data = NULL;
complete_routine(complete_data);
}
return;
}
......@@ -938,7 +941,7 @@ void abort_requests(struct hpsb_host *host)
{
unsigned long flags;
struct hpsb_packet *packet;
struct list_head *lh;
struct list_head *lh, *tlh;
LIST_HEAD(llist);
host->driver->devctl(host, CANCEL_REQUESTS, 0);
......@@ -948,8 +951,9 @@ void abort_requests(struct hpsb_host *host)
INIT_LIST_HEAD(&host->pending_packets);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
list_for_each(lh, &llist) {
list_for_each_safe(lh, tlh, &llist) {
packet = list_entry(lh, struct hpsb_packet, list);
list_del(&packet->list);
packet->state = hpsb_complete;
packet->ack_code = ACKX_ABORTED;
up(&packet->state_change);
......@@ -962,7 +966,7 @@ void abort_timedouts(struct hpsb_host *host)
unsigned long flags;
struct hpsb_packet *packet;
unsigned long expire;
struct list_head *lh, *next;
struct list_head *lh, *next, *tlh;
LIST_HEAD(expiredlist);
spin_lock_irqsave(&host->csr.lock, flags);
......@@ -990,8 +994,9 @@ void abort_timedouts(struct hpsb_host *host)
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
list_for_each(lh, &expiredlist) {
list_for_each_safe(lh, tlh, &expiredlist) {
packet = list_entry(lh, struct hpsb_packet, list);
list_del(&packet->list);
packet->state = hpsb_complete;
packet->ack_code = ACKX_TIMEOUT;
up(&packet->state_change);
......
......@@ -147,6 +147,8 @@ int hpsb_get_tlabel(struct hpsb_packet *packet, int wait)
spin_lock_irqsave(&tp->lock, flags);
packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
if(packet->tlabel > 63)
packet->tlabel = find_first_zero_bit(tp->pool, 64);
tp->next = (packet->tlabel + 1) % 64;
/* Should _never_ happen */
BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
......@@ -573,10 +575,6 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
quadlet_t *buffer, size_t length, u32 specifier_id,
unsigned int version)
{
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
int i;
#endif
struct hpsb_packet *packet;
int retval = 0;
u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
......@@ -604,14 +602,6 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
memcpy(&(packet->data[2]), buffer, length - 4);
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG("GASP: packet->header_size = %d", packet->header_size);
HPSB_DEBUG("GASP: packet->data_size = %d", packet->data_size);
for(i=0; i<(packet->data_size/4); i++)
HPSB_DEBUG("GASP: data[%d]: 0x%08x", i*4, be32_to_cpu(packet->data[i]));
#endif
packet->generation = generation;
packet->no_waiter = 1;
......
......@@ -164,7 +164,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata =
"$Rev: 931 $ Ben Collins <bcollins@debian.org>";
"$Rev: 938 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......@@ -3165,7 +3165,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci)
struct config_rom_ptr cr;
memset(&cr, 0, sizeof(cr));
memset(ohci->csr_config_rom_cpu, 0, sizeof(*ohci->csr_config_rom_cpu));
memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN);
cr.data = ohci->csr_config_rom_cpu;
......@@ -3530,6 +3530,16 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
}
}
#ifdef CONFIG_PM
static int ohci1394_pci_resume (struct pci_dev *dev)
{
pci_enable_device(dev);
return 0;
}
#endif
#define PCI_CLASS_FIREWIRE_OHCI ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
......@@ -3551,6 +3561,10 @@ static struct pci_driver ohci1394_pci_driver = {
.id_table = ohci1394_pci_tbl,
.probe = ohci1394_pci_probe,
.remove = ohci1394_pci_remove,
#ifdef CONFIG_PM
.resume = ohci1394_pci_resume,
#endif /* PM */
};
......
......@@ -79,7 +79,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 931 $ Ben Collins <bcollins@debian.org>";
"$Rev: 938 $ Ben Collins <bcollins@debian.org>";
/*
* Module load parameter definitions
......
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