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

[PATCH] Linux IEEE-1394 Updates

 - Cleanup (purge) some of our old compat code (never thouched)
 - Fix dv1394 compilation warnings without devfs
 - Added new config-rom handling features. Allows for on-the-fly
   config-rom generation for dynamic functionality of the host nodes.
 - Convert to workqueue from taskqueue interfaces. This is actually
   abstracted compatibility code between tqueue/workqueue.
parent 34d3616d
......@@ -199,7 +199,7 @@ static void cmp_remove_host(struct hpsb_host *host)
}
static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf,
u64 addr, unsigned int length)
u64 addr, unsigned int length, u16 flags)
{
int csraddr = addr - CSR_REGISTER_BASE;
int plug;
......@@ -235,7 +235,7 @@ static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf,
}
static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int extcode)
u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 flags)
{
int csraddr = addr - CSR_REGISTER_BASE;
int plug;
......
......@@ -4,20 +4,33 @@
* CSR implementation, iso/bus manager implementation.
*
* Copyright (C) 1999 Andreas E. Bombe
* 2002 Manfred Weihs <weihs@ict.tuwien.ac.at>
*
* This code is licensed under the GPL. See the file COPYING in the root
* directory of the kernel sources for details.
*
*
* Contributions:
*
* Manfred Weihs <weihs@ict.tuwien.ac.at>
* configuration ROM manipulation
*
*/
#include <linux/string.h>
#include <linux/module.h> /* needed for MODULE_PARM */
#include "ieee1394_types.h"
#include "hosts.h"
#include "ieee1394.h"
#include "highlevel.h"
/* Module Parameters */
/* this module parameter can be used to disable mapping of the FCP registers */
MODULE_PARM(fcp,"i");
MODULE_PARM_DESC(fcp, "FCP-registers");
static int fcp = 1;
/* FIXME: this one won't work on little endian with big endian data */
static u16 csr_crc16(unsigned *data, int length)
{
int check=0, i;
......@@ -25,7 +38,7 @@ static u16 csr_crc16(unsigned *data, int length)
for (i = length; i; i--) {
for (next = check, shift = 28; shift >= 0; shift -= 4 ) {
sum = ((next >> 12) ^ (*data >> shift)) & 0xf;
sum = ((next >> 12) ^ (be32_to_cpu(*data) >> shift)) & 0xf;
next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
}
check = next & 0xffff;
......@@ -60,6 +73,8 @@ static void host_reset(struct hpsb_host *host)
| csr_crc16(host->csr.topology_map + 1,
host->selfid_count + 2));
host->csr.speed_map[1] =
cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1);
host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16
| csr_crc16(host->csr.speed_map+1,
0x3f1));
......@@ -71,7 +86,7 @@ static void add_host(struct hpsb_host *host)
host->csr.lock = SPIN_LOCK_UNLOCKED;
host->csr.rom_size = host->driver->get_rom(host, &host->csr.rom);
host->csr.rom_version = 0;
host->csr.state = 0;
host->csr.node_ids = 0;
host->csr.split_timeout_hi = 0;
......@@ -84,13 +99,52 @@ static void add_host(struct hpsb_host *host)
host->csr.channels_available_lo = ~0;
}
int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom,
size_t size, unsigned char rom_version)
{
int ret,flags;
spin_lock_irqsave(&host->csr.lock, flags);
if (rom_version != host->csr.rom_version)
ret = -1;
else if (size > (CSR_CONFIG_ROM_SIZE << 2))
ret = -2;
else {
memcpy(host->csr.rom,new_rom,size);
host->csr.rom_size=size;
host->csr.rom_version++;
ret=0;
}
spin_unlock_irqrestore(&host->csr.lock, flags);
return ret;
}
int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer,
size_t buffersize, size_t *rom_size, unsigned char *rom_version)
{
int ret,flags;
spin_lock_irqsave(&host->csr.lock, flags);
*rom_version=host->csr.rom_version;
*rom_size=host->csr.rom_size;
if (buffersize < host->csr.rom_size)
ret = -1;
else {
memcpy(buffer,host->csr.rom,host->csr.rom_size);
ret=0;
}
spin_unlock_irqrestore(&host->csr.lock, flags);
return ret;
}
/* Read topology / speed maps and configuration ROM */
static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, unsigned int length)
u64 addr, unsigned int length, u16 fl)
{
int csraddr = addr - CSR_REGISTER_BASE;
const char *src;
int flags;
spin_lock_irqsave(&host->csr.lock, flags);
if (csraddr < CSR_TOPOLOGY_MAP) {
if (csraddr + length > CSR_CONFIG_ROM + host->csr.rom_size) {
......@@ -105,6 +159,7 @@ static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
}
memcpy(buffer, src, length);
spin_unlock_irqrestore(&host->csr.lock, flags);
return RCODE_COMPLETE;
}
......@@ -112,7 +167,7 @@ static int read_maps(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
#define out if (--length == 0) break
static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
u64 addr, unsigned int length)
u64 addr, unsigned int length, u16 flags)
{
int csraddr = addr - CSR_REGISTER_BASE;
int oldcycle;
......@@ -222,7 +277,7 @@ static int read_regs(struct hpsb_host *host, int nodeid, quadlet_t *buf,
}
static int write_regs(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length)
quadlet_t *data, u64 addr, unsigned int length, u16 flags)
{
int csraddr = addr - CSR_REGISTER_BASE;
......@@ -302,7 +357,7 @@ static int write_regs(struct hpsb_host *host, int nodeid, int destid,
static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int extcode)
u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 fl)
{
int csraddr = addr - CSR_REGISTER_BASE;
unsigned long flags;
......@@ -379,7 +434,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
}
static int write_fcp(struct hpsb_host *host, int nodeid, int dest,
quadlet_t *data, u64 addr, unsigned int length)
quadlet_t *data, u64 addr, unsigned int length, u16 flags)
{
int csraddr = addr - CSR_REGISTER_BASE;
......@@ -436,9 +491,11 @@ void init_csr(void)
hpsb_register_addrspace(hl, &map_ops,
CSR_REGISTER_BASE + CSR_CONFIG_ROM,
CSR_REGISTER_BASE + CSR_CONFIG_ROM_END);
hpsb_register_addrspace(hl, &fcp_ops,
if (fcp) {
hpsb_register_addrspace(hl, &fcp_ops,
CSR_REGISTER_BASE + CSR_FCP_COMMAND,
CSR_REGISTER_BASE + CSR_FCP_END);
}
hpsb_register_addrspace(hl, &map_ops,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP,
CSR_REGISTER_BASE + CSR_TOPOLOGY_MAP_END);
......
......@@ -41,8 +41,10 @@ struct csr_control {
quadlet_t bandwidth_available;
quadlet_t channels_available_hi, channels_available_lo;
const quadlet_t *rom;
quadlet_t *rom;
size_t rom_size;
unsigned char rom_version;
quadlet_t topology_map[256];
quadlet_t speed_map[1024];
......
......@@ -97,7 +97,6 @@
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/tqueue.h>
#include <linux/delay.h>
#include <asm/pgtable.h>
#include <asm/page.h>
......@@ -2587,6 +2586,7 @@ dv1394_devfs_find( char *name)
return p;
}
#ifdef CONFIG_DEVFS_FS
static int dv1394_devfs_add_entry(struct video_card *video)
{
char buf[32];
......@@ -2694,6 +2694,7 @@ void dv1394_devfs_del( char *name)
kfree(p);
}
}
#endif /* CONFIG_DEVFS_FS */
/*** IEEE1394 HPSB CALLBACKS ***********************************************/
......@@ -2852,7 +2853,6 @@ static void dv1394_add_host (struct hpsb_host *host)
{
struct ti_ohci *ohci;
char buf[16];
struct dv1394_devfs_entry *devfs_entry;
/* We only work with the OHCI-1394 driver */
if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
......@@ -2874,13 +2874,15 @@ static void dv1394_add_host (struct hpsb_host *host)
#endif
#ifdef CONFIG_DEVFS_FS
devfs_entry = dv1394_devfs_find("dv");
{
struct dv1394_devfs_entry = devfs_entry = dv1394_devfs_find("dv");
if (devfs_entry != NULL) {
snprintf(buf, sizeof(buf), "host%d", ohci->id);
dv1394_devfs_add_dir(buf, devfs_entry, &devfs_entry);
dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
}
}
#endif
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
......
......@@ -77,7 +77,7 @@
printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata =
"$Rev: 546 $ Ben Collins <bcollins@debian.org>";
"$Rev: 601 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
......@@ -522,7 +522,7 @@ static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct
* ethernet header, and fill it with some of our other fields. This is
* an incoming packet from the 1394 bus. */
static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
quadlet_t *data, u64 addr, unsigned int len)
quadlet_t *data, u64 addr, unsigned int len, u16 fl)
{
struct sk_buff *skb;
char *buf = (char *)data;
......@@ -682,8 +682,8 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
ptask->skb = skb;
ptask->addr = addr;
ptask->dest_node = dest_node;
INIT_TQUEUE(&ptask->tq, hpsb_write_sched, ptask);
schedule_task(&ptask->tq);
HPSB_INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
hpsb_schedule_work(&ptask->tq);
return 0;
fail:
......
......@@ -56,7 +56,7 @@ struct packet_task {
struct sk_buff *skb; /* Socket buffer we are sending */
nodeid_t dest_node; /* Destination of the packet */
u64 addr; /* Address */
struct tq_struct tq; /* The task */
struct hpsb_queue_struct tq; /* The task */
};
/* IP1394 headers */
......
......@@ -5,6 +5,16 @@
*
* This code is licensed under the GPL. See the file COPYING in the root
* directory of the kernel sources for details.
*
*
* Contributions:
*
* Christian Toegel <christian.toegel@gmx.at>
* unregister address space
*
* Manfred Weihs <weihs@ict.tuwien.ac.at>
* unregister address space
*
*/
#include <linux/config.h>
......@@ -129,6 +139,32 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
return retval;
}
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
{
int retval = 0;
struct hpsb_address_serve *as;
struct list_head *entry;
write_lock_irq(&addr_space_lock);
entry = hl->addr_list.next;
while (entry != &hl->addr_list) {
as = list_entry(entry, struct hpsb_address_serve, addr_list);
entry = entry->next;
if (as->start == start) {
list_del(&as->as_list);
list_del(&as->addr_list);
kfree(as);
retval = 1;
break;
}
}
write_unlock_irq(&addr_space_lock);
return retval;
}
void hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel)
......@@ -243,7 +279,7 @@ void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
}
int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, unsigned int length)
u64 addr, unsigned int length, u16 flags)
{
struct hpsb_address_serve *as;
struct list_head *entry;
......@@ -261,7 +297,7 @@ int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
if (as->op->read != NULL) {
rcode = as->op->read(host, nodeid, buffer,
addr, partlength);
addr, partlength, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
......@@ -288,7 +324,7 @@ int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
}
int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length)
quadlet_t *data, u64 addr, unsigned int length, u16 flags)
{
struct hpsb_address_serve *as;
struct list_head *entry;
......@@ -306,7 +342,7 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
if (as->op->write != NULL) {
rcode = as->op->write(host, nodeid, destid,
data, addr, partlength);
data, addr, partlength, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
......@@ -334,7 +370,7 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode)
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags)
{
struct hpsb_address_serve *as;
struct list_head *entry;
......@@ -349,7 +385,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
if (as->end > addr) {
if (as->op->lock != NULL) {
rcode = as->op->lock(host, nodeid, store, addr,
data, arg, ext_tcode);
data, arg, ext_tcode, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
......@@ -367,7 +403,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
}
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode)
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags)
{
struct hpsb_address_serve *as;
struct list_head *entry;
......@@ -383,7 +419,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
if (as->op->lock64 != NULL) {
rcode = as->op->lock64(host, nodeid, store,
addr, data, arg,
ext_tcode);
ext_tcode, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
......
......@@ -74,17 +74,22 @@ struct hpsb_address_ops {
*/
/* These functions have to implement block reads for themselves. */
/* These functions either return a response code
or a negative number. In the first case a response will be generated; in the
later case, no response will be sent and the driver, that handled the request
will send the response itself
*/
int (*read) (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, unsigned int length);
u64 addr, unsigned int length, u16 flags);
int (*write) (struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length);
quadlet_t *data, u64 addr, unsigned int length, u16 flags);
/* Lock transactions: write results of ext_tcode operation into
* *store. */
int (*lock) (struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode);
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
int (*lock64) (struct hpsb_host *host, int nodeid, octlet_t *store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode);
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
};
......@@ -94,14 +99,23 @@ void highlevel_add_host(struct hpsb_host *host);
void highlevel_remove_host(struct hpsb_host *host);
void highlevel_host_reset(struct hpsb_host *host);
/* these functions are called to handle transactions. They are called, when
a packet arrives. The flags argument contains the second word of the first header
quadlet of the incoming packet (containing transaction label, retry code,
transaction code and priority). These functions either return a response code
or a negative number. In the first case a response will be generated; in the
later case, no response will be sent and the driver, that handled the request
will send the response itself.
*/
int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
u64 addr, unsigned int length);
u64 addr, unsigned int length, u16 flags);
int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length);
quadlet_t *data, u64 addr, unsigned int length, u16 flags);
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode);
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode);
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
void highlevel_iso_receive(struct hpsb_host *host, quadlet_t *data,
unsigned int length);
......@@ -130,6 +144,8 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
int hpsb_register_addrspace(struct hpsb_highlevel *hl,
struct hpsb_address_ops *ops, u64 start, u64 end);
int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start);
/*
* Enable or disable receving a certain isochronous channel through the
* iso_receive op.
......
......@@ -138,7 +138,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
atomic_set(&h->generation, 0);
INIT_TQUEUE(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
HPSB_INIT_WORK(&h->timeout_tq, (void (*)(void*))abort_timedouts, h);
h->topology_map = h->csr.topology_map + 3;
h->speed_map = (u8 *)(h->csr.speed_map + 2);
......
......@@ -2,13 +2,20 @@
#define _IEEE1394_HOSTS_H
#include <linux/wait.h>
#include <linux/tqueue.h>
#include <linux/list.h>
#include <asm/semaphore.h>
#include "ieee1394_types.h"
#include "csr.h"
/* size of the array used to store config rom (in quadlets)
maximum is 0x100. About 0x40 is needed for the default
entries. So 0x80 should provide enough space for additional
directories etc.
Note: All lowlevel drivers are required to allocate at least
this amount of memory for the configuration rom!
*/
#define CSR_CONFIG_ROM_SIZE 0x100
struct hpsb_packet;
......@@ -23,7 +30,7 @@ struct hpsb_host {
struct list_head pending_packets;
spinlock_t pending_pkt_lock;
struct tq_struct timeout_tq;
struct hpsb_queue_struct timeout_tq;
/* A bitmask where a set bit means that this tlabel is in use.
* FIXME - should be handled per node instead of per bus. */
......@@ -119,7 +126,7 @@ struct hpsb_host_driver {
* may not fail. If any allocation is required, it must be done
* earlier.
*/
size_t (*get_rom) (struct hpsb_host *host, const quadlet_t **pointer);
size_t (*get_rom) (struct hpsb_host *host, quadlet_t **pointer);
/* This function shall implement packet transmission based on
* packet->type. It shall CRC both parts of the packet (unless
......@@ -172,4 +179,24 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra);
void hpsb_add_host(struct hpsb_host *host);
void hpsb_remove_host(struct hpsb_host *h);
/* updates the configuration rom of a host.
* rom_version must be the current version,
* otherwise it will fail with return value -1.
* Return value -2 indicates that the new
* rom version is too big.
* Return value 0 indicates success
*/
int hpsb_update_config_rom(struct hpsb_host *host,
const quadlet_t *new_rom, size_t size, unsigned char rom_version);
/* reads the current version of the configuration rom of a host.
* buffersize is the size of the buffer, rom_size
* returns the size of the current rom image.
* rom_version is the version number of the fetched rom.
* return value -1 indicates, that the buffer was
* too small, 0 indicates success.
*/
int hpsb_get_config_rom(struct hpsb_host *host, quadlet_t *buffer,
size_t buffersize, size_t *rom_size, unsigned char *rom_version);
#endif /* _IEEE1394_HOSTS_H */
This diff is collapsed.
......@@ -2,7 +2,6 @@
#ifndef _IEEE1394_CORE_H
#define _IEEE1394_CORE_H
#include <linux/tqueue.h>
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/proc_fs.h>
......@@ -78,7 +77,7 @@ struct hpsb_packet {
};
/* add a new task for when a packet completes */
void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct tq_struct *tq);
void hpsb_add_packet_complete_task(struct hpsb_packet *packet, struct hpsb_queue_struct *tq);
static inline struct hpsb_packet *driver_packet(struct list_head *l)
{
......
......@@ -297,14 +297,6 @@ int hpsb_packet_success(struct hpsb_packet *packet)
HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
}
int hpsb_read_trylocal(struct hpsb_host *host, nodeid_t node, u64 addr,
quadlet_t *buffer, size_t length)
{
if (host->node_id != node) return -1;
return highlevel_read(host, node, buffer, addr, length);
}
struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node,
u64 addr)
{
......@@ -400,6 +392,31 @@ struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
return p;
}
struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
u64 addr, int extcode)
{
struct hpsb_packet *p;
p = alloc_hpsb_packet(16);
if (!p) return NULL;
p->host = host;
p->tlabel = get_tlabel(host, node, 1);
p->node_id = node;
switch (extcode) {
case EXTCODE_FETCH_ADD:
case EXTCODE_LITTLE_ADD:
fill_async_lock(p, addr, extcode, 8);
break;
default:
fill_async_lock(p, addr, extcode, 16);
break;
}
return p;
}
struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
quadlet_t data)
{
......@@ -429,18 +446,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return -EINVAL;
}
if (host->node_id == node) {
switch(highlevel_read(host, node, buffer, addr, length)) {
case RCODE_COMPLETE:
return 0;
case RCODE_TYPE_ERROR:
return -EACCES;
case RCODE_ADDRESS_ERROR:
default:
return -EINVAL;
}
}
if (length == 4) {
packet = hpsb_make_readqpacket(host, node, addr);
} else {
......@@ -509,18 +514,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
if (host->node_id == node) {
switch(highlevel_write(host, node, node, buffer, addr, length)) {
case RCODE_COMPLETE:
return 0;
case RCODE_TYPE_ERROR:
return -EACCES;
case RCODE_ADDRESS_ERROR:
default:
return -EINVAL;
}
}
packet = hpsb_make_packet (host, node, addr, buffer, length);
if (!packet)
......@@ -551,19 +544,6 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
struct hpsb_packet *packet;
int retval = 0, length;
if (host->node_id == node) {
switch(highlevel_lock(host, node, data, addr, *data, arg,
extcode)) {
case RCODE_COMPLETE:
return 0;
case RCODE_TYPE_ERROR:
return -EACCES;
case RCODE_ADDRESS_ERROR:
default:
return -EINVAL;
}
}
packet = alloc_hpsb_packet(8);
if (!packet) {
return -ENOMEM;
......
......@@ -42,6 +42,8 @@ struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host,
size_t length);
struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, int extcode);
struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
u64 addr, int extcode);
struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
quadlet_t data) ;
......
......@@ -20,23 +20,6 @@
#define __devexit_p(x) x
#endif
/* This showed up around this time */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12)
# ifndef MODULE_LICENSE
# define MODULE_LICENSE(x)
# endif
# ifndef min
# define min(x,y) ({ \
const typeof(x) _x = (x); \
const typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
# endif
#endif /* Linux version < 2.4.12 */
#include <linux/spinlock.h>
#ifndef list_for_each_safe
......@@ -58,10 +41,35 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
/* Compatibility for task/work queues */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,42)
/* Use task queue */
#include <linux/tqueue.h>
#define hpsb_queue_struct tq_struct
#define hpsb_queue_list list
#define hpsb_schedule_work(x) schedule_task(x)
#define HPSB_INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z)
#define HPSB_PREPARE_WORK(x,y,z) PREPARE_TQUEUE(x,y,z)
#else
/* Use work queue */
#include <linux/workqueue.h>
#define hpsb_queue_struct work_struct
#define hpsb_queue_list entry
#define hpsb_schedule_work(x) schedule_work(x)
#define HPSB_INIT_WORK(x,y,z) INIT_WORK(x,y,z)
#define HPSB_PREPARE_WORK(x,y,z) PREPARE_WORK(x,y,z)
#endif
typedef u32 quadlet_t;
typedef u64 octlet_t;
typedef u16 nodeid_t;
typedef u8 byte_t;
typedef u64 nodeaddr_t;
typedef u16 arm_length_t;
#define BUS_MASK 0xffc0
#define NODE_MASK 0x003f
#define LOCAL_BUS 0xffc0
......
......@@ -91,7 +91,6 @@
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <linux/tqueue.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
......@@ -154,7 +153,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: 578 $ Ben Collins <bcollins@debian.org>";
"$Rev: 601 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
MODULE_PARM(attempt_root,"i");
......@@ -1905,7 +1904,7 @@ static void ohci_init_config_rom(struct ti_ohci *ohci)
ohci->csr_config_rom_length = cr.data - ohci->csr_config_rom_cpu;
}
static size_t ohci_get_rom(struct hpsb_host *host, const quadlet_t **ptr)
static size_t ohci_get_rom(struct hpsb_host *host, quadlet_t **ptr)
{
struct ti_ohci *ohci=host->hostdata;
......
......@@ -1677,7 +1677,7 @@ static int __devinit add_card(struct pci_dev *dev,
static size_t get_lynx_rom(struct hpsb_host *host, const quadlet_t **ptr)
static size_t get_lynx_rom(struct hpsb_host *host, quadlet_t **ptr)
{
struct ti_lynx *lynx = host->hostdata;
*ptr = lynx->config_rom;
......
This diff is collapsed.
......@@ -14,20 +14,32 @@
#define RAW1394_REQ_SET_CARD 3
/* state: connected */
#define RAW1394_REQ_ASYNC_READ 100
#define RAW1394_REQ_ASYNC_WRITE 101
#define RAW1394_REQ_LOCK 102
#define RAW1394_REQ_LOCK64 103
#define RAW1394_REQ_ISO_SEND 104
#define RAW1394_REQ_ASYNC_READ 100
#define RAW1394_REQ_ASYNC_WRITE 101
#define RAW1394_REQ_LOCK 102
#define RAW1394_REQ_LOCK64 103
#define RAW1394_REQ_ISO_SEND 104
#define RAW1394_REQ_ASYNC_SEND 105
#define RAW1394_REQ_ISO_LISTEN 200
#define RAW1394_REQ_FCP_LISTEN 201
#define RAW1394_REQ_RESET_BUS 202
#define RAW1394_REQ_ISO_LISTEN 200
#define RAW1394_REQ_FCP_LISTEN 201
#define RAW1394_REQ_RESET_BUS 202
#define RAW1394_REQ_GET_ROM 203
#define RAW1394_REQ_UPDATE_ROM 204
#define RAW1394_REQ_ECHO 205
#define RAW1394_REQ_ARM_REGISTER 300
#define RAW1394_REQ_ARM_UNREGISTER 301
#define RAW1394_REQ_RESET_NOTIFY 400
#define RAW1394_REQ_PHYPACKET 500
/* kernel to user */
#define RAW1394_REQ_BUS_RESET 10000
#define RAW1394_REQ_ISO_RECEIVE 10001
#define RAW1394_REQ_FCP_REQUEST 10002
#define RAW1394_REQ_ARM 10003
/* error codes */
#define RAW1394_ERROR_NONE 0
......@@ -45,6 +57,17 @@
#define RAW1394_ERROR_ABORTED (-1101)
#define RAW1394_ERROR_TIMEOUT (-1102)
/* arm_codes */
#define ARM_READ 1
#define ARM_WRITE 2
#define ARM_LOCK 4
#define RAW1394_LONG_RESET 0
#define RAW1394_SHORT_RESET 1
/* busresetnotify ... */
#define RAW1394_NOTIFY_OFF 0
#define RAW1394_NOTIFY_ON 1
#include <asm/types.h>
......@@ -69,6 +92,29 @@ struct raw1394_khost_list {
__u8 name[32];
};
typedef struct arm_request {
nodeid_t destination_nodeid;
nodeid_t source_nodeid;
nodeaddr_t destination_offset;
u8 tlabel;
u8 tcode;
u_int8_t extended_transaction_code;
u_int32_t generation;
arm_length_t buffer_length;
byte_t *buffer;
} *arm_request_t;
typedef struct arm_response {
int response_code;
arm_length_t buffer_length;
byte_t *buffer;
} *arm_response_t;
typedef struct arm_request_response {
struct arm_request *request;
struct arm_response *response;
} *arm_request_response_t;
#ifdef __KERNEL__
struct iso_block_store {
......@@ -91,18 +137,34 @@ struct file_info {
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;
struct list_head addr_list;
u8 *fcp_buffer;
u64 listen_channels;
quadlet_t *iso_buffer;
size_t iso_buffer_length;
u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
};
struct arm_addr {
struct list_head addr_list; /* file_info list */
u64 start, end;
u64 arm_tag;
u8 access_rights;
u8 notification_options;
u8 client_transactions;
u64 recvb;
u16 rec_length;
u8 *addr_space_buffer; /* accessed by read/write/lock */
};
struct pending_request {
struct list_head list;
struct file_info *file_info;
struct hpsb_packet *packet;
struct tq_struct tq;
struct hpsb_queue_struct tq;
struct iso_block_store *ibs;
quadlet_t *data;
int free_data;
......
......@@ -351,7 +351,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 584 $ James Goodwin <jamesg@filanet.com>";
"$Rev: 601 $ James Goodwin <jamesg@filanet.com>";
/*
* Module load parameter definitions
......@@ -421,8 +421,9 @@ static int sbp2_max_cmds_per_lun = SBP2SCSI_MAX_CMDS_PER_LUN;
* talking to a single sbp2 device at the same time (filesystem coherency,
* etc.). If you're running an sbp2 device that supports multiple logins,
* and you're either running read-only filesystems or some sort of special
* filesystem supporting multiple hosts, then set sbp2_exclusive_login to
* zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four
* filesystem supporting multiple hosts (one such filesystem is OpenGFS,
* see opengfs.sourceforge.net for more info), then set sbp2_exclusive_login
* to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four
* concurrent logins.
*/
MODULE_PARM(sbp2_exclusive_login,"i");
......@@ -800,8 +801,9 @@ sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
* Set up a task queue completion routine, which returns
* the packet to the free list and releases the tlabel.
*/
request_packet->tq.routine = (void (*)(void*))sbp2util_free_request_packet;
request_packet->tq.data = request_packet;
HPSB_PREPARE_WORK(&request_packet->tq,
(void (*)(void*))sbp2util_free_request_packet,
request_packet);
request_packet->hi_context = hi;
hpsb_add_packet_complete_task(packet, &request_packet->tq);
......@@ -1007,13 +1009,8 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
command->dma_size, command->dma_dir);
SBP2_DMA_FREE("single bulk");
} else if (command->dma_type == CMD_DMA_PAGE) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13)
pci_unmap_single(hi->host->pdev, command->cmd_dma,
command->dma_size, command->dma_dir);
#else
pci_unmap_page(hi->host->pdev, command->cmd_dma,
command->dma_size, command->dma_dir);
#endif /* Linux version < 2.4.13 */
SBP2_DMA_FREE("single page");
} /* XXX: Check for CMD_DMA_NONE bug */
command->dma_type = CMD_DMA_NONE;
......@@ -2146,17 +2143,11 @@ static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
command->dma_dir = dma_dir;
command->dma_size = sgpnt[0].length;
command->dma_type = CMD_DMA_PAGE;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13)
command->cmd_dma = pci_map_single (hi->host->pdev, sgpnt[0].address,
command->dma_size,
command->dma_dir);
#else
command->cmd_dma = pci_map_page(hi->host->pdev,
sgpnt[0].page,
sgpnt[0].offset,
command->dma_size,
command->dma_dir);
#endif /* Linux version < 2.4.13 */
SBP2_DMA_ALLOC("single page scatter element");
command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
......@@ -2702,7 +2693,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
* This function deals with status writes from the SBP-2 device
*/
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length)
quadlet_t *data, u64 addr, unsigned int length, u16 fl)
{
struct sbp2scsi_host_info *hi = NULL;
struct scsi_id_instance_data *scsi_id = NULL;
......@@ -3161,7 +3152,6 @@ static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int ge
heads = 64;
sectors = 32;
cylinders = (int)disk->capacity / (heads * sectors);
if (cylinders > 1024) {
heads = 255;
......
......@@ -324,7 +324,7 @@ struct sbp2_request_packet {
struct list_head list;
struct hpsb_packet *packet;
struct tq_struct tq;
struct hpsb_queue_struct tq;
void *hi_context;
};
......@@ -510,9 +510,9 @@ static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
u64 addr, unsigned int length);
u64 addr, unsigned int length, u16 flags);
static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
u64 addr, unsigned int length);
u64 addr, unsigned int length, u16 flags);
#endif
/*
......@@ -522,7 +522,7 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_logout_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length);
quadlet_t *data, u64 addr, unsigned int length, u16 flags);
static int sbp2_agent_reset(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, u32 flags);
static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
struct scsi_id_instance_data *scsi_id,
......
......@@ -35,7 +35,6 @@
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/tqueue.h>
#include <linux/delay.h>
#include <linux/devfs_fs_kernel.h>
......@@ -1455,12 +1454,7 @@ static int __init video1394_init_module (void)
return -EIO;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME,
strlen(VIDEO1394_DRIVER_NAME), NULL);
#else
devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME, NULL);
#endif
hl_handle = hpsb_register_highlevel (VIDEO1394_DRIVER_NAME, &hl_ops);
if (hl_handle == NULL) {
......
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