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
......
This diff is collapsed.
/*
* 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,19 +60,22 @@ 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;
int i;
size /= 4;
size = (size > 4 ? 4 : size);
size /= 4;
size = (size > 4 ? 4 : size);
printk(KERN_DEBUG "ieee1394: %s", text);
for (i = 0; i < size; i++) {
printk(" %8.8x", data[i]);
}
printk("\n");
printk(KERN_DEBUG "ieee1394: %s", text);
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 "
"... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
#endif
HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
"... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
/* 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);
......
This diff is collapsed.
......@@ -82,12 +82,14 @@ struct bus_options {
};
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
#define UNIT_DIRECTORY_VERSION 0x08
#define UNIT_DIRECTORY_VENDOR_TEXT 0x10
#define UNIT_DIRECTORY_MODEL_TEXT 0x20
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
#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,36 +1637,44 @@ 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 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)) {
scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
if (!scsi_id) {
SBP2_ERR("Out of memory adding scsi_id");
return;
}
memset(scsi_id, 0, sizeof(*scsi_id));
/* 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)) {
scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
if (!scsi_id) {
SBP2_ERR("Out of memory adding scsi_id");
return;
}
memset(scsi_id, 0, sizeof(*scsi_id));
scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list);
}
scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
list_add_tail(&scsi_id->list, &scsi_group->scsi_id_list);
}
/* Update the generic fields in all the LUN's */
list_for_each (lh, &scsi_group->scsi_id_list) {
scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
/* Update the generic fields in all the LUN's */
list_for_each (lh, &scsi_group->scsi_id_list) {
scsi_id = list_entry(lh, struct scsi_id_instance_data, list);
scsi_id->sbp2_management_agent_addr = management_agent_addr;
scsi_id->sbp2_command_set_spec_id = command_set_spec_id;
scsi_id->sbp2_command_set = command_set;
scsi_id->sbp2_unit_characteristics = unit_characteristics;
scsi_id->sbp2_firmware_revision = firmware_revision;
scsi_id->workarounds = workarounds;
scsi_id->sbp2_management_agent_addr = management_agent_addr;
scsi_id->sbp2_command_set_spec_id = command_set_spec_id;
scsi_id->sbp2_command_set = command_set;
scsi_id->sbp2_unit_characteristics = unit_characteristics;
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