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)
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)
{
......@@ -100,6 +131,7 @@ static void add_host(struct hpsb_host *host)
host->csr.node_ids = 0;
host->csr.split_timeout_hi = 0;
host->csr.split_timeout_lo = 800 << 19;
calculate_expire(&host->csr);
host->csr.cycle_time = 0;
host->csr.bus_time = 0;
host->csr.bus_manager_id = 0x3f;
......@@ -336,10 +368,12 @@ static int write_regs(struct hpsb_host *host, int nodeid, int destid,
case CSR_SPLIT_TIMEOUT_HI:
host->csr.split_timeout_hi =
be32_to_cpu(*(data++)) & 0x00000007;
calculate_expire(&host->csr);
out;
case CSR_SPLIT_TIMEOUT_LO:
host->csr.split_timeout_lo =
be32_to_cpu(*(data++)) & 0xfff80000;
calculate_expire(&host->csr);
out;
/* address gap */
......@@ -410,7 +444,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
* eventually. */
HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
"broadcast channel 31. Ignoring.",
NODE_BUS_ARGS(nodeid));
NODE_BUS_ARGS(host, nodeid));
data &= ~0x1; /* keep broadcast channel allocated */
}
......@@ -556,7 +590,7 @@ static int lock64_regs(struct hpsb_host *host, int nodeid, octlet_t * store,
* eventually. */
HPSB_WARN("Node [" NODE_BUS_FMT "] wants to release "
"broadcast channel 31. Ignoring.",
NODE_BUS_ARGS(nodeid));
NODE_BUS_ARGS(host, nodeid));
data &= ~0x100000000ULL; /* keep broadcast channel allocated */
}
......
......@@ -41,6 +41,7 @@ struct csr_control {
quadlet_t state;
quadlet_t node_ids;
quadlet_t split_timeout_hi, split_timeout_lo;
unsigned long expire; // Calculated from split_timeout
quadlet_t cycle_time;
quadlet_t bus_time;
quadlet_t bus_manager_id;
......
......@@ -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++) {
if (off < sg_dma_len(&dma->sglist[i])) {
*rem = off;
return i;
break;
}
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)
......
/*
* dv1394-private.h - DV input/output over IEEE 1394 on OHCI chips
* 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:
* video1394.h - driver for OHCI 1394 boards
......
/*
* dv1394.c - DV input/output over IEEE 1394 on OHCI chips
* 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:
* video1394.c - video driver for OHCI 1394 boards
......@@ -80,7 +80,6 @@
- add proc fs interface to set cip_n, cip_d, syt_offset, and video signal
- expose xmit and recv as separate devices (not exclusive)
- expose NTSC and PAL as separate devices (can be overridden)
- read/edit channel in procfs
*/
......@@ -102,7 +101,6 @@
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <asm/pgtable.h>
#include <asm/page.h>
......@@ -1103,7 +1101,7 @@ static int do_dv1394_init_default(struct video_card *video)
init.api_version = DV1394_API_VERSION;
init.n_frames = DV1394_MAX_FRAMES / 4;
/* the following are now set via proc_fs or devfs */
/* the following are now set via devfs */
init.channel = video->channel;
init.format = video->pal_or_ntsc;
init.cip_n = video->cip_n;
......@@ -1857,244 +1855,6 @@ static int dv1394_release(struct inode *inode, struct file *file)
}
/*** PROC_FS INTERFACE ******************************************************/
#ifdef CONFIG_PROC_FS
static LIST_HEAD(dv1394_procfs);
struct dv1394_procfs_entry {
struct list_head list;
struct proc_dir_entry *procfs;
char name[32];
struct dv1394_procfs_entry *parent;
};
static spinlock_t dv1394_procfs_lock = SPIN_LOCK_UNLOCKED;
static int dv1394_procfs_read( char *page, char **start, off_t off,
int count, int *eof, void *data)
{
struct video_card *video = (struct video_card*) data;
snprintf( page, count,
"\
format=%s\n\
channel=%d\n\
cip_n=%lu\n\
cip_d=%lu\n\
syt_offset=%u\n",
(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
video->channel,
video->cip_n, video->cip_d, video->syt_offset );
return strlen(page);
}
/* lifted from the stallion.c driver */
#undef TOLOWER
#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
static unsigned long atol(char *str)
{
unsigned long val;
int base, c;
char *sp;
val = 0;
sp = str;
if ((*sp == '0') && (*(sp+1) == 'x')) {
base = 16;
sp += 2;
} else if (*sp == '0') {
base = 8;
sp++;
} else {
base = 10;
}
for (; (*sp != 0); sp++) {
c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
if ((c < 0) || (c >= base)) {
printk(KERN_ERR "dv1394: atol() invalid argument %s\n", str);
val = 0;
break;
}
val = (val * base) + c;
}
return(val);
}
static int dv1394_procfs_write( struct file *file,
const char *buffer, unsigned long count, void *data)
{
int len = 0;
char new_value[65];
char *pos;
struct video_card *video = (struct video_card*) data;
if (count > 64)
len = 64;
else
len = count;
if (copy_from_user( new_value, buffer, len))
return -EFAULT;
new_value[len] = 0;
pos = strchr(new_value, '=');
if (pos != NULL) {
int val_len = len - (pos-new_value) - 1;
char buf[65];
memset(buf, 0, 65);
strncpy(buf, pos+1, val_len);
if (buf[val_len-1] == '\n') buf[val_len-1] = 0;
if (strnicmp( new_value, "format", (pos-new_value)) == 0) {
if (strnicmp( buf, "NTSC", val_len) == 0)
video->pal_or_ntsc = DV1394_NTSC;
else if (strnicmp( buf, "PAL", val_len) == 0)
video->pal_or_ntsc = DV1394_PAL;
} else if (strnicmp( new_value, "cip_n", (pos-new_value)) == 0) {
video->cip_n = atol(buf);
} else if (strnicmp( new_value, "cip_d", (pos-new_value)) == 0) {
video->cip_d = atol(buf);
} else if (strnicmp( new_value, "syt_offset", (pos-new_value)) == 0) {
video->syt_offset = atol(buf);
} else if (strnicmp( new_value, "channel", (pos-new_value)) == 0) {
video->channel = atol(buf);
}
}
return len;
}
struct dv1394_procfs_entry *
dv1394_procfs_find( char *name)
{
struct list_head *lh;
struct dv1394_procfs_entry *p;
spin_lock( &dv1394_procfs_lock);
if (!list_empty(&dv1394_procfs)) {
list_for_each(lh, &dv1394_procfs) {
p = list_entry(lh, struct dv1394_procfs_entry, list);
if (!strncmp(p->name, name, sizeof(p->name))) {
spin_unlock( &dv1394_procfs_lock);
return p;
}
}
}
spin_unlock( &dv1394_procfs_lock);
return NULL;
}
static int dv1394_procfs_add_entry(struct video_card *video)
{
char buf[32];
struct dv1394_procfs_entry *p;
struct dv1394_procfs_entry *parent;
p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
if (!p) {
printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
goto err;
}
memset(p, 0, sizeof(struct dv1394_procfs_entry));
snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2),
(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"));
parent = dv1394_procfs_find(buf);
if (parent == NULL) {
printk(KERN_ERR "dv1394: unable to locate parent procfs of %s\n", buf);
goto err_free;
}
p->procfs = create_proc_entry(
(video->mode == MODE_RECEIVE ? "in" : "out"),
0666, parent->procfs);
if (p->procfs == NULL) {
printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s/%s\n",
parent->name,
(video->mode == MODE_RECEIVE ? "in" : "out"));
goto err_free;
}
p->procfs->owner = THIS_MODULE;
p->procfs->data = video;
p->procfs->read_proc = dv1394_procfs_read;
p->procfs->write_proc = dv1394_procfs_write;
spin_lock( &dv1394_procfs_lock);
INIT_LIST_HEAD(&p->list);
list_add_tail(&p->list, &dv1394_procfs);
spin_unlock( &dv1394_procfs_lock);
return 0;
err_free:
kfree(p);
err:
return -ENOMEM;
}
static int
dv1394_procfs_add_dir( char *name,
struct dv1394_procfs_entry *parent,
struct dv1394_procfs_entry **out)
{
struct dv1394_procfs_entry *p;
p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);
if (!p) {
printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");
goto err;
}
memset(p, 0, sizeof(struct dv1394_procfs_entry));
if (parent == NULL) {
snprintf(p->name, sizeof(p->name), "%s", name);
p->procfs = proc_mkdir( name, ieee1394_procfs_entry);
} else {
snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name);
p->procfs = proc_mkdir( name, parent->procfs);
}
if (p->procfs == NULL) {
printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s\n", p->name);
goto err_free;
}
p->procfs->owner = THIS_MODULE;
p->parent = parent;
if (out != NULL) *out = p;
spin_lock( &dv1394_procfs_lock);
INIT_LIST_HEAD(&p->list);
list_add_tail(&p->list, &dv1394_procfs);
spin_unlock( &dv1394_procfs_lock);
return 0;
err_free:
kfree(p);
err:
return -ENOMEM;
}
void dv1394_procfs_del( char *name)
{
struct dv1394_procfs_entry *p = dv1394_procfs_find(name);
if (p != NULL) {
if (p->parent == NULL)
remove_proc_entry(p->name, ieee1394_procfs_entry);
else
remove_proc_entry(p->name, p->parent->procfs);
spin_lock( &dv1394_procfs_lock);
list_del(&p->list);
spin_unlock( &dv1394_procfs_lock);
kfree(p);
}
}
#endif /* CONFIG_PROC_FS */
/*** DEVICE DRIVER HANDLERS ************************************************/
static void it_tasklet_func(unsigned long data)
......@@ -2485,18 +2245,13 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
video->channel = 63; /* default to broadcast channel */
video->active_frame = -1;
/* initialize the following for proc_fs */
/* initialize the following */
video->pal_or_ntsc = format;
video->cip_n = 0; /* 0 = use builtin default */
video->cip_d = 0;
video->syt_offset = 0;
video->mode = mode;
#ifdef CONFIG_PROC_FS
if ( dv1394_procfs_add_entry(video) < 0 )
goto err_free;
#endif
for (i = 0; i < DV1394_MAX_FRAMES; i++)
video->frames[i] = NULL;
......@@ -2548,9 +2303,6 @@ static void dv1394_un_init(struct video_card *video)
);
devfs_remove("ieee1394/%s", buf);
#ifdef CONFIG_PROC_FS
dv1394_procfs_del(buf);
#endif
list_del(&video->list);
kfree(video);
}
......@@ -2562,7 +2314,6 @@ static void dv1394_remove_host (struct hpsb_host *host)
struct video_card *video = NULL;
unsigned long flags;
struct list_head *lh, *templh;
char buf[32];
int n;
/* We only work with the OHCI-1394 driver */
......@@ -2588,21 +2339,11 @@ static void dv1394_remove_host (struct hpsb_host *host)
devfs_remove("ieee1394/dv/host%d/NTSC", n);
devfs_remove("ieee1394/dv/host%d/PAL", n);
devfs_remove("ieee1394/dv/host%d", n);
#ifdef CONFIG_PROC_FS
snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
dv1394_procfs_del(buf);
snprintf(buf, sizeof(buf), "dv/host%d/PAL", n);
dv1394_procfs_del(buf);
snprintf(buf, sizeof(buf), "dv/host%d", n);
dv1394_procfs_del(buf);
#endif
}
static void dv1394_add_host (struct hpsb_host *host)
{
struct ti_ohci *ohci;
char buf[16];
/* We only work with the OHCI-1394 driver */
if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
......@@ -2610,19 +2351,6 @@ static void dv1394_add_host (struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
#ifdef CONFIG_PROC_FS
{
struct dv1394_procfs_entry *p;
p = dv1394_procfs_find("dv");
if (p != NULL) {
snprintf(buf, sizeof(buf), "host%d", ohci->id);
dv1394_procfs_add_dir(buf, p, &p);
dv1394_procfs_add_dir("NTSC", p, NULL);
dv1394_procfs_add_dir("PAL", p, NULL);
}
}
#endif
devfs_mk_dir("ieee1394/dv/host%d", ohci->id);
devfs_mk_dir("ieee1394/dv/host%d/NTSC", ohci->id);
devfs_mk_dir("ieee1394/dv/host%d/PAL", ohci->id);
......@@ -2881,9 +2609,6 @@ static void __exit dv1394_exit_module(void)
hpsb_unregister_highlevel(&dv1394_highlevel);
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
devfs_remove("ieee1394/dv");
#ifdef CONFIG_PROC_FS
dv1394_procfs_del("dv");
#endif
}
static int __init dv1394_init_module(void)
......@@ -2899,16 +2624,6 @@ static int __init dv1394_init_module(void)
devfs_mk_dir("ieee1394/dv");
#ifdef CONFIG_PROC_FS
ret = dv1394_procfs_add_dir("dv",NULL,NULL);
if (ret < 0) {
printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
devfs_remove("ieee1394/dv");
return -ENOMEM;
}
#endif
hpsb_register_highlevel(&dv1394_highlevel);
hpsb_register_protocol(&dv1394_driver);
......
/*
* dv1394.h - DV input/output over IEEE 1394 on OHCI chips
* 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:
* video1394.h - driver for OHCI 1394 boards
......
......@@ -89,7 +89,7 @@
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata =
"$Rev: 986 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1010 $ Ben Collins <bcollins@debian.org>";
struct fragment_info {
struct list_head list;
......@@ -1285,7 +1285,7 @@ static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
if (hpsb_get_tlabel(p, !in_interrupt())) {
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;
}
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)
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, driver_name);
strcpy (info.version, "$Rev: 986 $");
strcpy (info.version, "$Rev: 1010 $");
/* FIXME XXX provide sane businfo */
strcpy (info.bus_info, "ieee1394");
if (copy_to_user (useraddr, &info, sizeof (info)))
......
......@@ -21,6 +21,7 @@ struct hpsb_address_serve {
*/
struct hpsb_highlevel {
struct module *owner;
const char *name;
/* Any of the following pointers can legally be NULL, except for
......
......@@ -16,7 +16,6 @@
#include <linux/list.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "ieee1394_types.h"
#include "hosts.h"
......@@ -67,7 +66,7 @@ int hpsb_ref_host(struct hpsb_host *host)
list_for_each(lh, &hpsb_hosts) {
if (host == list_entry(lh, struct hpsb_host, host_list)) {
if (try_module_get(host->driver->owner)) {
host->refcount++;
atomic_inc(&host->refcount);
retval = 1;
}
break;
......@@ -92,9 +91,7 @@ void hpsb_unref_host(struct hpsb_host *host)
module_put(host->driver->owner);
down(&hpsb_hosts_lock);
host->refcount--;
if (!host->refcount && host->is_shutdown)
if (atomic_dec_and_test(&host->refcount) && host->is_shutdown)
kfree(host);
up(&hpsb_hosts_lock);
}
......@@ -131,7 +128,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
h->hostdata = h + 1;
h->driver = drv;
h->refcount = 1;
atomic_set(&h->refcount, 1);
INIT_LIST_HEAD(&h->pending_packets);
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)
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->speed_map = (u8 *)(h->csr.speed_map + 2);
......
......@@ -4,7 +4,7 @@
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <asm/semaphore.h>
#include "ieee1394_types.h"
......@@ -29,11 +29,12 @@ struct hpsb_host {
atomic_t generation;
int refcount;
atomic_t refcount;
struct list_head pending_packets;
spinlock_t pending_pkt_lock;
struct work_struct timeout_tq;
struct timer_list timeout;
unsigned long timeout_interval;
unsigned char iso_listen_count[64];
......@@ -107,6 +108,7 @@ enum devctl_cmd {
enum isoctl_cmd {
/* rawiso API - see iso.h for the meanings of these commands
(they correspond exactly to the hpsb_iso_* API functions)
* INIT = allocate resources
* START = begin transmission/reception
* STOP = halt transmission/reception
......@@ -128,6 +130,7 @@ enum isoctl_cmd {
RECV_STOP,
RECV_RELEASE,
RECV_SHUTDOWN,
RECV_FLUSH
};
enum reset_types {
......
......@@ -100,6 +100,8 @@
_IOW ('#', 0x27, struct raw1394_iso_packets)
#define RAW1394_IOC_ISO_XMIT_SYNC \
_IO ('#', 0x28)
#define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29)
#endif /* __IEEE1394_IOCTL_H */
......@@ -29,9 +29,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
#include <asm/byteorder.h>
#include <asm/semaphore.h>
......@@ -62,6 +60,7 @@ static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */
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)
{
int i;
......@@ -70,11 +69,13 @@ static void dump_packet(const char *text, quadlet_t *data, int size)
size = (size > 4 ? 4 : size);
printk(KERN_DEBUG "ieee1394: %s", text);
for (i = 0; i < size; i++) {
printk(" %8.8x", data[i]);
}
for (i = 0; i < size; i++)
printk(" %08x", data[i]);
printk("\n");
}
#else
#define dump_packet(x,y,z)
#endif
static void run_packet_complete(struct hpsb_packet *packet)
{
......@@ -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)
{
if (host->in_bus_reset) {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_INFO("Including SelfID 0x%x", sid);
#endif
HPSB_VERBOSE("Including SelfID 0x%x", sid);
host->topology_map[host->selfid_count++] = sid;
} else {
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)
} else {
HPSB_NOTICE("Stopping out-of-control reset loop");
HPSB_NOTICE("Warning - topology map and speed map will not be valid");
host->reset_retries = 0;
}
} else {
host->reset_retries = 0;
build_speed_map(host, host->node_count);
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_INFO("selfid_complete called with successful SelfID stage "
HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
"... 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() */
if (host->irm_id == host->node_id) {
host->is_irm = 1;
......@@ -440,7 +440,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
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)
}
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
dump_packet("send packet local:", packet->header,
packet->header_size);
#endif
hpsb_packet_sent(host, packet, packet->expect_response?ACK_PENDING:ACK_COMPLETE);
hpsb_packet_received(host, data, size, 0);
......@@ -568,7 +567,6 @@ int hpsb_send_packet(struct hpsb_packet *packet)
+ NODEID_TO_NODE(packet->node_id)];
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
switch (packet->speed_code) {
case 2:
dump_packet("send packet 400:", packet->header,
......@@ -582,7 +580,6 @@ int hpsb_send_packet(struct hpsb_packet *packet)
dump_packet("send packet 100:", packet->header,
packet->header_size);
}
#endif
return host->driver->transmit_packet(host, packet);
}
......@@ -617,7 +614,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
}
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);
spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
return;
......@@ -641,7 +638,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
if (!tcode_match || (packet->tlabel != tlabel)
|| (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);
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,
return;
}
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
dump_packet("received packet:", data, size);
#endif
tcode = (data[0] >> 4) & 0xf;
......@@ -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;
struct hpsb_packet *packet;
unsigned long expire;
struct list_head *lh, *next, *tlh;
struct list_head *lh, *tlh;
LIST_HEAD(expiredlist);
spin_lock_irqsave(&host->csr.lock, flags);
expire = (host->csr.split_timeout_hi * 8000
+ (host->csr.split_timeout_lo >> 19))
* HZ / 8000;
/* Avoid shortening of timeout due to rounding errors: */
expire++;
expire = host->csr.expire;
spin_unlock_irqrestore(&host->csr.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);
next = lh->next;
if (time_before(packet->sendtime + expire, jiffies)) {
list_del(&packet->list);
list_add(&packet->list, &expiredlist);
......@@ -988,7 +978,7 @@ void abort_timedouts(struct hpsb_host *host)
}
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);
......@@ -1179,8 +1169,6 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
return retval;
}
struct proc_dir_entry *ieee1394_procfs_entry;
static int __init ieee1394_init(void)
{
hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
......@@ -1194,19 +1182,6 @@ static int __init ieee1394_init(void)
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_csr();
if (!disable_nodemgr)
......@@ -1227,7 +1202,6 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
devfs_remove("ieee1394");
remove_proc_entry("ieee1394", proc_bus);
}
module_init(ieee1394_init);
......@@ -1257,7 +1231,6 @@ EXPORT_SYMBOL(hpsb_packet_sent);
EXPORT_SYMBOL(hpsb_packet_received);
EXPORT_SYMBOL(ieee1394_register_chardev);
EXPORT_SYMBOL(ieee1394_unregister_chardev);
EXPORT_SYMBOL(ieee1394_procfs_entry);
/** ieee1394_transactions.c **/
EXPORT_SYMBOL(hpsb_get_tlabel);
......@@ -1341,3 +1314,4 @@ EXPORT_SYMBOL(hpsb_iso_n_ready);
EXPORT_SYMBOL(hpsb_iso_packet_sent);
EXPORT_SYMBOL(hpsb_iso_packet_received);
EXPORT_SYMBOL(hpsb_iso_wake);
EXPORT_SYMBOL(hpsb_iso_recv_flush);
......@@ -4,7 +4,6 @@
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/proc_fs.h>
#include <asm/semaphore.h>
#include "hosts.h"
......@@ -88,7 +87,7 @@ static inline struct hpsb_packet *driver_packet(struct list_head *l)
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);
struct hpsb_packet *alloc_hpsb_packet(size_t data_size);
......@@ -224,9 +223,6 @@ int ieee1394_register_chardev(int blocknum, /* 0-15 */
/* release a block of minor numbers */
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 */
extern struct bus_type ieee1394_bus_type;
......
......@@ -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;
u8 specifier_id_lo = specifier_id & 0xff;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG("Send GASP: channel = %d, length = %d", channel, length);
#endif
HPSB_VERBOSE("Send GASP: channel = %d, length = %d", channel, length);
length += 8;
......
......@@ -61,8 +61,9 @@ typedef u16 arm_length_t;
#define NODEID_TO_NODE(nodeid) (nodeid & NODE_MASK)
/* Can be used to consistently print a node/bus ID. */
#define NODE_BUS_FMT "%02d:%04d"
#define NODE_BUS_ARGS(nodeid) NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid)
#define NODE_BUS_FMT "%d-%02d:%04d"
#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)
......@@ -72,6 +73,12 @@ typedef u16 arm_length_t;
#define HPSB_WARN(fmt, args...) HPSB_PRINT(KERN_WARNING, 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_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)
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)
{
int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
......
......@@ -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 */
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 */
int hpsb_iso_n_ready(struct hpsb_iso *iso);
......
......@@ -424,8 +424,15 @@ static void nodemgr_release_ne(struct device *dev)
static void nodemgr_remove_ud(struct unit_directory *ud)
{
struct device *dev = &ud->device;
struct list_head *lh, *next;
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++)
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)
ud = container_of(list_to_dev(lh), struct unit_directory, device);
snprintf(ud->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 unit directory %d-" NODE_BUS_FMT "-%u",
hi->host->id, NODE_BUS_ARGS(ne->nodeid), ud->id);
"IEEE-1394 unit directory " NODE_BUS_FMT "-%u",
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
snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
(unsigned long long)(ne->guid));
snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT, host->id,
NODE_BUS_ARGS(ne->nodeid));
"IEEE-1394 device " NODE_BUS_FMT,
NODE_BUS_ARGS(host, ne->nodeid));
device_register(&ne->device);
......@@ -727,9 +734,9 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoption
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->id, NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
return ne;
}
......@@ -911,7 +918,8 @@ static struct unit_directory *nodemgr_scan_unit_directory
* immediate unit directories looking for software_id and
* software_version entries, in order to get driver autoloading working. */
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;
quadlet_t quad;
......@@ -1001,12 +1009,14 @@ static struct unit_directory *nodemgr_process_unit_directory
break;
case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY:
/* TODO: Parent this with it's UD */
ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id);
ud->flags |= UNIT_DIRECTORY_HAS_LUN_DIRECTORY;
ud_temp = nodemgr_process_unit_directory(hi, ne, address + value * 4, id,
parent);
if (ud_temp == NULL)
break;
/* inherit unspecified values */
if (ud_temp != NULL)
{
if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) &&
!(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID))
{
......@@ -1032,7 +1042,6 @@ static struct unit_directory *nodemgr_process_unit_directory
ud_temp->flags |= UNIT_DIRECTORY_VERSION;
ud_temp->version = ud->version;
}
}
break;
......@@ -1049,7 +1058,13 @@ static struct unit_directory *nodemgr_process_unit_directory
memcpy(&ud->device, &nodemgr_dev_template_ud,
sizeof(ud->device));
if (parent) {
ud->flags |= UNIT_DIRECTORY_LUN_DIRECTORY;
ud->device.parent = &parent->device;
} else
ud->device.parent = &ne->device;
snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
ne->device.bus_id, ud->id);
......@@ -1125,7 +1140,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
break;
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;
case CONFIG_ROM_DESCRIPTOR_LEAF:
......@@ -1239,14 +1255,13 @@ static void nodemgr_process_config_rom(struct host_info *hi,
ne->busopt.generation = (busoptions >> 4) & 0xf;
ne->busopt.lnkspd = busoptions & 0x7;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
HPSB_VERBOSE("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",
busoptions, ne->busopt.irmc, ne->busopt.cmc,
ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
ne->busopt.generation, ne->busopt.lnkspd);
#endif
device_remove_file(&ne->device, &dev_attr_ne_vendor_oui);
nodemgr_process_root_directory(hi, ne);
......@@ -1301,11 +1316,11 @@ static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
if (ne->nodeid != nodeid) {
snprintf(ne->device.name, DEVICE_NAME_SIZE,
"IEEE-1394 device %d-" NODE_BUS_FMT,
hi->host->id, NODE_BUS_ARGS(ne->nodeid));
HPSB_DEBUG("Node changed: %d-" NODE_BUS_FMT " -> %d-" NODE_BUS_FMT,
ne->host->id, NODE_BUS_ARGS(ne->nodeid),
ne->host->id, NODE_BUS_ARGS(nodeid));
"IEEE-1394 device " NODE_BUS_FMT,
NODE_BUS_ARGS(hi->host, ne->nodeid));
HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
NODE_BUS_ARGS(ne->host, ne->nodeid),
NODE_BUS_ARGS(ne->host, nodeid));
ne->nodeid = nodeid;
update_ud_names++;
......@@ -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
* reads. */
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
NODE_BUS_ARGS(nodeid));
#endif
HPSB_VERBOSE("Initiating ConfigROM request for node " NODE_BUS_FMT,
NODE_BUS_ARGS(host, nodeid));
/*
* 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
......@@ -1360,7 +1374,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
if (nodemgr_read_quadlet(host, nodeid, generation,
addr, &buffer[0]) < 0) {
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;
}
if (buffer[0])
......@@ -1377,14 +1391,14 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
if (header_size == 1) {
HPSB_INFO("Node " NODE_BUS_FMT " has a minimal ROM. "
"Vendor is %08x",
NODE_BUS_ARGS(nodeid), buffer[0] & 0x00ffffff);
NODE_BUS_ARGS(host, nodeid), buffer[0] & 0x00ffffff);
return -1;
}
if (header_size < 4) {
HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM "
"format (%d quads), cannot parse",
NODE_BUS_ARGS(nodeid), header_size);
NODE_BUS_ARGS(host, nodeid), header_size);
return -1;
}
......@@ -1393,7 +1407,7 @@ static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid, unsigned
addr, &buffer[i]) < 0) {
HPSB_ERR("ConfigROM quadlet transaction "
"error for node " NODE_BUS_FMT,
NODE_BUS_ARGS(nodeid));
NODE_BUS_ARGS(host, nodeid));
return -1;
}
}
......@@ -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
* warning. */
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];
......@@ -1508,8 +1522,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
nodemgr_remove_node)) {
struct node_entry *ne = cleanup.ne;
HPSB_DEBUG("Node removed: ID:BUS[%d-" NODE_BUS_FMT "] GUID[%016Lx]",
host->id, NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid);
HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(host, ne->nodeid), (unsigned long long)ne->guid);
nodemgr_remove_ne(ne);
}
......@@ -1618,11 +1632,12 @@ static int nodemgr_host_thread(void *__hi)
* happens when we get a bus reset. */
while (!down_interruptible(&hi->reset_sem) &&
!down_interruptible(&nodemgr_serialize)) {
unsigned int generation;
unsigned int generation = 0;
int i;
/* Pause for 1/4 second, to make sure things settle down. */
for (i = HZ/4; i > 0; i-= HZ/16) {
/* Pause for 1/4 second in 1/16 second intervals,
* to make sure things settle down. */
for (i = 0; i < 4 ; i++) {
set_current_state(TASK_INTERRUPTIBLE);
if (schedule_timeout(HZ/16))
goto caught_signal;
......@@ -1637,7 +1652,7 @@ static int nodemgr_host_thread(void *__hi)
/* If we get a reset before we are done waiting, then
* start the the waiting over again */
while (!down_trylock(&hi->reset_sem))
i = HZ/4;
i = 0;
}
if (!nodemgr_check_irm_capability(host, reset_cycles++)) {
......@@ -1658,9 +1673,7 @@ static int nodemgr_host_thread(void *__hi)
}
caught_signal:
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG ("NodeMgr: Exiting thread");
#endif
HPSB_VERBOSE("NodeMgr: Exiting thread");
complete_and_exit(&hi->exited, 0);
}
......@@ -1782,9 +1795,7 @@ static void nodemgr_host_reset(struct hpsb_host *host)
struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
if (hi != NULL) {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
HPSB_DEBUG ("NodeMgr: Processing host reset for %s", hi->daemon_name);
#endif
HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name);
up(&hi->reset_sem);
} else
HPSB_ERR ("NodeMgr: could not process reset of unused host");
......
......@@ -88,6 +88,8 @@ struct bus_options {
#define UNIT_DIRECTORY_VERSION 0x08
#define UNIT_DIRECTORY_VENDOR_TEXT 0x10
#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
......
......@@ -47,9 +47,6 @@
* Adam J Richter <adam@yggdrasil.com>
* . Use of pci_class to find device
*
* Andreas Tobler <toa@pop.agri.ch>
* . Updated proc_fs calls
*
* Emilie Chung <emilie.chung@axis.com>
* . Tip on Async Request Filter
*
......@@ -74,7 +71,6 @@
* Ben Collins <bcollins@debian.org>
* . Working big-endian support
* . Updated to 2.4.x module scheme (PCI aswell)
* . Removed procfs support since it trashes random mem
* . Config ROM generation
*
* Manfred Weihs <weihs@ict.tuwien.ac.at>
......@@ -98,6 +94,7 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
......@@ -164,7 +161,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: 986 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1011 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......@@ -502,6 +499,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci);
/* Global initialization */
static void ohci_initialize(struct ti_ohci *ohci)
{
char irq_buf[16];
quadlet_t buf;
spin_lock_init(&ohci->phy_reg_lock);
......@@ -601,10 +599,15 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
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]",
((((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) + OHCI1394_REGISTER_SIZE - 1,
ohci->max_packet_size);
......@@ -625,7 +628,7 @@ static void insert_packet(struct ti_ohci *ohci,
DBGMSG(ohci->id, "Inserting packet for node " NODE_BUS_FMT
", 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);
d->prg_cpu[idx]->begin.address = 0;
......@@ -650,8 +653,8 @@ static void insert_packet(struct ti_ohci *ohci,
if (packet->type == hpsb_raw) {
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[2] = packet->header[1];
d->prg_cpu[idx]->data[1] = cpu_to_le32(packet->header[0]);
d->prg_cpu[idx]->data[2] = cpu_to_le32(packet->header[1]);
} else {
d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
(packet->header[0] & 0xFFFF);
......@@ -1146,8 +1149,7 @@ struct ohci_iso_recv {
u32 ContextMatch;
};
static void ohci_iso_recv_bufferfill_task(unsigned long data);
static void ohci_iso_recv_packetperbuf_task(unsigned long data);
static void ohci_iso_recv_task(unsigned long data);
static void ohci_iso_recv_stop(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);
......@@ -1237,10 +1239,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
ohci1394_init_iso_tasklet(&recv->task,
iso->channel == -1 ? OHCI_ISO_MULTICHANNEL_RECEIVE :
OHCI_ISO_RECEIVE,
recv->dma_mode == BUFFER_FILL_MODE ?
ohci_iso_recv_bufferfill_task :
ohci_iso_recv_packetperbuf_task,
(unsigned long) iso);
ohci_iso_recv_task, (unsigned long) iso);
if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0)
goto err;
......@@ -1665,18 +1664,14 @@ static void ohci_iso_recv_bufferfill_parse(struct hpsb_iso *iso, struct ohci_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;
/* loop over all blocks */
for (loop = 0; loop < recv->nblocks; loop++) {
/* check block_dma to see if it's done */
struct dma_cmd *im = &recv->block[recv->block_dma];
/* check the DMA descriptor for new writes to xferStatus */
......@@ -1726,10 +1721,8 @@ static void ohci_iso_recv_bufferfill_task(unsigned long data)
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 wake = 0;
......@@ -1803,6 +1796,16 @@ static void ohci_iso_recv_packetperbuf_task(unsigned long data)
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 *
......@@ -2125,6 +2128,9 @@ static int ohci_isoctl(struct hpsb_iso *iso, enum isoctl_cmd cmd, unsigned long
case RECV_RELEASE:
ohci_iso_recv_release(iso, (struct hpsb_iso_packet_info*) arg);
return 0;
case RECV_FLUSH:
ohci_iso_recv_task((unsigned long) iso);
return 0;
case RECV_SHUTDOWN:
ohci_iso_recv_shutdown(iso);
return 0;
......@@ -3465,7 +3471,31 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
case OHCI_INIT_DONE:
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:
/* 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
* interrupts and clears linkEnable and LPS. */
ohci_soft_reset(ohci);
......
......@@ -42,6 +42,7 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/kdev_t.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
......@@ -1457,6 +1458,14 @@ static void remove_card(struct pci_dev *dev)
case have_intr:
reg_write(lynx, PCI_INT_ENABLE, 0);
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:
reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
/* Fix buggy cards with autoboot pin not tied low: */
......@@ -1504,6 +1513,7 @@ static int __devinit add_card(struct pci_dev *dev,
return error; \
} while (0)
char irq_buf[16];
struct hpsb_host *host;
struct ti_lynx *lynx; /* shortcut to currently handled device */
struct ti_pcl pcl;
......@@ -1603,12 +1613,18 @@ static int __devinit add_card(struct pci_dev *dev,
/* Fix buggy cards with autoboot pin not tied low: */
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,
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;
} 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
......@@ -1787,9 +1803,8 @@ static int __devinit add_card(struct pci_dev *dev,
i2c_adapter.algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx;
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
PRINT(KERN_DEBUG, lynx->id,"original eeprom control: %d",reg_read(lynx,SERIAL_EEPROM_CONTROL));
#endif
PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
reg_read(lynx, SERIAL_EEPROM_CONTROL));
/* reset hardware to sane state */
lynx->i2c_driven_state = 0x00000070;
......@@ -1832,17 +1847,16 @@ static int __devinit add_card(struct pci_dev *dev,
if (i2c_transfer(&i2c_adapter, msg, 2) < 0) {
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else {
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
int i;
#endif
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
and recalculate the CRC */
/* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a),
* generation(1394a) and link_spd(1394a) field and recalculate
* the CRC */
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
for (i=0; i < 5 ; i++)
PRINT(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",i, be32_to_cpu(lynx->config_rom[i]));
#endif
for (i = 0; i < 5 ; i++)
PRINTD(KERN_DEBUG, lynx->id, "Businfo block quadlet %i: %08x",
i, be32_to_cpu(lynx->config_rom[i]));
/* 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) &&
......
......@@ -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.misc & 0xFF),((req->req.misc >> 16) & 0xFFFF));
/* check addressrange */
if ((((req->req.address) & ~(0xFFFFFFFFFFFF)) != 0) ||
(((req->req.address + req->req.length) & ~(0xFFFFFFFFFFFF)) != 0)) {
if ((((req->req.address) & ~((u64)0xFFFFFFFFFFFFLL)) != 0) ||
(((req->req.address + req->req.length) & ~((u64)0xFFFFFFFFFFFFLL)) != 0)) {
req->req.length = 0;
return (-EINVAL);
}
......@@ -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);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
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:
raw1394_iso_shutdown(fi);
return 0;
......
......@@ -51,7 +51,6 @@
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
......@@ -81,7 +80,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 967 $ Ben Collins <bcollins@debian.org>";
"$Rev: 1010 $ Ben Collins <bcollins@debian.org>";
/*
* Module load parameter definitions
......@@ -611,6 +610,11 @@ static int sbp2_probe(struct device *dev)
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 */
hi = sbp2_add_host(ud->ne->host);
......@@ -1142,7 +1146,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
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);
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,
SBP2_128KB_BROKEN_FIRMWARE &&
(max_sectors * 512) > (128*1024)) {
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)!",
max_sectors);
workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
......@@ -1633,12 +1637,19 @@ static void sbp2_parse_unit_directory(struct scsi_id_group *scsi_group,
if ((firmware_revision & 0xffff00) ==
sbp2_broken_inquiry_list[i]) {
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;
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
* case where there is no logical_unit_number entry */
if (list_empty(&scsi_group->scsi_id_list)) {
......@@ -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->workarounds = workarounds;
}
}
}
/*
......@@ -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],
(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
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],
SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]",
NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid),
hpsb_speedto_str[scsi_id->speed_code],
1 << ((u32)scsi_id->max_payload_size + 2));
return(0);
......@@ -2845,70 +2858,6 @@ static const char *sbp2scsi_info (struct Scsi_Host *host)
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_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
......@@ -2920,7 +2869,6 @@ static Scsi_Host_Template scsi_driver_template = {
.name = "SBP-2 IEEE-1394",
.proc_name = SBP2_DEVICE_NAME,
.info = sbp2scsi_info,
.proc_info = sbp2scsi_proc_info,
.queuecommand = sbp2scsi_queuecommand,
.eh_abort_handler = sbp2scsi_abort,
.eh_device_reset_handler = sbp2scsi_reset,
......@@ -2939,6 +2887,8 @@ static int sbp2_module_init(void)
{
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) */
if (serialize_io) {
SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
......
......@@ -34,7 +34,6 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/devfs_fs_kernel.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