Commit ccdba6ab authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[PATCH] Update IEEE1394 (r1014)

 misc:      - Consolidate and make consistent, the NODE_BUS_{FMT,ARGS}
	      macros.
	    - Add HPSB_VERBOSE() macro to make VERBOSEDEBUG code a
	      little cleaner.
 ieee1394 : - Replace panic() with BUG and return value in dma routine.
	    - Reset reset_retries on success or loop recover.
	    - Add RECV_FLUSH to flush buffers on > 1 irq interval or in
	      buffer-fill mode.
	    - Probe logic-unit-subdirectories as children of the
	      unit-dir.
	    - Fix compile warning in nodemgr thread.
	    - Replace tightly scheduled timeout loop with a 50ms timer.
	    - Better return and usage of BUG_ON() in dma handler.
	    - Calculate timeout expiry interval at change instead of at
	      every timeout check.
 SBP2     : - Fix logical-unit-directory LUN's.
	    - Remove procfs interface.
	    - Fix usage of initdata after init.
 Host con : - Change irq output to use __irq_itoa() for sparc.
	    - Do more to notify bus when module is unloaded, to clear
	      IRM, etc.
 ohci1394 : Fix endianess of async stream packet headers.
parent e45635cc
...@@ -89,6 +89,37 @@ static void host_reset(struct hpsb_host *host) ...@@ -89,6 +89,37 @@ static void host_reset(struct hpsb_host *host)
0x3f1)); 0x3f1));
} }
/*
* HI == seconds (bits 0:2)
* LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31)
*
* Convert to units and then to HZ, for comparison to jiffies.
*
* By default this will end up being 800 units, or 100ms (125usec per
* unit).
*
* NOTE: The spec says 1/8000, but also says we can compute based on 1/8192
* like CSR specifies. Should make our math less complex.
*/
static inline void calculate_expire(struct csr_control *csr)
{
unsigned long units;
/* Take the seconds, and convert to units */
units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13;
/* Add in the fractional units */
units += (unsigned long)(csr->split_timeout_lo >> 19);
/* Convert to jiffies */
csr->expire = (unsigned long)(units * HZ) >> 13UL;
/* Just to keep from rounding low */
csr->expire++;
HPSB_VERBOSE("CSR: setting expire to %lu, HZ=%lu", csr->expire, HZ);
}
static void add_host(struct hpsb_host *host) static void add_host(struct hpsb_host *host)
{ {
...@@ -100,6 +131,7 @@ static void add_host(struct hpsb_host *host) ...@@ -100,6 +131,7 @@ static void add_host(struct hpsb_host *host)
host->csr.node_ids = 0; host->csr.node_ids = 0;
host->csr.split_timeout_hi = 0; host->csr.split_timeout_hi = 0;
host->csr.split_timeout_lo = 800 << 19; host->csr.split_timeout_lo = 800 << 19;
calculate_expire(&host->csr);
host->csr.cycle_time = 0; host->csr.cycle_time = 0;
host->csr.bus_time = 0; host->csr.bus_time = 0;
host->csr.bus_manager_id = 0x3f; host->csr.bus_manager_id = 0x3f;
...@@ -336,10 +368,12 @@ static int write_regs(struct hpsb_host *host, int nodeid, int destid, ...@@ -336,10 +368,12 @@ static int write_regs(struct hpsb_host *host, int nodeid, int destid,
case CSR_SPLIT_TIMEOUT_HI: case CSR_SPLIT_TIMEOUT_HI:
host->csr.split_timeout_hi = host->csr.split_timeout_hi =
be32_to_cpu(*(data++)) & 0x00000007; be32_to_cpu(*(data++)) & 0x00000007;
calculate_expire(&host->csr);
out; out;
case CSR_SPLIT_TIMEOUT_LO: case CSR_SPLIT_TIMEOUT_LO:
host->csr.split_timeout_lo = host->csr.split_timeout_lo =
be32_to_cpu(*(data++)) & 0xfff80000; be32_to_cpu(*(data++)) & 0xfff80000;
calculate_expire(&host->csr);
out; out;
/* address gap */ /* address gap */
...@@ -410,7 +444,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store, ...@@ -410,7 +444,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
* eventually. */ * eventually. */
HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
"broadcast channel 31. Ignoring.", "broadcast channel 31. Ignoring.",
NODE_BUS_ARGS(nodeid)); NODE_BUS_ARGS(host, nodeid));
data &= ~0x1; /* keep broadcast channel allocated */ data &= ~0x1; /* keep broadcast channel allocated */
} }
...@@ -556,7 +590,7 @@ static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store, ...@@ -556,7 +590,7 @@ static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
* eventually. */ * eventually. */
HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release " HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
"broadcast channel 31. Ignoring.", "broadcast channel 31. Ignoring.",
NODE_BUS_ARGS(nodeid)); NODE_BUS_ARGS(host, nodeid));
data &= ~0x100000000ULL; /* keep broadcast channel allocated */ data &= ~0x100000000ULL; /* keep broadcast channel allocated */
} }
......
...@@ -41,6 +41,7 @@ struct csr_control { ...@@ -41,6 +41,7 @@ struct csr_control {
quadlet_t state; quadlet_t state;
quadlet_t node_ids; quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo; quadlet_t split_timeout_hi, split_timeout_lo;
unsigned long expire; // Calculated from split_timeout
quadlet_t cycle_time; quadlet_t cycle_time;
quadlet_t bus_time; quadlet_t bus_time;
quadlet_t bus_manager_id; quadlet_t bus_manager_id;
......
...@@ -151,13 +151,15 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset, ...@@ -151,13 +151,15 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
for (i = 0; i < dma->n_dma_pages; i++) { for (i = 0; i < dma->n_dma_pages; i++) {
if (off < sg_dma_len(&dma->sglist[i])) { if (off < sg_dma_len(&dma->sglist[i])) {
*rem = off; *rem = off;
return i; break;
} }
off -= sg_dma_len(&dma->sglist[i]); off -= sg_dma_len(&dma->sglist[i]);
} }
panic("dma_region_find: offset %lu beyond end of DMA mapping\n", offset); BUG_ON(i >= dma->n_dma_pages);
return i;
} }
dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset) dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
......
/* /*
* dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips * dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips
* Copyright (C)2001 Daniel Maas <dmaas@dcine.com> * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
* receive, proc_fs by Dan Dennedy <dan@dennedy.org> * receive by Dan Dennedy <dan@dennedy.org>
* *
* based on: * based on:
* video1394.h - driver for OHCI 1394 boards * video1394.h - driver for OHCI 1394 boards
......
This diff is collapsed.
/* /*
* dv1394.h - DV input/output over IEEE 1394 on OHCI chips * dv1394.h - DV input/output over IEEE 1394 on OHCI chips
* Copyright (C)2001 Daniel Maas <dmaas@dcine.com> * Copyright (C)2001 Daniel Maas <dmaas@dcine.com>
* receive, proc_fs by Dan Dennedy <dan@dennedy.org> * receive by Dan Dennedy <dan@dennedy.org>
* *
* based on: * based on:
* video1394.h - driver for OHCI 1394 boards * video1394.h - driver for OHCI 1394 boards
......
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 986 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1010 $ Ben Collins <bcollins@debian.org>";
struct fragment_info { struct fragment_info {
struct list_head list; struct list_head list;
...@@ -1285,7 +1285,7 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p, ...@@ -1285,7 +1285,7 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
if (hpsb_get_tlabel(p, !in_interrupt())) { if (hpsb_get_tlabel(p, !in_interrupt())) {
ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending " ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending "
"to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(node)); "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(host, node));
return -1; return -1;
} }
p->header[0] = (p->node_id << 16) | (p->tlabel << 10) p->header[0] = (p->node_id << 16) | (p->tlabel << 10)
...@@ -1600,7 +1600,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -1600,7 +1600,7 @@ static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
case ETHTOOL_GDRVINFO: { case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, driver_name); strcpy (info.driver, driver_name);
strcpy (info.version, "$Rev: 986 $"); strcpy (info.version, "$Rev: 1010 $");
/* FIXME XXX provide sane businfo */ /* FIXME XXX provide sane businfo */
strcpy (info.bus_info, "ieee1394"); strcpy (info.bus_info, "ieee1394");
if (copy_to_user (useraddr, &info, sizeof (info))) if (copy_to_user (useraddr, &info, sizeof (info)))
......
...@@ -21,6 +21,7 @@ struct hpsb_address_serve { ...@@ -21,6 +21,7 @@ struct hpsb_address_serve {
*/ */
struct hpsb_highlevel { struct hpsb_highlevel {
struct module *owner;
const char *name; const char *name;
/* Any of the following pointers can legally be NULL, except for /* Any of the following pointers can legally be NULL, except for
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/workqueue.h>
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "hosts.h" #include "hosts.h"
...@@ -67,7 +66,7 @@ int hpsb_ref_host(struct hpsb_host *host) ...@@ -67,7 +66,7 @@ int hpsb_ref_host(struct hpsb_host *host)
list_for_each(lh, &hpsb_hosts) { list_for_each(lh, &hpsb_hosts) {
if (host == list_entry(lh, struct hpsb_host, host_list)) { if (host == list_entry(lh, struct hpsb_host, host_list)) {
if (try_module_get(host->driver->owner)) { if (try_module_get(host->driver->owner)) {
host->refcount++; atomic_inc(&host->refcount);
retval = 1; retval = 1;
} }
break; break;
...@@ -92,9 +91,7 @@ void hpsb_unref_host(struct hpsb_host *host) ...@@ -92,9 +91,7 @@ void hpsb_unref_host(struct hpsb_host *host)
module_put(host->driver->owner); module_put(host->driver->owner);
down(&hpsb_hosts_lock); down(&hpsb_hosts_lock);
host->refcount--; if (atomic_dec_and_test(&host->refcount) && host->is_shutdown)
if (!host->refcount && host->is_shutdown)
kfree(host); kfree(host);
up(&hpsb_hosts_lock); up(&hpsb_hosts_lock);
} }
...@@ -131,7 +128,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra) ...@@ -131,7 +128,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
h->hostdata = h + 1; h->hostdata = h + 1;
h->driver = drv; h->driver = drv;
h->refcount = 1; atomic_set(&h->refcount, 1);
INIT_LIST_HEAD(&h->pending_packets); INIT_LIST_HEAD(&h->pending_packets);
spin_lock_init(&h->pending_pkt_lock); spin_lock_init(&h->pending_pkt_lock);
...@@ -141,7 +138,10 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra) ...@@ -141,7 +138,10 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
atomic_set(&h->generation, 0); atomic_set(&h->generation, 0);
INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h); init_timer(&h->timeout);
h->timeout.data = (unsigned long) h;
h->timeout.function = abort_timedouts;
h->timeout_interval = HZ / 20; // 50ms by default
h->topology_map = h->csr.topology_map + 3; h->topology_map = h->csr.topology_map + 3;
h->speed_map = (u8 *)(h->csr.speed_map + 2); h->speed_map = (u8 *)(h->csr.speed_map + 2);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/workqueue.h> #include <linux/timer.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include "ieee1394_types.h" #include "ieee1394_types.h"
...@@ -29,11 +29,12 @@ struct hpsb_host { ...@@ -29,11 +29,12 @@ struct hpsb_host {
atomic_t generation; atomic_t generation;
int refcount; atomic_t refcount;
struct list_head pending_packets; struct list_head pending_packets;
spinlock_t pending_pkt_lock; spinlock_t pending_pkt_lock;
struct work_struct timeout_tq; struct timer_list timeout;
unsigned long timeout_interval;
unsigned char iso_listen_count[64]; unsigned char iso_listen_count[64];
...@@ -107,6 +108,7 @@ enum devctl_cmd { ...@@ -107,6 +108,7 @@ enum devctl_cmd {
enum isoctl_cmd { enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands /* rawiso API - see iso.h for the meanings of these commands
(they correspond exactly to the hpsb_iso_* API functions)
* INIT = allocate resources * INIT = allocate resources
* START = begin transmission/reception * START = begin transmission/reception
* STOP = halt transmission/reception * STOP = halt transmission/reception
...@@ -128,6 +130,7 @@ enum isoctl_cmd { ...@@ -128,6 +130,7 @@ enum isoctl_cmd {
RECV_STOP, RECV_STOP,
RECV_RELEASE, RECV_RELEASE,
RECV_SHUTDOWN, RECV_SHUTDOWN,
RECV_FLUSH
}; };
enum reset_types { enum reset_types {
......
...@@ -100,6 +100,8 @@ ...@@ -100,6 +100,8 @@
_IOW ('#', 0x27, struct raw1394_iso_packets) _IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \ #define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28) _IO ('#', 0x28)
#define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29)
#endif /* __IEEE1394_IOCTL_H */ #endif /* __IEEE1394_IOCTL_H */
...@@ -29,9 +29,7 @@ ...@@ -29,9 +29,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -62,6 +60,7 @@ static kmem_cache_t *hpsb_packet_cache; ...@@ -62,6 +60,7 @@ 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" };
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
static void dump_packet(const char *text, quadlet_t *data, int size) static void dump_packet(const char *text, quadlet_t *data, int size)
{ {
int i; int i;
...@@ -70,11 +69,13 @@ static void dump_packet(const char *text, quadlet_t *data, int size) ...@@ -70,11 +69,13 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
size = (size > 4 ? 4 : size); size = (size > 4 ? 4 : size);
printk(KERN_DEBUG "ieee1394: %s", text); printk(KERN_DEBUG "ieee1394: %s", text);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++)
printk(" %8.8x", data[i]); printk(" %08x", data[i]);
}
printk("\n"); printk("\n");
} }
#else
#define dump_packet(x,y,z)
#endif
static void run_packet_complete(struct hpsb_packet *packet) static void run_packet_complete(struct hpsb_packet *packet)
{ {
...@@ -355,9 +356,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount) ...@@ -355,9 +356,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid) void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
{ {
if (host->in_bus_reset) { if (host->in_bus_reset) {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("Including SelfID 0x%x", sid);
HPSB_INFO("Including SelfID 0x%x", sid);
#endif
host->topology_map[host->selfid_count++] = sid; host->topology_map[host->selfid_count++] = sid;
} else { } else {
HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d", HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
...@@ -384,15 +383,16 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot) ...@@ -384,15 +383,16 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
} else { } else {
HPSB_NOTICE("Stopping out-of-control reset loop"); HPSB_NOTICE("Stopping out-of-control reset loop");
HPSB_NOTICE("Warning - topology map and speed map will not be valid"); HPSB_NOTICE("Warning - topology map and speed map will not be valid");
host->reset_retries = 0;
} }
} else { } else {
host->reset_retries = 0;
build_speed_map(host, host->node_count); build_speed_map(host, host->node_count);
} }
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
HPSB_INFO("selfid_complete called with successful SelfID stage "
"... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id); "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
#endif
/* irm_id is kept up to date by check_selfids() */ /* irm_id is kept up to date by check_selfids() */
if (host->irm_id == host->node_id) { if (host->irm_id == host->node_id) {
host->is_irm = 1; host->is_irm = 1;
...@@ -440,7 +440,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, ...@@ -440,7 +440,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
up(&packet->state_change); up(&packet->state_change);
schedule_work(&host->timeout_tq); mod_timer(&host->timeout, jiffies + host->timeout_interval);
} }
/** /**
...@@ -550,10 +550,9 @@ int hpsb_send_packet(struct hpsb_packet *packet) ...@@ -550,10 +550,9 @@ int hpsb_send_packet(struct hpsb_packet *packet)
} }
} }
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
dump_packet("send packet local:", packet->header, dump_packet("send packet local:", packet->header,
packet->header_size); packet->header_size);
#endif
hpsb_packet_sent(host, packet, packet->expect_response?ACK_PENDING:ACK_COMPLETE); hpsb_packet_sent(host, packet, packet->expect_response?ACK_PENDING:ACK_COMPLETE);
hpsb_packet_received(host, data, size, 0); hpsb_packet_received(host, data, size, 0);
...@@ -568,7 +567,6 @@ int hpsb_send_packet(struct hpsb_packet *packet) ...@@ -568,7 +567,6 @@ int hpsb_send_packet(struct hpsb_packet *packet)
+ NODEID_TO_NODE(packet->node_id)]; + NODEID_TO_NODE(packet->node_id)];
} }
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
switch (packet->speed_code) { switch (packet->speed_code) {
case 2: case 2:
dump_packet("send packet 400:", packet->header, dump_packet("send packet 400:", packet->header,
...@@ -582,7 +580,6 @@ int hpsb_send_packet(struct hpsb_packet *packet) ...@@ -582,7 +580,6 @@ int hpsb_send_packet(struct hpsb_packet *packet)
dump_packet("send packet 100:", packet->header, dump_packet("send packet 100:", packet->header,
packet->header_size); packet->header_size);
} }
#endif
return host->driver->transmit_packet(host, packet); return host->driver->transmit_packet(host, packet);
} }
...@@ -617,7 +614,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, ...@@ -617,7 +614,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
} }
if (lh == &host->pending_packets) { if (lh == &host->pending_packets) {
HPSB_DEBUG("unsolicited response packet received - np"); HPSB_DEBUG("unsolicited response packet received - no tlabel match");
dump_packet("contents:", data, 16); dump_packet("contents:", data, 16);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
return; return;
...@@ -641,7 +638,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, ...@@ -641,7 +638,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
if (!tcode_match || (packet->tlabel != tlabel) if (!tcode_match || (packet->tlabel != tlabel)
|| (packet->node_id != (data[1] >> 16))) { || (packet->node_id != (data[1] >> 16))) {
HPSB_INFO("unsolicited response packet received"); HPSB_INFO("unsolicited response packet received - tcode mismatch");
dump_packet("contents:", data, 16); dump_packet("contents:", data, 16);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
...@@ -896,9 +893,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, ...@@ -896,9 +893,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
return; return;
} }
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
dump_packet("received packet:", data, size); dump_packet("received packet:", data, size);
#endif
tcode = (data[0] >> 4) & 0xf; tcode = (data[0] >> 4) & 0xf;
...@@ -959,28 +954,23 @@ void abort_requests(struct hpsb_host *host) ...@@ -959,28 +954,23 @@ void abort_requests(struct hpsb_host *host)
} }
} }
void abort_timedouts(struct hpsb_host *host) void abort_timedouts(unsigned long __opaque)
{ {
struct hpsb_host *host = (struct hpsb_host *)__opaque;
unsigned long flags; unsigned long flags;
struct hpsb_packet *packet; struct hpsb_packet *packet;
unsigned long expire; unsigned long expire;
struct list_head *lh, *next, *tlh; struct list_head *lh, *tlh;
LIST_HEAD(expiredlist); LIST_HEAD(expiredlist);
spin_lock_irqsave(&host->csr.lock, flags); spin_lock_irqsave(&host->csr.lock, flags);
expire = (host->csr.split_timeout_hi * 8000 expire = host->csr.expire;
+ (host->csr.split_timeout_lo >> 19))
* HZ / 8000;
/* Avoid shortening of timeout due to rounding errors: */
expire++;
spin_unlock_irqrestore(&host->csr.lock, flags); spin_unlock_irqrestore(&host->csr.lock, flags);
spin_lock_irqsave(&host->pending_pkt_lock, flags); spin_lock_irqsave(&host->pending_pkt_lock, flags);
for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) { list_for_each_safe(lh, tlh, &host->pending_packets) {
packet = list_entry(lh, struct hpsb_packet, list); packet = list_entry(lh, struct hpsb_packet, list);
next = lh->next;
if (time_before(packet->sendtime + expire, jiffies)) { if (time_before(packet->sendtime + expire, jiffies)) {
list_del(&packet->list); list_del(&packet->list);
list_add(&packet->list, &expiredlist); list_add(&packet->list, &expiredlist);
...@@ -988,7 +978,7 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -988,7 +978,7 @@ void abort_timedouts(struct hpsb_host *host)
} }
if (!list_empty(&host->pending_packets)) if (!list_empty(&host->pending_packets))
schedule_work(&host->timeout_tq); mod_timer(&host->timeout, jiffies + host->timeout_interval);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags); spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
...@@ -1179,8 +1169,6 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file) ...@@ -1179,8 +1169,6 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
return retval; return retval;
} }
struct proc_dir_entry *ieee1394_procfs_entry;
static int __init ieee1394_init(void) static int __init ieee1394_init(void)
{ {
hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet), hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
...@@ -1194,19 +1182,6 @@ static int __init ieee1394_init(void) ...@@ -1194,19 +1182,6 @@ static int __init ieee1394_init(void)
return -ENODEV; return -ENODEV;
} }
#ifdef CONFIG_PROC_FS
/* Must be done before we start everything else, since the drivers
* may use it. */
ieee1394_procfs_entry = proc_mkdir("ieee1394", proc_bus);
if (ieee1394_procfs_entry == NULL) {
HPSB_ERR("unable to create /proc/bus/ieee1394\n");
unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
devfs_remove("ieee1394");
return -ENOMEM;
}
ieee1394_procfs_entry->owner = THIS_MODULE;
#endif
init_hpsb_highlevel(); init_hpsb_highlevel();
init_csr(); init_csr();
if (!disable_nodemgr) if (!disable_nodemgr)
...@@ -1227,7 +1202,6 @@ static void __exit ieee1394_cleanup(void) ...@@ -1227,7 +1202,6 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev(IEEE1394_MAJOR, "ieee1394"); unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
devfs_remove("ieee1394"); devfs_remove("ieee1394");
remove_proc_entry("ieee1394", proc_bus);
} }
module_init(ieee1394_init); module_init(ieee1394_init);
...@@ -1257,7 +1231,6 @@ EXPORT_SYMBOL(hpsb_packet_sent); ...@@ -1257,7 +1231,6 @@ EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received); EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL(ieee1394_register_chardev); EXPORT_SYMBOL(ieee1394_register_chardev);
EXPORT_SYMBOL(ieee1394_unregister_chardev); EXPORT_SYMBOL(ieee1394_unregister_chardev);
EXPORT_SYMBOL(ieee1394_procfs_entry);
/** ieee1394_transactions.c **/ /** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel); EXPORT_SYMBOL(hpsb_get_tlabel);
...@@ -1341,3 +1314,4 @@ EXPORT_SYMBOL(hpsb_iso_n_ready); ...@@ -1341,3 +1314,4 @@ EXPORT_SYMBOL(hpsb_iso_n_ready);
EXPORT_SYMBOL(hpsb_iso_packet_sent); EXPORT_SYMBOL(hpsb_iso_packet_sent);
EXPORT_SYMBOL(hpsb_iso_packet_received); EXPORT_SYMBOL(hpsb_iso_packet_received);
EXPORT_SYMBOL(hpsb_iso_wake); EXPORT_SYMBOL(hpsb_iso_wake);
EXPORT_SYMBOL(hpsb_iso_recv_flush);
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#include <linux/proc_fs.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include "hosts.h" #include "hosts.h"
...@@ -88,7 +87,7 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l) ...@@ -88,7 +87,7 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l)
return list_entry(l, struct hpsb_packet, driver_list); return list_entry(l, struct hpsb_packet, driver_list);
} }
void abort_timedouts(struct hpsb_host *host); void abort_timedouts(unsigned long __opaque);
void abort_requests(struct hpsb_host *host); void abort_requests(struct hpsb_host *host);
struct hpsb_packet *alloc_hpsb_packet(size_t data_size); struct hpsb_packet *alloc_hpsb_packet(size_t data_size);
...@@ -224,9 +223,6 @@ int ieee1394_register_chardev(int blocknum, /* 0-15 */ ...@@ -224,9 +223,6 @@ int ieee1394_register_chardev(int blocknum, /* 0-15 */
/* release a block of minor numbers */ /* release a block of minor numbers */
void ieee1394_unregister_chardev(int blocknum); void ieee1394_unregister_chardev(int blocknum);
/* the proc_fs entry for /proc/ieee1394 */
extern struct proc_dir_entry *ieee1394_procfs_entry;
/* Our sysfs bus entry */ /* Our sysfs bus entry */
extern struct bus_type ieee1394_bus_type; extern struct bus_type ieee1394_bus_type;
......
...@@ -580,9 +580,7 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, ...@@ -580,9 +580,7 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8; u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
u8 specifier_id_lo = specifier_id & 0xff; u8 specifier_id_lo = specifier_id & 0xff;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("Send GASP: channel = %d, length = %d", channel, length);
HPSB_DEBUG("Send GASP: channel = %d, length = %d", channel, length);
#endif
length += 8; length += 8;
......
...@@ -61,8 +61,9 @@ typedef u16 arm_length_t; ...@@ -61,8 +61,9 @@ typedef u16 arm_length_t;
#define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK) #define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK)
/* Can be used to consistently print a node/bus ID. */ /* Can be used to consistently print a node/bus ID. */
#define NODE_BUS_FMT "%02d:%04d" #define NODE_BUS_FMT "%d-%02d:%04d"
#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid) #define NODE_BUS_ARGS(__host, __nodeid) \
__host->id, NODEID_TO_NODE(__nodeid), NODEID_TO_BUS(__nodeid)
#define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args) #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
...@@ -72,6 +73,12 @@ typedef u16 arm_length_t; ...@@ -72,6 +73,12 @@ typedef u16 arm_length_t;
#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args) #define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, fmt , ## args)
#define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args) #define HPSB_ERR(fmt, args...) HPSB_PRINT(KERN_ERR, fmt , ## args)
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
#define HPSB_VERBOSE(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
#else
#define HPSB_VERBOSE(fmt, args...)
#endif
#define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args) #define HPSB_PANIC(fmt, args...) panic("ieee1394: " fmt "\n" , ## args)
#define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__) #define HPSB_TRACE() HPSB_PRINT(KERN_INFO, "TRACE - %s, %s(), line %d", __FILE__, __FUNCTION__, __LINE__)
......
...@@ -200,6 +200,13 @@ int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) ...@@ -200,6 +200,13 @@ int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
} }
int hpsb_iso_recv_flush(struct hpsb_iso *iso)
{
if (iso->type != HPSB_ISO_RECV)
return -EINVAL;
return iso->host->driver->isoctl(iso, RECV_FLUSH, 0);
}
static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle) static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
{ {
int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle); int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
......
...@@ -165,6 +165,10 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso); ...@@ -165,6 +165,10 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso);
/* N packets have been read out of the buffer, re-use the buffer space */ /* N packets have been read out of the buffer, re-use the buffer space */
int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets); int hpsb_iso_recv_release_packets(struct hpsb_iso *recv, unsigned int n_packets);
/* check for arrival of new packets immediately (even if irq_interval
has not yet been reached) */
int hpsb_iso_recv_flush(struct hpsb_iso *iso);
/* returns # of packets ready to send or receive */ /* returns # of packets ready to send or receive */
int hpsb_iso_n_ready(struct hpsb_iso *iso); int hpsb_iso_n_ready(struct hpsb_iso *iso);
......
...@@ -424,8 +424,15 @@ static void nodemgr_release_ne(struct device *dev) ...@@ -424,8 +424,15 @@ static void nodemgr_release_ne(struct device *dev)
static void nodemgr_remove_ud(struct unit_directory *ud) static void nodemgr_remove_ud(struct unit_directory *ud)
{ {
struct device *dev = &ud->device; struct device *dev = &ud->device;
struct list_head *lh, *next;
int i; int i;
list_for_each_safe(lh, next, &ud->device.children) {
struct unit_directory *ud;
ud = container_of(list_to_dev(lh), struct unit_directory, device);
nodemgr_remove_ud(ud);
}
for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++) for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++)
device_remove_file(dev, fw_ud_attrs[i]); device_remove_file(dev, fw_ud_attrs[i]);
...@@ -462,8 +469,8 @@ static void nodemgr_update_ud_names(struct host_info *hi, struct node_entry *ne) ...@@ -462,8 +469,8 @@ static void nodemgr_update_ud_names(struct host_info *hi, struct node_entry *ne)
ud = container_of(list_to_dev(lh), struct unit_directory, device); ud = container_of(list_to_dev(lh), struct unit_directory, device);
snprintf(ud->device.name, DEVICE_NAME_SIZE, snprintf(ud->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 unit directory %d-" NODE_BUS_FMT "-%u", "IEEE-1394 unit directory " NODE_BUS_FMT "-%u",
hi->host->id, NODE_BUS_ARGS(ne->nodeid), ud->id); NODE_BUS_ARGS(hi->host, ne->nodeid), ud->id);
} }
} }
...@@ -714,8 +721,8 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption ...@@ -714,8 +721,8 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
(unsigned long long)(ne->guid)); (unsigned long long)(ne->guid));
snprintf(ne->device.name, DEVICE_NAME_SIZE, snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT, host->id, "IEEE-1394 device " NODE_BUS_FMT,
NODE_BUS_ARGS(ne->nodeid)); NODE_BUS_ARGS(host, ne->nodeid));
device_register(&ne->device); device_register(&ne->device);
...@@ -727,9 +734,9 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption ...@@ -727,9 +734,9 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
nodemgr_update_ud_names(hi, ne); nodemgr_update_ud_names(hi, ne);
HPSB_DEBUG("%s added: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]", HPSB_DEBUG("%s added: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
(host->node_id == nodeid) ? "Host" : "Node", (host->node_id == nodeid) ? "Host" : "Node",
host->id, NODE_BUS_ARGS(nodeid), (unsigned long long)guid); NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
return ne; return ne;
} }
...@@ -911,7 +918,8 @@ static struct unit_directory *nodemgr_scan_unit_directory ...@@ -911,7 +918,8 @@ static struct unit_directory *nodemgr_scan_unit_directory
* immediate unit directories looking for software_id and * immediate unit directories looking for software_id and
* software_version entries, in order to get driver autoloading working. */ * software_version entries, in order to get driver autoloading working. */
static struct unit_directory *nodemgr_process_unit_directory static struct unit_directory *nodemgr_process_unit_directory
(struct host_info *hi, struct node_entry *ne, octlet_t address, unsigned int *id) (struct host_info *hi, struct node_entry *ne, octlet_t address, unsigned int *id,
struct unit_directory *parent)
{ {
struct unit_directory *ud; struct unit_directory *ud;
quadlet_t quad; quadlet_t quad;
...@@ -1001,12 +1009,14 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -1001,12 +1009,14 @@ static struct unit_directory *nodemgr_process_unit_directory
break; break;
case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY: case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY:
/* TODO: Parent this with it's UD */ ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY;
ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id); ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id,
parent);
if (ud_temp == NULL)
break;
/* inherit unspecified values */ /* inherit unspecified values */
if (ud_temp != NULL)
{
if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) &&
!(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID))
{ {
...@@ -1032,7 +1042,6 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -1032,7 +1042,6 @@ static struct unit_directory *nodemgr_process_unit_directory
ud_temp->flags |= UNIT_DIRECTORY_VERSION; ud_temp->flags |= UNIT_DIRECTORY_VERSION;
ud_temp->version = ud->version; ud_temp->version = ud->version;
} }
}
break; break;
...@@ -1049,7 +1058,13 @@ static struct unit_directory *nodemgr_process_unit_directory ...@@ -1049,7 +1058,13 @@ static struct unit_directory *nodemgr_process_unit_directory
memcpy(&ud->device, &nodemgr_dev_template_ud, memcpy(&ud->device, &nodemgr_dev_template_ud,
sizeof(ud->device)); sizeof(ud->device));
if (parent) {
ud->flags |= UNIT_DIRECTORY_LUN_DIRECTORY;
ud->device.parent = &parent->device;
} else
ud->device.parent = &ne->device; ud->device.parent = &ne->device;
snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id); ne->device.bus_id, ud->id);
...@@ -1125,7 +1140,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent ...@@ -1125,7 +1140,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
break; break;
case CONFIG_ROM_UNIT_DIRECTORY: case CONFIG_ROM_UNIT_DIRECTORY:
nodemgr_process_unit_directory(hi, ne, address + value * 4, &ud_id); nodemgr_process_unit_directory(hi, ne, address + value * 4, &ud_id,
NULL);
break; break;
case CONFIG_ROM_DESCRIPTOR_LEAF: case CONFIG_ROM_DESCRIPTOR_LEAF:
...@@ -1239,14 +1255,13 @@ static void nodemgr_process_config_rom(struct host_info *hi, ...@@ -1239,14 +1255,13 @@ static void nodemgr_process_config_rom(struct host_info *hi,
ne->busopt.generation = (busoptions >> 4) & 0xf; ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7; ne->busopt.lnkspd = busoptions & 0x7;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
"cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d", "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d",
busoptions, ne->busopt.irmc, ne->busopt.cmc, busoptions, ne->busopt.irmc, ne->busopt.cmc,
ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
ne->busopt.cyc_clk_acc, ne->busopt.max_rec, ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
ne->busopt.generation, ne->busopt.lnkspd); ne->busopt.generation, ne->busopt.lnkspd);
#endif
device_remove_file(&ne->device, &dev_attr_ne_vendor_oui); device_remove_file(&ne->device, &dev_attr_ne_vendor_oui);
nodemgr_process_root_directory(hi, ne); nodemgr_process_root_directory(hi, ne);
...@@ -1301,11 +1316,11 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions, ...@@ -1301,11 +1316,11 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
if (ne->nodeid != nodeid) { if (ne->nodeid != nodeid) {
snprintf(ne->device.name, DEVICE_NAME_SIZE, snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT, "IEEE-1394 device " NODE_BUS_FMT,
hi->host->id, NODE_BUS_ARGS(ne->nodeid)); NODE_BUS_ARGS(hi->host, ne->nodeid));
HPSB_DEBUG("Node changed: %d-" NODE_BUS_FMT " -> %d-" NODE_BUS_FMT, HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
ne->host->id, NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(ne->host, ne->nodeid),
ne->host->id, NODE_BUS_ARGS(nodeid)); NODE_BUS_ARGS(ne->host, nodeid));
ne->nodeid = nodeid; ne->nodeid = nodeid;
update_ud_names++; update_ud_names++;
...@@ -1345,10 +1360,9 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1345,10 +1360,9 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
* work though, and we are forced to doing quadlet sized * work though, and we are forced to doing quadlet sized
* reads. */ * reads. */
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("Initiating ConfigROM request for node " NODE_BUS_FMT,
HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT, NODE_BUS_ARGS(host, nodeid));
NODE_BUS_ARGS(nodeid));
#endif
/* /*
* Must retry a few times if config rom read returns zero (how long?). Will * Must retry a few times if config rom read returns zero (how long?). Will
* not normally occur, but we should do the right thing. For example, with * not normally occur, but we should do the right thing. For example, with
...@@ -1360,7 +1374,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1360,7 +1374,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
if (nodemgr_read_quadlet(host, nodeid, generation, if (nodemgr_read_quadlet(host, nodeid, generation,
addr, &buffer[0]) < 0) { addr, &buffer[0]) < 0) {
HPSB_ERR("ConfigROM quadlet transaction error for node " HPSB_ERR("ConfigROM quadlet transaction error for node "
NODE_BUS_FMT, NODE_BUS_ARGS(nodeid)); NODE_BUS_FMT, NODE_BUS_ARGS(host, nodeid));
return -1; return -1;
} }
if (buffer[0]) if (buffer[0])
...@@ -1377,14 +1391,14 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1377,14 +1391,14 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
if (header_size == 1) { if (header_size == 1) {
HPSB_INFO("Node " NODE_BUS_FMT " has a minimal ROM. " HPSB_INFO("Node " NODE_BUS_FMT " has a minimal ROM. "
"Vendor is %08x", "Vendor is %08x",
NODE_BUS_ARGS(nodeid), buffer[0] & 0x00ffffff); NODE_BUS_ARGS(host, nodeid), buffer[0] & 0x00ffffff);
return -1; return -1;
} }
if (header_size < 4) { if (header_size < 4) {
HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM " HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM "
"format (%d quads), cannot parse", "format (%d quads), cannot parse",
NODE_BUS_ARGS(nodeid), header_size); NODE_BUS_ARGS(host, nodeid), header_size);
return -1; return -1;
} }
...@@ -1393,7 +1407,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned ...@@ -1393,7 +1407,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
addr, &buffer[i]) < 0) { addr, &buffer[i]) < 0) {
HPSB_ERR("ConfigROM quadlet transaction " HPSB_ERR("ConfigROM quadlet transaction "
"error for node " NODE_BUS_FMT, "error for node " NODE_BUS_FMT,
NODE_BUS_ARGS(nodeid)); NODE_BUS_ARGS(host, nodeid));
return -1; return -1;
} }
} }
...@@ -1428,7 +1442,7 @@ static void nodemgr_node_probe_one(struct host_info *hi, ...@@ -1428,7 +1442,7 @@ static void nodemgr_node_probe_one(struct host_info *hi,
* shouldn't be held responsible, so we'll allow it with a * shouldn't be held responsible, so we'll allow it with a
* warning. */ * warning. */
HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]", HPSB_WARN("Node " NODE_BUS_FMT " has invalid busID magic [0x%08x]",
NODE_BUS_ARGS(nodeid), buffer[1]); NODE_BUS_ARGS(host, nodeid), buffer[1]);
} }
guid = ((u64)buffer[3] << 32) | buffer[4]; guid = ((u64)buffer[3] << 32) | buffer[4];
...@@ -1508,8 +1522,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) ...@@ -1508,8 +1522,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
nodemgr_remove_node)) { nodemgr_remove_node)) {
struct node_entry *ne = cleanup.ne; struct node_entry *ne = cleanup.ne;
HPSB_DEBUG("Node removed: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]", HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
host->id, NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid); NODE_BUS_ARGS(host, ne->nodeid), (unsigned long long)ne->guid);
nodemgr_remove_ne(ne); nodemgr_remove_ne(ne);
} }
...@@ -1618,11 +1632,12 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1618,11 +1632,12 @@ static int nodemgr_host_thread(void *__hi)
* happens when we get a bus reset. */ * happens when we get a bus reset. */
while (!down_interruptible(&hi->reset_sem) && while (!down_interruptible(&hi->reset_sem) &&
!down_interruptible(&nodemgr_serialize)) { !down_interruptible(&nodemgr_serialize)) {
unsigned int generation; unsigned int generation = 0;
int i; int i;
/* Pause for 1/4 second, to make sure things settle down. */ /* Pause for 1/4 second in 1/16 second intervals,
for (i = HZ/4; i > 0; i-= HZ/16) { * to make sure things settle down. */
for (i = 0; i < 4 ; i++) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout(HZ/16)) if (schedule_timeout(HZ/16))
goto caught_signal; goto caught_signal;
...@@ -1637,7 +1652,7 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1637,7 +1652,7 @@ static int nodemgr_host_thread(void *__hi)
/* If we get a reset before we are done waiting, then /* If we get a reset before we are done waiting, then
* start the the waiting over again */ * start the the waiting over again */
while (!down_trylock(&hi->reset_sem)) while (!down_trylock(&hi->reset_sem))
i = HZ/4; i = 0;
} }
if (!nodemgr_check_irm_capability(host, reset_cycles++)) { if (!nodemgr_check_irm_capability(host, reset_cycles++)) {
...@@ -1658,9 +1673,7 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1658,9 +1673,7 @@ static int nodemgr_host_thread(void *__hi)
} }
caught_signal: caught_signal:
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("NodeMgr: Exiting thread");
HPSB_DEBUG ("NodeMgr: Exiting thread");
#endif
complete_and_exit(&hi->exited, 0); complete_and_exit(&hi->exited, 0);
} }
...@@ -1782,9 +1795,7 @@ static void nodemgr_host_reset(struct hpsb_host *host) ...@@ -1782,9 +1795,7 @@ static void nodemgr_host_reset(struct hpsb_host *host)
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host); struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi != NULL) { if (hi != NULL) {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name);
HPSB_DEBUG ("NodeMgr: Processing host reset for %s", hi->daemon_name);
#endif
up(&hi->reset_sem); up(&hi->reset_sem);
} else } else
HPSB_ERR ("NodeMgr: could not process reset of unused host"); HPSB_ERR ("NodeMgr: could not process reset of unused host");
......
...@@ -88,6 +88,8 @@ struct bus_options { ...@@ -88,6 +88,8 @@ struct bus_options {
#define UNIT_DIRECTORY_VERSION 0x08 #define UNIT_DIRECTORY_VERSION 0x08
#define UNIT_DIRECTORY_VENDOR_TEXT 0x10 #define UNIT_DIRECTORY_VENDOR_TEXT 0x10
#define UNIT_DIRECTORY_MODEL_TEXT 0x20 #define UNIT_DIRECTORY_MODEL_TEXT 0x20
#define UNIT_DIRECTORY_HAS_LUN_DIRECTORY 0x40
#define UNIT_DIRECTORY_LUN_DIRECTORY 0x80
/* /*
* A unit directory corresponds to a protocol supported by the * A unit directory corresponds to a protocol supported by the
......
...@@ -47,9 +47,6 @@ ...@@ -47,9 +47,6 @@
* Adam J Richter <adam@yggdrasil.com> * Adam J Richter <adam@yggdrasil.com>
* . Use of pci_class to find device * . Use of pci_class to find device
* *
* Andreas Tobler <toa@pop.agri.ch>
* . Updated proc_fs calls
*
* Emilie Chung <emilie.chung@axis.com> * Emilie Chung <emilie.chung@axis.com>
* . Tip on Async Request Filter * . Tip on Async Request Filter
* *
...@@ -74,7 +71,6 @@ ...@@ -74,7 +71,6 @@
* Ben Collins <bcollins@debian.org> * Ben Collins <bcollins@debian.org>
* . Working big-endian support * . Working big-endian support
* . Updated to 2.4.x module scheme (PCI aswell) * . Updated to 2.4.x module scheme (PCI aswell)
* . Removed procfs support since it trashes random mem
* . Config ROM generation * . Config ROM generation
* *
* Manfred Weihs <weihs@ict.tuwien.ac.at> * Manfred Weihs <weihs@ict.tuwien.ac.at>
...@@ -98,6 +94,7 @@ ...@@ -98,6 +94,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/irq.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -164,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) ...@@ -164,7 +161,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 986 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1011 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */ /* Module Parameters */
static int phys_dma = 1; static int phys_dma = 1;
...@@ -502,6 +499,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci); ...@@ -502,6 +499,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci);
/* Global initialization */ /* Global initialization */
static void ohci_initialize(struct ti_ohci *ohci) static void ohci_initialize(struct ti_ohci *ohci)
{ {
char irq_buf[16];
quadlet_t buf; quadlet_t buf;
spin_lock_init(&ohci->phy_reg_lock); spin_lock_init(&ohci->phy_reg_lock);
...@@ -601,10 +599,15 @@ static void ohci_initialize(struct ti_ohci *ohci) ...@@ -601,10 +599,15 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable); reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
buf = reg_read(ohci, OHCI1394_Version); buf = reg_read(ohci, OHCI1394_Version);
PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d] " #ifndef __sparc__
sprintf (irq_buf, "%d", ohci->dev->irq);
#else
sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq));
#endif
PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%s] "
"MMIO=[%lx-%lx] Max Packet=[%d]", "MMIO=[%lx-%lx] Max Packet=[%d]",
((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), ohci->dev->irq, ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf,
pci_resource_start(ohci->dev, 0), pci_resource_start(ohci->dev, 0),
pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
ohci->max_packet_size); ohci->max_packet_size);
...@@ -625,7 +628,7 @@ static void insert_packet(struct ti_ohci *ohci, ...@@ -625,7 +628,7 @@ static void insert_packet(struct ti_ohci *ohci,
DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT
", tlabel=%d, tcode=0x%x, speed=%d", ", tlabel=%d, tcode=0x%x, speed=%d",
NODE_BUS_ARGS(packet->node_id), packet->tlabel, NODE_BUS_ARGS(ohci->host, packet->node_id), packet->tlabel,
packet->tcode, packet->speed_code); packet->tcode, packet->speed_code);
d->prg_cpu[idx]->begin.address = 0; d->prg_cpu[idx]->begin.address = 0;
...@@ -650,8 +653,8 @@ static void insert_packet(struct ti_ohci *ohci, ...@@ -650,8 +653,8 @@ static void insert_packet(struct ti_ohci *ohci,
if (packet->type == hpsb_raw) { if (packet->type == hpsb_raw) {
d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4); d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4);
d->prg_cpu[idx]->data[1] = packet->header[0]; d->prg_cpu[idx]->data[1] = cpu_to_le32(packet->header[0]);
d->prg_cpu[idx]->data[2] = packet->header[1]; d->prg_cpu[idx]->data[2] = cpu_to_le32(packet->header[1]);
} else { } else {
d->prg_cpu[idx]->data[0] = packet->speed_code<<16 | d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
(packet->header[0] & 0xFFFF); (packet->header[0] & 0xFFFF);
...@@ -1146,8 +1149,7 @@ struct ohci_iso_recv { ...@@ -1146,8 +1149,7 @@ struct ohci_iso_recv {
u32 ContextMatch; u32 ContextMatch;
}; };
static void ohci_iso_recv_bufferfill_task(unsigned long data); static void ohci_iso_recv_task(unsigned long data);
static void ohci_iso_recv_packetperbuf_task(unsigned long data);
static void ohci_iso_recv_stop(struct hpsb_iso *iso); static void ohci_iso_recv_stop(struct hpsb_iso *iso);
static void ohci_iso_recv_shutdown(struct hpsb_iso *iso); static void ohci_iso_recv_shutdown(struct hpsb_iso *iso);
static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync); static int ohci_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync);
...@@ -1237,10 +1239,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) ...@@ -1237,10 +1239,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
ohci1394_init_iso_tasklet(&recv->task, ohci1394_init_iso_tasklet(&recv->task,
iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE : iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE :
OHCI_ISO_RECEIVE, OHCI_ISO_RECEIVE,
recv->dma_mode == BUFFER_FILL_MODE ? ohci_iso_recv_task, (unsigned long) iso);
ohci_iso_recv_bufferfill_task :
ohci_iso_recv_packetperbuf_task,
(unsigned long) iso);
if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0)
goto err; goto err;
...@@ -1665,18 +1664,14 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso ...@@ -1665,18 +1664,14 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_iso
hpsb_iso_wake(iso); hpsb_iso_wake(iso);
} }
static void ohci_iso_recv_bufferfill_task(unsigned long data) static void ohci_iso_recv_bufferfill_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv)
{ {
struct hpsb_iso *iso = (struct hpsb_iso*) data;
struct ohci_iso_recv *recv = iso->hostdata;
int loop; int loop;
/* loop over all blocks */ /* loop over all blocks */
for (loop = 0; loop < recv->nblocks; loop++) { for (loop = 0; loop < recv->nblocks; loop++) {
/* check block_dma to see if it's done */ /* check block_dma to see if it's done */
struct dma_cmd *im = &recv->block[recv->block_dma]; struct dma_cmd *im = &recv->block[recv->block_dma];
/* check the DMA descriptor for new writes to xferStatus */ /* check the DMA descriptor for new writes to xferStatus */
...@@ -1726,10 +1721,8 @@ static void ohci_iso_recv_bufferfill_task(unsigned long data) ...@@ -1726,10 +1721,8 @@ static void ohci_iso_recv_bufferfill_task(unsigned long data)
ohci_iso_recv_bufferfill_parse(iso, recv); ohci_iso_recv_bufferfill_parse(iso, recv);
} }
static void ohci_iso_recv_packetperbuf_task(unsigned long data) static void ohci_iso_recv_packetperbuf_task(struct hpsb_iso *iso, struct ohci_iso_recv *recv)
{ {
struct hpsb_iso *iso = (struct hpsb_iso*) data;
struct ohci_iso_recv *recv = iso->hostdata;
int count; int count;
int wake = 0; int wake = 0;
...@@ -1803,6 +1796,16 @@ static void ohci_iso_recv_packetperbuf_task(unsigned long data) ...@@ -1803,6 +1796,16 @@ static void ohci_iso_recv_packetperbuf_task(unsigned long data)
hpsb_iso_wake(iso); hpsb_iso_wake(iso);
} }
static void ohci_iso_recv_task(unsigned long data)
{
struct hpsb_iso *iso = (struct hpsb_iso*) data;
struct ohci_iso_recv *recv = iso->hostdata;
if (recv->dma_mode == BUFFER_FILL_MODE)
ohci_iso_recv_bufferfill_task(iso, recv);
else
ohci_iso_recv_packetperbuf_task(iso, recv);
}
/*********************************** /***********************************
* rawiso ISO transmission * * rawiso ISO transmission *
...@@ -2125,6 +2128,9 @@ static int ohci_isoctl(struct hpsb_iso *iso, enum isoctl_cmd cmd, unsigned long ...@@ -2125,6 +2128,9 @@ static int ohci_isoctl(struct hpsb_iso *iso, enum isoctl_cmd cmd, unsigned long
case RECV_RELEASE: case RECV_RELEASE:
ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg); ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg);
return 0; return 0;
case RECV_FLUSH:
ohci_iso_recv_task((unsigned long) iso);
return 0;
case RECV_SHUTDOWN: case RECV_SHUTDOWN:
ohci_iso_recv_shutdown(iso); ohci_iso_recv_shutdown(iso);
return 0; return 0;
...@@ -3465,7 +3471,31 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) ...@@ -3465,7 +3471,31 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
case OHCI_INIT_DONE: case OHCI_INIT_DONE:
hpsb_remove_host(ohci->host); hpsb_remove_host(ohci->host);
/* Clear out BUS Options */
reg_write(ohci, OHCI1394_ConfigROMhdr, 0);
reg_write(ohci, OHCI1394_BusOptions,
(reg_read(ohci, OHCI1394_BusOptions) & 0x0000f007) |
0x00ff0000);
memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN);
case OHCI_INIT_HAVE_IRQ: case OHCI_INIT_HAVE_IRQ:
/* Clear interrupt registers */
reg_write(ohci, OHCI1394_IntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, 0xffffffff);
reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 0xffffffff);
/* Disable IRM Contender */
set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4));
/* Clear link control register */
reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
/* Let all other nodes know to ignore us */
ohci_devctl(ohci->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
/* Soft reset before we start - this disables /* Soft reset before we start - this disables
* interrupts and clears linkEnable and LPS. */ * interrupts and clears linkEnable and LPS. */
ohci_soft_reset(ohci); ohci_soft_reset(ohci);
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/irq.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
...@@ -1457,6 +1458,14 @@ static void remove_card(struct pci_dev *dev) ...@@ -1457,6 +1458,14 @@ static void remove_card(struct pci_dev *dev)
case have_intr: case have_intr:
reg_write(lynx, PCI_INT_ENABLE, 0); reg_write(lynx, PCI_INT_ENABLE, 0);
free_irq(lynx->dev->irq, lynx); free_irq(lynx->dev->irq, lynx);
/* Disable IRM Contender */
if (lynx->phyic.reg_1394a)
set_phy_reg(lynx, 4, ~0xc0 & get_phy_reg(lynx, 4));
/* Let all other nodes know to ignore us */
lynx_devctl(lynx->host, RESET_BUS, LONG_RESET_NO_FORCE_ROOT);
case have_iomappings: case have_iomappings:
reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
/* Fix buggy cards with autoboot pin not tied low: */ /* Fix buggy cards with autoboot pin not tied low: */
...@@ -1504,6 +1513,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1504,6 +1513,7 @@ static int __devinit add_card(struct pci_dev *dev,
return error; \ return error; \
} while (0) } while (0)
char irq_buf[16];
struct hpsb_host *host; struct hpsb_host *host;
struct ti_lynx *lynx; /* shortcut to currently handled device */ struct ti_lynx *lynx; /* shortcut to currently handled device */
struct ti_pcl pcl; struct ti_pcl pcl;
...@@ -1603,12 +1613,18 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1603,12 +1613,18 @@ static int __devinit add_card(struct pci_dev *dev,
/* Fix buggy cards with autoboot pin not tied low: */ /* Fix buggy cards with autoboot pin not tied low: */
reg_write(lynx, DMA0_CHAN_CTRL, 0); reg_write(lynx, DMA0_CHAN_CTRL, 0);
#ifndef __sparc__
sprintf (irq_buf, "%d", dev->irq);
#else
sprintf (irq_buf, "%s", __irq_itoa(dev->irq));
#endif
if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ, if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ,
PCILYNX_DRIVER_NAME, lynx)) { PCILYNX_DRIVER_NAME, lynx)) {
PRINT(KERN_INFO, lynx->id, "allocated interrupt %d", dev->irq); PRINT(KERN_INFO, lynx->id, "allocated interrupt %s", irq_buf);
lynx->state = have_intr; lynx->state = have_intr;
} else { } else {
FAIL("failed to allocate shared interrupt %d", dev->irq); FAIL("failed to allocate shared interrupt %s", irq_buf);
} }
/* alloc_pcl return values are not checked, it is expected that the /* alloc_pcl return values are not checked, it is expected that the
...@@ -1787,9 +1803,8 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1787,9 +1803,8 @@ static int __devinit add_card(struct pci_dev *dev,
i2c_adapter.algo_data = &i2c_adapter_data; i2c_adapter.algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx; i2c_adapter_data.data = lynx;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
PRINT(KERN_DEBUG, lynx->id,"original eeprom control: %d",reg_read(lynx,SERIAL_EEPROM_CONTROL)); reg_read(lynx, SERIAL_EEPROM_CONTROL));
#endif
/* reset hardware to sane state */ /* reset hardware to sane state */
lynx->i2c_driven_state = 0x00000070; lynx->i2c_driven_state = 0x00000070;
...@@ -1832,17 +1847,16 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1832,17 +1847,16 @@ static int __devinit add_card(struct pci_dev *dev,
if (i2c_transfer(&i2c_adapter, msg, 2) < 0) { if (i2c_transfer(&i2c_adapter, msg, 2) < 0) {
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else { } else {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
int i; int i;
#endif
PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom");
/* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), generation(1394a) and link_spd(1394a) field /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a),
and recalculate the CRC */ * generation(1394a) and link_spd(1394a) field and recalculate
* the CRC */
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG for (i = 0; i < 5 ; i++)
for (i=0; i < 5 ; i++) PRINTD(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",
PRINT(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",i, be32_to_cpu(lynx->config_rom[i])); i, be32_to_cpu(lynx->config_rom[i]));
#endif
/* info_length, crc_length and 1394 magic number to check, if it is really a bus info block */ /* info_length, crc_length and 1394 magic number to check, if it is really a bus info block */
if (((be32_to_cpu(lynx->config_rom[0]) & 0xffff0000) == 0x04040000) && if (((be32_to_cpu(lynx->config_rom[0]) & 0xffff0000) == 0x04040000) &&
......
...@@ -1566,8 +1566,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1566,8 +1566,8 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
req->req.length, ((req->req.misc >> 8) & 0xFF), req->req.length, ((req->req.misc >> 8) & 0xFF),
(req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF)); (req->req.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF));
/* check addressrange */ /* check addressrange */
if ((((req->req.address) & ~(0xFFFFFFFFFFFF)) != 0) || if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) ||
(((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFF)) != 0)) { (((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) {
req->req.length = 0; req->req.length = 0;
return (-EINVAL); return (-EINVAL);
} }
...@@ -2273,6 +2273,8 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -2273,6 +2273,8 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
return raw1394_iso_recv_packets(fi, (void*) arg); return raw1394_iso_recv_packets(fi, (void*) arg);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
return hpsb_iso_recv_release_packets(fi->iso_handle, arg); return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
case RAW1394_IOC_ISO_RECV_FLUSH:
return hpsb_iso_recv_flush(fi->iso_handle);
case RAW1394_IOC_ISO_SHUTDOWN: case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi); raw1394_iso_shutdown(fi);
return 0; return 0;
......
...@@ -51,7 +51,6 @@ ...@@ -51,7 +51,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -81,7 +80,7 @@ ...@@ -81,7 +80,7 @@
#include "sbp2.h" #include "sbp2.h"
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 967 $ Ben Collins <bcollins@debian.org>"; "$Rev: 1010 $ Ben Collins <bcollins@debian.org>";
/* /*
* Module load parameter definitions * Module load parameter definitions
...@@ -611,6 +610,11 @@ static int sbp2_probe(struct device *dev) ...@@ -611,6 +610,11 @@ static int sbp2_probe(struct device *dev)
ud = container_of(dev, struct unit_directory, device); ud = container_of(dev, struct unit_directory, device);
/* Don't probe UD's that have the LUN flag. We'll probe the LUN(s)
* instead. */
if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY)
return -ENODEV;
/* This will only add it if it doesn't exist */ /* This will only add it if it doesn't exist */
hi = sbp2_add_host(ud->ne->host); hi = sbp2_add_host(ud->ne->host);
...@@ -1142,7 +1146,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) ...@@ -1142,7 +1146,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
SBP2_DEBUG("sbp2_query_logins: orb byte-swapped"); SBP2_DEBUG("sbp2_query_logins: orb byte-swapped");
sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(stuct sbp2_query_logins_orb), sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb),
"sbp2 query logins orb", scsi_id->query_logins_orb_dma); "sbp2 query logins orb", scsi_id->query_logins_orb_dma);
memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response));
...@@ -1620,7 +1624,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, ...@@ -1620,7 +1624,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
SBP2_128KB_BROKEN_FIRMWARE && SBP2_128KB_BROKEN_FIRMWARE &&
(max_sectors * 512) > (128*1024)) { (max_sectors * 512) > (128*1024)) {
SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.", SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.",
NODE_BUS_ARGS(ud->ne->nodeid)); NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid));
SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!", SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!",
max_sectors); max_sectors);
workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
...@@ -1633,12 +1637,19 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, ...@@ -1633,12 +1637,19 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
if ((firmware_revision & 0xffff00) == if ((firmware_revision & 0xffff00) ==
sbp2_broken_inquiry_list[i]) { sbp2_broken_inquiry_list[i]) {
SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
NODE_BUS_ARGS(ud->ne->nodeid)); NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid));
workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
break; /* No need to continue. */ break; /* No need to continue. */
} }
} }
/* If this is a logical unit directory entry, process the parent
* to get the common values. */
if (ud->flags & UNIT_DIRECTORY_LUN_DIRECTORY) {
struct unit_directory *parent_ud =
container_of(ud->device.parent, struct unit_directory, device);
sbp2_parse_unit_directory(scsi_group, parent_ud);
} else {
/* If our list is empty, add a base scsi_id (happens in a normal /* If our list is empty, add a base scsi_id (happens in a normal
* case where there is no logical_unit_number entry */ * case where there is no logical_unit_number entry */
if (list_empty(&scsi_group->scsi_id_list)) { if (list_empty(&scsi_group->scsi_id_list)) {
...@@ -1664,6 +1675,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group, ...@@ -1664,6 +1675,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
scsi_id->sbp2_firmware_revision = firmware_revision; scsi_id->sbp2_firmware_revision = firmware_revision;
scsi_id->workarounds = workarounds; scsi_id->workarounds = workarounds;
} }
}
} }
/* /*
...@@ -1697,8 +1709,9 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) ...@@ -1697,8 +1709,9 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
scsi_id->max_payload_size = min(sbp2_speedto_max_payload[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]",
NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code], NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid),
hpsb_speedto_str[scsi_id->speed_code],
1 << ((u32)scsi_id->max_payload_size + 2)); 1 << ((u32)scsi_id->max_payload_size + 2));
return(0); return(0);
...@@ -2845,70 +2858,6 @@ static const char *sbp2scsi_info (struct Scsi_Host *host) ...@@ -2845,70 +2858,6 @@ static const char *sbp2scsi_info (struct Scsi_Host *host)
return "SCSI emulation for IEEE-1394 SBP-2 Devices"; return "SCSI emulation for IEEE-1394 SBP-2 Devices";
} }
/* Called for contents of procfs */
#define SPRINTF(args...) \
do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
static int sbp2scsi_proc_info(struct Scsi_Host *scsi_host, char *buffer, char **start, off_t offset,
int length, int inout)
{
Scsi_Device *scd;
struct hpsb_host *host;
char *pos = buffer;
/* if someone is sending us data, just throw it away */
if (inout)
return length;
host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host);
if (!host) /* shouldn't happen, but... */
return -ESRCH;
SPRINTF("Host scsi%d : SBP-2 IEEE-1394 (%s)\n",
scsi_host->host_no, host->driver->name);
SPRINTF("Driver version : %s\n", version);
SPRINTF("\nModule options :\n");
SPRINTF(" max_speed : %s\n", hpsb_speedto_str[max_speed]);
SPRINTF(" max_sectors : %d\n", max_sectors);
SPRINTF(" serialize_io : %s\n", serialize_io ? "yes" : "no");
SPRINTF(" exclusive_login : %s\n", exclusive_login ? "yes" : "no");
SPRINTF("\nAttached devices : %s\n", !list_empty(&scsi_host->my_devices) ?
"" : "none");
list_for_each_entry (scd, &scsi_host->my_devices, siblings) {
int i;
SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel,
scd->id, scd->lun);
SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ?
scsi_device_types[(short) scd->type] : "Unknown device");
for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++)
SPRINTF("%c", scd->vendor[i]);
SPRINTF(" ");
for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++)
SPRINTF("%c", scd->model[i]);
SPRINTF("\n");
}
SPRINTF("\n");
/* Calculate start of next buffer, and return value. */
*start = buffer + offset;
if ((pos - buffer) < offset)
return (0);
else if ((pos - buffer - offset) < length)
return (pos - buffer - offset);
else
return (length);
}
MODULE_AUTHOR("Ben Collins <bcollins@debian.org>"); MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver"); MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
...@@ -2920,7 +2869,6 @@ static Scsi_Host_Template scsi_driver_template = { ...@@ -2920,7 +2869,6 @@ static Scsi_Host_Template scsi_driver_template = {
.name = "SBP-2 IEEE-1394", .name = "SBP-2 IEEE-1394",
.proc_name = SBP2_DEVICE_NAME, .proc_name = SBP2_DEVICE_NAME,
.info = sbp2scsi_info, .info = sbp2scsi_info,
.proc_info = sbp2scsi_proc_info,
.queuecommand = sbp2scsi_queuecommand, .queuecommand = sbp2scsi_queuecommand,
.eh_abort_handler = sbp2scsi_abort, .eh_abort_handler = sbp2scsi_abort,
.eh_device_reset_handler = sbp2scsi_reset, .eh_device_reset_handler = sbp2scsi_reset,
...@@ -2939,6 +2887,8 @@ static int sbp2_module_init(void) ...@@ -2939,6 +2887,8 @@ static int sbp2_module_init(void)
{ {
SBP2_DEBUG("sbp2_module_init"); SBP2_DEBUG("sbp2_module_init");
printk(KERN_INFO "sbp2: %s\n", version);
/* Module load debug option to force one command at a time (serializing I/O) */ /* Module load debug option to force one command at a time (serializing I/O) */
if (serialize_io) { if (serialize_io) {
SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)"); SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#include <linux/bitops.h> #include <linux/bitops.h>
......
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