Commit 0a97b16a authored by Linus Torvalds's avatar Linus Torvalds

v2.4.10.2 -> v2.4.10.3

  - Al Viro: superblock cleanups, partition handling fixes and cleanups
  - Ben Collins: firewire update
  - Jeff Garzik: network driver updates
  - Urban Widmark: smbfs updates
  - Kai Mäkisara: SCSI tape driver update
  - various: embarrassing lack of error checking in ELF loader
  - Neil Brown: md formatting cleanup.
parent 5bf3be03
VERSION = 2 VERSION = 2
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 11 SUBLEVEL = 11
EXTRAVERSION =-pre2 EXTRAVERSION =-pre3
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
/* /*
* BK Id: SCCS/s.fault.c 1.13 06/28/01 15:50:17 paulus * BK Id: SCCS/s.fault.c 1.15 09/24/01 16:35:10 paulus
*/ */
/* /*
* arch/ppc/mm/fault.c * arch/ppc/mm/fault.c
...@@ -150,6 +150,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -150,6 +150,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* make sure we exit gracefully rather than endlessly redo * make sure we exit gracefully rather than endlessly redo
* the fault. * the fault.
*/ */
survive:
switch (handle_mm_fault(mm, vma, address, is_write)) { switch (handle_mm_fault(mm, vma, address, is_write)) {
case 1: case 1:
current->min_flt++; current->min_flt++;
...@@ -195,6 +196,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -195,6 +196,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
*/ */
out_of_memory: out_of_memory:
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (current->pid == 1) {
current->policy |= SCHED_YIELD;
schedule();
down_read(&mm->mmap_sem);
goto survive;
}
printk("VM: killing process %s\n", current->comm); printk("VM: killing process %s\n", current->comm);
if (user_mode(regs)) if (user_mode(regs))
do_exit(SIGKILL); do_exit(SIGKILL);
...@@ -346,34 +353,3 @@ get_8xx_pte(struct mm_struct *mm, unsigned long addr) ...@@ -346,34 +353,3 @@ get_8xx_pte(struct mm_struct *mm, unsigned long addr)
return(retval); return(retval);
} }
#endif /* CONFIG_8xx */ #endif /* CONFIG_8xx */
#if 0
/*
* Misc debugging functions. Please leave them here. -- Cort
*/
void print_pte(struct _PTE p)
{
printk(
"%08x %08x vsid: %06x h: %01x api: %02x rpn: %05x rcwimg: %d%d%d%d%d%d pp: %02x\n",
*((unsigned long *)(&p)), *((long *)&p+1),
p.vsid, p.h, p.api, p.rpn,
p.r,p.c,p.w,p.i,p.m,p.g,p.pp);
}
/*
* Search the hw hash table for a mapping to the given physical
* address. -- Cort
*/
unsigned long htab_phys_to_va(unsigned long address)
{
extern PTE *Hash, *Hash_end;
PTE *ptr;
for ( ptr = Hash ; ptr < Hash_end ; ptr++ )
{
if ( ptr->rpn == (address>>12) )
printk("phys %08lX -> va ???\n",
address);
}
}
#endif
/* /*
* BK Id: SCCS/s.init.c 1.34 08/20/01 22:12:43 paulus * BK Id: SCCS/s.init.c 1.36 09/22/01 14:03:09 paulus
*/ */
/* /*
* PowerPC version * PowerPC version
...@@ -44,12 +44,15 @@ ...@@ -44,12 +44,15 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/btext.h> #include <asm/btext.h>
#include <asm/tlb.h>
#include "mem_pieces.h" #include "mem_pieces.h"
#include "mmu_decl.h" #include "mmu_decl.h"
#define MAX_LOW_MEM (0xF0000000UL - KERNELBASE) #define MAX_LOW_MEM (0xF0000000UL - KERNELBASE)
mmu_gather_t mmu_gathers[NR_CPUS];
void *end_of_DRAM; void *end_of_DRAM;
unsigned long total_memory; unsigned long total_memory;
unsigned long total_lowmem; unsigned long total_lowmem;
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
mm_context_t next_mmu_context; mm_context_t next_mmu_context;
unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))]; unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
#ifdef FEW_CONTEXTS #ifdef FEW_CONTEXTS
atomic_t nr_free_contexts; atomic_t nr_free_contexts;
struct mm_struct *context_mm[LAST_CONTEXT+1]; struct mm_struct *context_mm[LAST_CONTEXT+1];
...@@ -57,7 +57,7 @@ void __init mmu_context_init(void) ...@@ -57,7 +57,7 @@ void __init mmu_context_init(void)
context_map[0] = (1 << FIRST_CONTEXT) - 1; context_map[0] = (1 << FIRST_CONTEXT) - 1;
next_mmu_context = FIRST_CONTEXT; next_mmu_context = FIRST_CONTEXT;
#ifdef FEW_CONTEXTS #ifdef FEW_CONTEXTS
atomic_set(&nr_free_contexts, LAST_CONTEXT); atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
#endif /* FEW_CONTEXTS */ #endif /* FEW_CONTEXTS */
} }
......
...@@ -211,12 +211,12 @@ void __init mapin_ram(void) ...@@ -211,12 +211,12 @@ void __init mapin_ram(void)
#else #else
if ((char *) v < _stext || (char *) v >= etext) if ((char *) v < _stext || (char *) v >= etext)
f |= _PAGE_RW | _PAGE_DIRTY; f |= _PAGE_RW | _PAGE_DIRTY;
#ifndef CONFIG_8xx #ifdef CONFIG_PPC_STD_MMU
else else
/* On the powerpc (not 8xx), no user access /* On the powerpc (not all), no user access
forces R/W kernel access */ forces R/W kernel access */
f |= _PAGE_USER; f |= _PAGE_USER;
#endif /* CONFIG_8xx */ #endif /* CONFIG_PPC_STD_MMU */
#endif /* CONFIG_KGDB */ #endif /* CONFIG_KGDB */
map_page(v, p, f); map_page(v, p, f);
v += PAGE_SIZE; v += PAGE_SIZE;
......
...@@ -231,12 +231,12 @@ static struct sysrq_key_op sysrq_sync_op = { ...@@ -231,12 +231,12 @@ static struct sysrq_key_op sysrq_sync_op = {
static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs, static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
struct kbd_struct *kbd, struct tty_struct *tty) { struct kbd_struct *kbd, struct tty_struct *tty) {
emergency_sync_scheduled = EMERG_REMOUNT; emergency_sync_scheduled = EMERG_REMOUNT;
wakeup_bdflush(0); wakeup_bdflush();
} }
static struct sysrq_key_op sysrq_mountro_op = { static struct sysrq_key_op sysrq_mountro_op = {
handler: sysrq_handle_mountro, handler: sysrq_handle_mountro,
help_msg: "Unmount", help_msg: "Unmount",
action_msg: "Emergency Remount R/0", action_msg: "Emergency Remount R/O",
}; };
/* END SYNC SYSRQ HANDLERS BLOCK */ /* END SYNC SYSRQ HANDLERS BLOCK */
......
This diff is collapsed.
...@@ -157,16 +157,13 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, ...@@ -157,16 +157,13 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
#define DEFINE_MULTIPLEXER(Function) \ #define DEFINE_MULTIPLEXER(Function) \
void highlevel_##Function(struct hpsb_host *host) \ void highlevel_##Function(struct hpsb_host *host) \
{ \ { \
struct list_head *entry,*next; \ struct list_head *lh; \
void (*funcptr)(struct hpsb_host*); \ void (*funcptr)(struct hpsb_host*); \
read_lock(&hl_drivers_lock); \ read_lock(&hl_drivers_lock); \
entry = hl_drivers.next; \ list_for_each(lh, &hl_drivers) { \
while (entry != &hl_drivers) { \ funcptr = list_entry(lh, struct hpsb_highlevel, hl_list) \
next = entry->next; \
funcptr = list_entry(entry, struct hpsb_highlevel, hl_list) \
->op->Function; \ ->op->Function; \
if (funcptr) funcptr(host); \ if (funcptr) funcptr(host); \
entry = next; \
} \ } \
read_unlock(&hl_drivers_lock); \ read_unlock(&hl_drivers_lock); \
} }
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include "highlevel.h" #include "highlevel.h"
static struct hpsb_host_template *templates = NULL; static LIST_HEAD(templates);
spinlock_t templates_lock = SPIN_LOCK_UNLOCKED; static spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
/* /*
* This function calls the add_host/remove_host hooks for every host currently * This function calls the add_host/remove_host hooks for every host currently
...@@ -32,13 +32,16 @@ spinlock_t templates_lock = SPIN_LOCK_UNLOCKED; ...@@ -32,13 +32,16 @@ spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
*/ */
void hl_all_hosts(struct hpsb_highlevel *hl, int init) void hl_all_hosts(struct hpsb_highlevel *hl, int init)
{ {
struct list_head *tlh, *hlh;
struct hpsb_host_template *tmpl; struct hpsb_host_template *tmpl;
struct hpsb_host *host; struct hpsb_host *host;
spin_lock(&templates_lock); spin_lock(&templates_lock);
for (tmpl = templates; tmpl != NULL; tmpl = tmpl->next) { list_for_each(tlh, &templates) {
for (host = tmpl->hosts; host != NULL; host = host->next) { tmpl = list_entry(tlh, struct hpsb_host_template, list);
list_for_each(hlh, &tmpl->hosts) {
host = list_entry(hlh, struct hpsb_host, list);
if (host->initialized) { if (host->initialized) {
if (init) { if (init) {
if (hl->op->add_host) { if (hl->op->add_host) {
...@@ -58,21 +61,24 @@ void hl_all_hosts(struct hpsb_highlevel *hl, int init) ...@@ -58,21 +61,24 @@ void hl_all_hosts(struct hpsb_highlevel *hl, int init)
int hpsb_inc_host_usage(struct hpsb_host *host) int hpsb_inc_host_usage(struct hpsb_host *host)
{ {
struct list_head *tlh, *hlh;
struct hpsb_host_template *tmpl; struct hpsb_host_template *tmpl;
struct hpsb_host *h;
int retval = 0; int retval = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&templates_lock, flags); spin_lock_irqsave(&templates_lock, flags);
for (tmpl = templates; (tmpl != NULL) && !retval; tmpl = tmpl->next) { list_for_each(tlh, &templates) {
for (h = tmpl->hosts; h != NULL; h = h->next) { tmpl = list_entry(tlh, struct hpsb_host_template, list);
if (h == host) { list_for_each(hlh, &tmpl->hosts) {
tmpl->devctl(h, MODIFY_USAGE, 1); if (host == list_entry(hlh, struct hpsb_host, list)) {
tmpl->devctl(host, MODIFY_USAGE, 1);
retval = 1; retval = 1;
break; break;
} }
} }
if (retval)
break;
} }
spin_unlock_irqrestore(&templates_lock, flags); spin_unlock_irqrestore(&templates_lock, flags);
...@@ -113,32 +119,22 @@ struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl, ...@@ -113,32 +119,22 @@ struct hpsb_host *hpsb_get_host(struct hpsb_host_template *tmpl,
h->speed_map = (u8 *)(h->csr.speed_map + 2); h->speed_map = (u8 *)(h->csr.speed_map + 2);
h->template = tmpl; h->template = tmpl;
if (hd_size) { if (hd_size)
h->hostdata = &h->embedded_hostdata[0]; h->hostdata = &h->embedded_hostdata[0];
}
if (tmpl->hosts == NULL) { list_add_tail(&h->list, &tmpl->hosts);
tmpl->hosts = h;
} else {
struct hpsb_host *last = tmpl->hosts;
while (last->next != NULL) {
last = last->next;
}
last->next = h;
}
return h; return h;
} }
static void free_all_hosts(struct hpsb_host_template *tmpl) static void free_all_hosts(struct hpsb_host_template *tmpl)
{ {
struct hpsb_host *next, *host = tmpl->hosts; struct list_head *hlh, *next;
struct hpsb_host *host;
while (host) { list_for_each_safe(hlh, next, &tmpl->hosts) {
next = host->next; host = list_entry(hlh, struct hpsb_host, list);
vfree(host); vfree(host);
host = next;
} }
} }
...@@ -146,11 +142,13 @@ static void free_all_hosts(struct hpsb_host_template *tmpl) ...@@ -146,11 +142,13 @@ static void free_all_hosts(struct hpsb_host_template *tmpl)
static void init_hosts(struct hpsb_host_template *tmpl) static void init_hosts(struct hpsb_host_template *tmpl)
{ {
int count; int count;
struct list_head *hlh;
struct hpsb_host *host; struct hpsb_host *host;
count = tmpl->detect_hosts(tmpl); count = tmpl->detect_hosts(tmpl);
for (host = tmpl->hosts; host != NULL; host = host->next) { list_for_each(hlh, &tmpl->hosts) {
host = list_entry(hlh, struct hpsb_host, list);
if (tmpl->initialize_host(host)) { if (tmpl->initialize_host(host)) {
host->initialized = 1; host->initialized = 1;
...@@ -166,9 +164,11 @@ static void init_hosts(struct hpsb_host_template *tmpl) ...@@ -166,9 +164,11 @@ static void init_hosts(struct hpsb_host_template *tmpl)
static void shutdown_hosts(struct hpsb_host_template *tmpl) static void shutdown_hosts(struct hpsb_host_template *tmpl)
{ {
struct list_head *hlh;
struct hpsb_host *host; struct hpsb_host *host;
for (host = tmpl->hosts; host != NULL; host = host->next) { list_for_each(hlh, &tmpl->hosts) {
host = list_entry(hlh, struct hpsb_host, list);
if (host->initialized) { if (host->initialized) {
host->initialized = 0; host->initialized = 0;
abort_requests(host); abort_requests(host);
...@@ -188,68 +188,17 @@ static void shutdown_hosts(struct hpsb_host_template *tmpl) ...@@ -188,68 +188,17 @@ static void shutdown_hosts(struct hpsb_host_template *tmpl)
} }
static int add_template(struct hpsb_host_template *new)
{
new->next = NULL;
new->hosts = NULL;
new->number_of_hosts = 0;
spin_lock(&templates_lock);
if (templates == NULL) {
templates = new;
} else {
struct hpsb_host_template *last = templates;
while (last->next != NULL) {
last = last->next;
}
last->next = new;
}
spin_unlock(&templates_lock);
return 0;
}
static int remove_template(struct hpsb_host_template *tmpl)
{
int retval = 0;
if (tmpl->number_of_hosts) {
HPSB_ERR("attempted to remove busy host template "
"of %s at address 0x%p", tmpl->name, tmpl);
return 1;
}
spin_lock(&templates_lock);
if (templates == tmpl) {
templates = tmpl->next;
} else {
struct hpsb_host_template *t;
t = templates;
while (t->next != tmpl && t->next != NULL) {
t = t->next;
}
if (t->next == NULL) {
HPSB_ERR("attempted to remove unregistered host template "
"of %s at address 0x%p", tmpl->name, tmpl);
retval = -1;
} else {
t->next = tmpl->next;
}
}
spin_unlock(&templates_lock);
return retval;
}
/* /*
* The following two functions are exported symbols for module usage. * The following two functions are exported symbols for module usage.
*/ */
int hpsb_register_lowlevel(struct hpsb_host_template *tmpl) int hpsb_register_lowlevel(struct hpsb_host_template *tmpl)
{ {
add_template(tmpl); INIT_LIST_HEAD(&tmpl->hosts);
tmpl->number_of_hosts = 0;
spin_lock(&templates_lock);
list_add_tail(&tmpl->list, &templates);
spin_unlock(&templates_lock);
/* PCI cards should be smart and use the PCI detection layer, and /* PCI cards should be smart and use the PCI detection layer, and
* not this one shot deal. detect_hosts() will be obsoleted soon. */ * not this one shot deal. detect_hosts() will be obsoleted soon. */
...@@ -265,7 +214,12 @@ void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl) ...@@ -265,7 +214,12 @@ void hpsb_unregister_lowlevel(struct hpsb_host_template *tmpl)
{ {
shutdown_hosts(tmpl); shutdown_hosts(tmpl);
if (remove_template(tmpl)) { if (tmpl->number_of_hosts)
HPSB_PANIC("remove_template failed on %s", tmpl->name); HPSB_PANIC("attempted to remove busy host template "
"of %s at address 0x%p", tmpl->name, tmpl);
else {
spin_lock(&templates_lock);
list_del(&tmpl->list);
spin_unlock(&templates_lock);
} }
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/tqueue.h> #include <linux/tqueue.h>
#include <linux/list.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include "ieee1394_types.h" #include "ieee1394_types.h"
...@@ -13,7 +14,7 @@ struct hpsb_packet; ...@@ -13,7 +14,7 @@ struct hpsb_packet;
struct hpsb_host { struct hpsb_host {
/* private fields (hosts, do not use them) */ /* private fields (hosts, do not use them) */
struct hpsb_host *next; struct list_head list;
atomic_t generation; atomic_t generation;
...@@ -109,9 +110,9 @@ enum reset_types { ...@@ -109,9 +110,9 @@ enum reset_types {
}; };
struct hpsb_host_template { struct hpsb_host_template {
struct hpsb_host_template *next; struct list_head list;
struct hpsb_host *hosts; struct list_head hosts;
int number_of_hosts; int number_of_hosts;
/* fields above will be ignored and overwritten after registering */ /* fields above will be ignored and overwritten after registering */
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
...@@ -30,6 +31,13 @@ ...@@ -30,6 +31,13 @@
#include "csr.h" #include "csr.h"
#include "nodemgr.h" #include "nodemgr.h"
/*
* Disable the nodemgr detection and config rom reading functionality.
*/
MODULE_PARM(disable_nodemgr, "i");
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
static int disable_nodemgr = 0;
static kmem_cache_t *hpsb_packet_cache; static kmem_cache_t *hpsb_packet_cache;
...@@ -95,7 +103,7 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size) ...@@ -95,7 +103,7 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
INIT_TQ_HEAD(packet->complete_tq); INIT_TQ_HEAD(packet->complete_tq);
INIT_LIST_HEAD(&packet->list); INIT_LIST_HEAD(&packet->list);
sema_init(&packet->state_change, 0); sema_init(&packet->state_change, 0);
packet->state = unused; packet->state = hpsb_unused;
packet->generation = -1; packet->generation = -1;
packet->data_be = 1; packet->data_be = 1;
...@@ -352,14 +360,14 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, ...@@ -352,14 +360,14 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
} }
if (ackcode != ACK_PENDING || !packet->expect_response) { if (ackcode != ACK_PENDING || !packet->expect_response) {
packet->state = completed; packet->state = hpsb_complete;
up(&packet->state_change); up(&packet->state_change);
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); run_task_queue(&packet->complete_tq);
return; return;
} }
packet->state = pending; packet->state = hpsb_pending;
packet->sendtime = jiffies; packet->sendtime = jiffies;
spin_lock_irqsave(&host->pending_pkt_lock, flags); spin_lock_irqsave(&host->pending_pkt_lock, flags);
...@@ -393,9 +401,9 @@ int hpsb_send_packet(struct hpsb_packet *packet) ...@@ -393,9 +401,9 @@ int hpsb_send_packet(struct hpsb_packet *packet)
return 0; return 0;
} }
packet->state = queued; packet->state = hpsb_queued;
if (packet->type == async && packet->node_id != ALL_NODES) { if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
packet->speed_code = packet->speed_code =
host->speed_map[(host->node_id & NODE_MASK) * 64 host->speed_map[(host->node_id & NODE_MASK) * 64
+ (packet->node_id & NODE_MASK)]; + (packet->node_id & NODE_MASK)];
...@@ -503,14 +511,14 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, ...@@ -503,14 +511,14 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
break; break;
} }
packet->state = completed; packet->state = hpsb_complete;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); run_task_queue(&packet->complete_tq);
} }
struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data, static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
size_t dsize) quadlet_t *data, size_t dsize)
{ {
struct hpsb_packet *p; struct hpsb_packet *p;
...@@ -522,13 +530,15 @@ struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data, ...@@ -522,13 +530,15 @@ struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data,
return NULL; return NULL;
} }
p->type = async; p->type = hpsb_async;
p->state = unused; p->state = hpsb_unused;
p->host = host; p->host = host;
p->node_id = data[1] >> 16; p->node_id = data[1] >> 16;
p->tlabel = (data[0] >> 10) & 0x3f; p->tlabel = (data[0] >> 10) & 0x3f;
p->no_waiter = 1; p->no_waiter = 1;
p->generation = get_hpsb_generation(host);
if (dsize % 4) { if (dsize % 4) {
p->data[dsize / 4] = 0; p->data[dsize / 4] = 0;
} }
...@@ -540,8 +550,8 @@ struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data, ...@@ -540,8 +550,8 @@ struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data,
packet = create_reply_packet(host, data, length); \ packet = create_reply_packet(host, data, length); \
if (packet == NULL) break if (packet == NULL) break
void handle_incoming_packet(struct hpsb_host *host, int tcode, quadlet_t *data, static void handle_incoming_packet(struct hpsb_host *host, int tcode,
size_t size, int write_acked) quadlet_t *data, size_t size, int write_acked)
{ {
struct hpsb_packet *packet; struct hpsb_packet *packet;
int length, rcode, extcode; int length, rcode, extcode;
...@@ -720,7 +730,7 @@ void abort_requests(struct hpsb_host *host) ...@@ -720,7 +730,7 @@ void abort_requests(struct hpsb_host *host)
list_for_each(lh, &llist) { list_for_each(lh, &llist) {
packet = list_entry(lh, struct hpsb_packet, list); packet = list_entry(lh, struct hpsb_packet, list);
packet->state = completed; packet->state = hpsb_complete;
packet->ack_code = ACKX_ABORTED; packet->ack_code = ACKX_ABORTED;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); run_task_queue(&packet->complete_tq);
...@@ -732,7 +742,7 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -732,7 +742,7 @@ void abort_timedouts(struct hpsb_host *host)
unsigned long flags; unsigned long flags;
struct hpsb_packet *packet; struct hpsb_packet *packet;
unsigned long expire; unsigned long expire;
struct list_head *lh; struct list_head *lh, *next;
LIST_HEAD(expiredlist); LIST_HEAD(expiredlist);
spin_lock_irqsave(&host->csr.lock, flags); spin_lock_irqsave(&host->csr.lock, flags);
...@@ -746,8 +756,9 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -746,8 +756,9 @@ void abort_timedouts(struct hpsb_host *host)
spin_lock_irqsave(&host->pending_pkt_lock, flags); spin_lock_irqsave(&host->pending_pkt_lock, flags);
list_for_each(lh, &host->pending_packets) { for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) {
packet = list_entry(lh, struct hpsb_packet, list); packet = list_entry(lh, struct hpsb_packet, list);
next = lh->next;
if (time_before(packet->sendtime + expire, jiffies)) { if (time_before(packet->sendtime + expire, jiffies)) {
list_del(&packet->list); list_del(&packet->list);
list_add(&packet->list, &expiredlist); list_add(&packet->list, &expiredlist);
...@@ -761,7 +772,7 @@ void abort_timedouts(struct hpsb_host *host) ...@@ -761,7 +772,7 @@ void abort_timedouts(struct hpsb_host *host)
list_for_each(lh, &expiredlist) { list_for_each(lh, &expiredlist) {
packet = list_entry(lh, struct hpsb_packet, list); packet = list_entry(lh, struct hpsb_packet, list);
packet->state = completed; packet->state = hpsb_complete;
packet->ack_code = ACKX_TIMEOUT; packet->ack_code = ACKX_TIMEOUT;
up(&packet->state_change); up(&packet->state_change);
run_task_queue(&packet->complete_tq); run_task_queue(&packet->complete_tq);
...@@ -775,13 +786,19 @@ static int __init ieee1394_init(void) ...@@ -775,13 +786,19 @@ static int __init ieee1394_init(void)
0, 0, NULL, NULL); 0, 0, NULL, NULL);
init_hpsb_highlevel(); init_hpsb_highlevel();
init_csr(); init_csr();
if (!disable_nodemgr)
init_ieee1394_nodemgr(); init_ieee1394_nodemgr();
else
HPSB_INFO("nodemgr functionality disabled");
return 0; return 0;
} }
static void __exit ieee1394_cleanup(void) static void __exit ieee1394_cleanup(void)
{ {
if (!disable_nodemgr)
cleanup_ieee1394_nodemgr(); cleanup_ieee1394_nodemgr();
cleanup_csr(); cleanup_csr();
kmem_cache_destroy(hpsb_packet_cache); kmem_cache_destroy(hpsb_packet_cache);
} }
......
...@@ -20,16 +20,16 @@ struct hpsb_packet { ...@@ -20,16 +20,16 @@ struct hpsb_packet {
/* Async and Iso types should be clear, raw means send-as-is, do not /* Async and Iso types should be clear, raw means send-as-is, do not
* CRC! Byte swapping shall still be done in this case. */ * CRC! Byte swapping shall still be done in this case. */
enum { async, iso, raw } __attribute__((packed)) type; enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
/* Okay, this is core internal and a no care for hosts. /* Okay, this is core internal and a no care for hosts.
* queued = queued for sending * queued = queued for sending
* pending = sent, waiting for response * pending = sent, waiting for response
* completed = processing completed, successful or not * complete = processing completed, successful or not
* incoming = incoming packet * incoming = incoming packet
*/ */
enum { enum {
unused, queued, pending, completed, incoming hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete, hpsb_incoming
} __attribute__((packed)) state; } __attribute__((packed)) state;
/* These are core internal. */ /* These are core internal. */
......
...@@ -2,32 +2,75 @@ ...@@ -2,32 +2,75 @@
#define _IEEE1394_HOTPLUG_H #define _IEEE1394_HOTPLUG_H
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "nodemgr.h"
#define IEEE1394_DEVICE_ID_MATCH_VENDOR_ID 0x0001 #define IEEE1394_MATCH_VENDOR_ID 0x0001
#define IEEE1394_DEVICE_ID_MATCH_MODEL_ID 0x0002 #define IEEE1394_MATCH_MODEL_ID 0x0002
#define IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_ID 0x0004 #define IEEE1394_MATCH_SPECIFIER_ID 0x0004
#define IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_VERSION 0x0008 #define IEEE1394_MATCH_VERSION 0x0008
struct ieee1394_device_id { struct ieee1394_device_id {
u32 match_flags; u32 match_flags;
u32 vendor_id; u32 vendor_id;
u32 model_id; u32 model_id;
u32 sw_specifier_id; u32 specifier_id;
u32 sw_specifier_version; u32 version;
void *driver_data;
}; };
#define IEEE1394_PROTOCOL(id, version) { \ struct hpsb_protocol_driver {
match_flags: IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_ID | \ /* The name of the driver, e.g. SBP2 or IP1394 */
IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_VERSION, \ const char *name;
sw_specifier_id: id, \
sw_specifier_version: version \ /*
} * The device id table describing the protocols and/or devices
* supported by this driver. This is used by the nodemgr to
#define IEEE1394_DEVICE(vendor_id, model_id) { \ * decide if a driver could support a given node, but the
match_flags: IEEE1394_DEVICE_ID_MATCH_VENDOR_ID | \ * probe function below can implement further protocol
IEEE1394_DEVICE_ID_MATCH_MODEL_ID, \ * dependent or vendor dependent checking.
vendor_id: vendor_id, \ */
model_id: vendor_id, \ struct ieee1394_device_id *id_table;
}
/*
* The probe function is called when a device is added to the
* bus and the nodemgr finds a matching entry in the drivers
* device id table or when registering this driver and a
* previously unhandled device can be handled. The driver may
* decline to handle the device based on further investigation
* of the device (or whatever reason) in which case a negative
* error code should be returned, otherwise 0 should be
* returned. The driver may use the driver_data field in the
* unit directory to store per device driver specific data.
*/
int (*probe)(struct unit_directory *ud);
/*
* The disconnect function is called when a device is removed
* from the bus or if it wasn't possible to read the guid
* after the last bus reset.
*/
void (*disconnect)(struct unit_directory *ud);
/*
* The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus.
* However, it may be necessary to reestablish the connection
* or login into the node again, depending on the protocol.
*/
void (*update)(struct unit_directory *ud);
/* Driver in list of all registered drivers */
struct list_head list;
/* The list of unit directories managed by this driver */
struct list_head unit_directories;
};
int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
int hpsb_claim_unit_directory(struct unit_directory *ud,
struct hpsb_protocol_driver *driver);
void hpsb_release_unit_directory(struct unit_directory *ud);
#endif /* _IEEE1394_HOTPLUG_H */ #endif /* _IEEE1394_HOTPLUG_H */
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "hosts.h" #include "hosts.h"
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#include "ieee1394_hotplug.h"
#include "highlevel.h" #include "highlevel.h"
#include "nodemgr.h" #include "nodemgr.h"
...@@ -75,8 +76,12 @@ EXPORT_SYMBOL(highlevel_add_host); ...@@ -75,8 +76,12 @@ EXPORT_SYMBOL(highlevel_add_host);
EXPORT_SYMBOL(highlevel_remove_host); EXPORT_SYMBOL(highlevel_remove_host);
EXPORT_SYMBOL(highlevel_host_reset); EXPORT_SYMBOL(highlevel_host_reset);
EXPORT_SYMBOL(highlevel_add_one_host); EXPORT_SYMBOL(highlevel_add_one_host);
EXPORT_SYMBOL(hpsb_guid_get_entry); EXPORT_SYMBOL(hpsb_guid_get_entry);
EXPORT_SYMBOL(hpsb_nodeid_get_entry); EXPORT_SYMBOL(hpsb_nodeid_get_entry);
EXPORT_SYMBOL(hpsb_get_host_by_ne); EXPORT_SYMBOL(hpsb_get_host_by_ne);
EXPORT_SYMBOL(hpsb_guid_fill_packet); EXPORT_SYMBOL(hpsb_guid_fill_packet);
EXPORT_SYMBOL(hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol);
EXPORT_SYMBOL(hpsb_release_unit_directory);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -131,7 +131,7 @@ void fill_iso_packet(struct hpsb_packet *packet, int length, int channel, ...@@ -131,7 +131,7 @@ void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
packet->header_size = 4; packet->header_size = 4;
packet->data_size = length; packet->data_size = length;
packet->type = iso; packet->type = hpsb_iso;
packet->tcode = TCODE_ISO_DATA; packet->tcode = TCODE_ISO_DATA;
} }
...@@ -142,7 +142,7 @@ void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) ...@@ -142,7 +142,7 @@ void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
packet->header_size = 8; packet->header_size = 8;
packet->data_size = 0; packet->data_size = 0;
packet->expect_response = 0; packet->expect_response = 0;
packet->type = raw; /* No CRC added */ packet->type = hpsb_raw; /* No CRC added */
packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */ packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */
} }
...@@ -488,7 +488,9 @@ struct hpsb_packet *hpsb_make_packet (struct hpsb_host *host, nodeid_t node, ...@@ -488,7 +488,9 @@ struct hpsb_packet *hpsb_make_packet (struct hpsb_host *host, nodeid_t node,
if (!packet) if (!packet)
return NULL; return NULL;
if (length != 4) /* Sometimes this may be called without data, just to allocate the
* packet. */
if (length != 4 && buffer)
memcpy(packet->data, buffer, length); memcpy(packet->data, buffer, length);
return packet; return packet;
......
...@@ -26,6 +26,13 @@ ...@@ -26,6 +26,13 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#endif #endif
#ifndef list_for_each_safe
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif #endif
......
This diff is collapsed.
...@@ -43,8 +43,18 @@ struct bus_options { ...@@ -43,8 +43,18 @@ struct bus_options {
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04 #define UNIT_DIRECTORY_SPECIFIER_ID 0x04
#define UNIT_DIRECTORY_VERSION 0x08 #define UNIT_DIRECTORY_VERSION 0x08
/*
* A unit directory corresponds to a protocol supported by the
* node. If a node supports eg. IP/1394 and AV/C, its config rom has a
* unit directory for each of these protocols.
*
* Unit directories appear on two types of lists: for each node we
* maintain a list of the unit directories found in its config rom and
* for each driver we maintain a list of the unit directories
* (ie. devices) the driver manages.
*/
struct unit_directory { struct unit_directory {
struct list_head list; struct node_entry *ne; /* The node which this directory belongs to */
octlet_t address; /* Address of the unit directory on the node */ octlet_t address; /* Address of the unit directory on the node */
u8 flags; /* Indicates which entries were read */ u8 flags; /* Indicates which entries were read */
quadlet_t vendor_id; quadlet_t vendor_id;
...@@ -53,6 +63,20 @@ struct unit_directory { ...@@ -53,6 +63,20 @@ struct unit_directory {
char *model_name; char *model_name;
quadlet_t specifier_id; quadlet_t specifier_id;
quadlet_t version; quadlet_t version;
/* Groupings for arbitrary key/value pairs */
int arb_count; /* Number of arbitrary key/values */
char arb_keys[16]; /* Up to 16 keys */
quadlet_t arb_values[16]; /* Same for values */
struct hpsb_protocol_driver *driver;
void *driver_data;
/* For linking the nodes managed by the driver, or unmanaged nodes */
struct list_head driver_list;
/* For linking directories belonging to a node */
struct list_head node_list;
}; };
struct node_entry { struct node_entry {
...@@ -69,6 +93,11 @@ struct node_entry { ...@@ -69,6 +93,11 @@ struct node_entry {
struct list_head unit_directories; struct list_head unit_directories;
}; };
static inline int hpsb_node_entry_valid(struct node_entry *ne)
{
return atomic_read(&ne->generation) == get_hpsb_generation(ne->host);
}
/* /*
* Returns a node entry (which has its reference count incremented) or NULL if * Returns a node entry (which has its reference count incremented) or NULL if
* the GUID in question is not known. Getting a valid entry does not mean that * the GUID in question is not known. Getting a valid entry does not mean that
......
This diff is collapsed.
...@@ -191,15 +191,14 @@ struct ti_ohci { ...@@ -191,15 +191,14 @@ struct ti_ohci {
spinlock_t event_lock; spinlock_t event_lock;
int self_id_errors; int self_id_errors;
int NumBusResets;
/* video device */ /* video device */
struct video_template *video_tmpl; struct video_template *video_tmpl;
/* Swap the selfid buffer? */ /* Swap the selfid buffer? */
unsigned int selfid_swap:1; unsigned int selfid_swap:1;
/* Swap the payload? */ /* Some Apple chipset seem to swap incoming headers for us */
unsigned int payload_swap:1; unsigned int no_swap_incoming:1;
}; };
static inline int cross_bound(unsigned long addr, unsigned int size) static inline int cross_bound(unsigned long addr, unsigned int size)
...@@ -332,14 +331,16 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset) ...@@ -332,14 +331,16 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
#define OHCI1394_phyRegRcvd 0x04000000 #define OHCI1394_phyRegRcvd 0x04000000
#define OHCI1394_masterIntEnable 0x80000000 #define OHCI1394_masterIntEnable 0x80000000
#define OUTPUT_MORE 0x00000000 /* DMA Control flags */
#define OUTPUT_MORE_IMMEDIATE 0x02000000 #define DMA_CTL_OUTPUT_MORE 0x00000000
#define OUTPUT_LAST 0x103c0000 #define DMA_CTL_OUTPUT_LAST 0x10000000
#define OUTPUT_LAST_IMMEDIATE 0x123c0000 #define DMA_CTL_INPUT_MORE 0x20000000
#define DMA_CTL_INPUT_LAST 0x30000000
#define DMA_SPEED_100 0x0 #define DMA_CTL_UPDATE 0x08000000
#define DMA_SPEED_200 0x1 #define DMA_CTL_IMMEDIATE 0x02000000
#define DMA_SPEED_400 0x2 #define DMA_CTL_IRQ 0x00300000
#define DMA_CTL_BRANCH 0x000c0000
#define DMA_CTL_WAIT 0x00030000
#define OHCI1394_TCODE_PHY 0xE #define OHCI1394_TCODE_PHY 0xE
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "hosts.h" #include "hosts.h"
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "highlevel.h"
#include "pcilynx.h" #include "pcilynx.h"
...@@ -393,7 +394,7 @@ static void send_next(struct ti_lynx *lynx, int what) ...@@ -393,7 +394,7 @@ static void send_next(struct ti_lynx *lynx, int what)
struct lynx_send_data *d; struct lynx_send_data *d;
struct hpsb_packet *packet; struct hpsb_packet *packet;
d = (what == iso ? &lynx->iso_send : &lynx->async); d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async);
packet = d->queue; packet = d->queue;
d->header_dma = pci_map_single(lynx->dev, packet->header, d->header_dma = pci_map_single(lynx->dev, packet->header,
...@@ -419,13 +420,13 @@ static void send_next(struct ti_lynx *lynx, int what) ...@@ -419,13 +420,13 @@ static void send_next(struct ti_lynx *lynx, int what)
pcl.buffer[1].pointer = d->data_dma; pcl.buffer[1].pointer = d->data_dma;
switch (packet->type) { switch (packet->type) {
case async: case hpsb_async:
pcl.buffer[0].control |= PCL_CMD_XMT; pcl.buffer[0].control |= PCL_CMD_XMT;
break; break;
case iso: case hpsb_iso:
pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE;
break; break;
case raw: case hpsb_raw:
pcl.buffer[0].control |= PCL_CMD_UNFXMT; pcl.buffer[0].control |= PCL_CMD_UNFXMT;
break; break;
} }
...@@ -606,11 +607,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet) ...@@ -606,11 +607,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
} }
switch (packet->type) { switch (packet->type) {
case async: case hpsb_async:
case raw: case hpsb_raw:
d = &lynx->async; d = &lynx->async;
break; break;
case iso: case hpsb_iso:
d = &lynx->iso_send; d = &lynx->iso_send;
break; break;
default: default:
...@@ -1227,7 +1228,7 @@ static void lynx_irq_handler(int irq, void *dev_id, ...@@ -1227,7 +1228,7 @@ static void lynx_irq_handler(int irq, void *dev_id,
} }
if (lynx->async.queue != NULL) { if (lynx->async.queue != NULL) {
send_next(lynx, async); send_next(lynx, hpsb_async);
} }
spin_unlock(&lynx->async.queue_lock); spin_unlock(&lynx->async.queue_lock);
...@@ -1259,7 +1260,7 @@ static void lynx_irq_handler(int irq, void *dev_id, ...@@ -1259,7 +1260,7 @@ static void lynx_irq_handler(int irq, void *dev_id,
} }
if (lynx->iso_send.queue != NULL) { if (lynx->iso_send.queue != NULL) {
send_next(lynx, iso); send_next(lynx, hpsb_iso);
} }
spin_unlock(&lynx->iso_send.queue_lock); spin_unlock(&lynx->iso_send.queue_lock);
...@@ -1368,7 +1369,7 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1368,7 +1369,7 @@ static int __devinit add_card(struct pci_dev *dev,
FAIL("failed to allocate host structure"); FAIL("failed to allocate host structure");
lynx->state = have_host_struct; lynx->state = have_host_struct;
lynx->host->hostdata = lynx;
lynx->id = num_of_cards-1; lynx->id = num_of_cards-1;
lynx->dev = dev; lynx->dev = dev;
lynx->host->pdev = dev; lynx->host->pdev = dev;
...@@ -1501,6 +1502,9 @@ static int __devinit add_card(struct pci_dev *dev, ...@@ -1501,6 +1502,9 @@ static int __devinit add_card(struct pci_dev *dev,
PRINT(KERN_INFO, lynx->id, "found old 1394 PHY"); PRINT(KERN_INFO, lynx->id, "found old 1394 PHY");
} }
/* Tell the highlevel this host is ready */
highlevel_add_one_host (lynx->host);
return 0; return 0;
#undef FAIL #undef FAIL
} }
...@@ -1633,8 +1637,8 @@ MODULE_DEVICE_TABLE(pci, pci_table); ...@@ -1633,8 +1637,8 @@ MODULE_DEVICE_TABLE(pci, pci_table);
static void __exit pcilynx_cleanup(void) static void __exit pcilynx_cleanup(void)
{ {
pci_unregister_driver(&lynx_pcidriver);
hpsb_unregister_lowlevel(&lynx_template); hpsb_unregister_lowlevel(&lynx_template);
pci_unregister_driver(&lynx_pcidriver);
PRINT_G(KERN_INFO, "removed " PCILYNX_DRIVER_NAME " module"); PRINT_G(KERN_INFO, "removed " PCILYNX_DRIVER_NAME " module");
} }
......
...@@ -290,8 +290,11 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, ...@@ -290,8 +290,11 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
} }
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
list_for_each(lh, &reqs) { lh = reqs.next;
while (lh != &reqs) {
req = list_entry(lh, struct pending_request, list); req = list_entry(lh, struct pending_request, list);
lh = lh->next;
queue_complete_req(req); queue_complete_req(req);
} }
} }
...@@ -356,8 +359,11 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction, ...@@ -356,8 +359,11 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
} }
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
list_for_each(lh, &reqs) { lh = reqs.next;
while (lh != &reqs) {
req = list_entry(lh, struct pending_request, list); req = list_entry(lh, struct pending_request, list);
lh = lh->next;
queue_complete_req(req); queue_complete_req(req);
} }
} }
...@@ -746,6 +752,8 @@ static int handle_remote_request(struct file_info *fi, ...@@ -746,6 +752,8 @@ static int handle_remote_request(struct file_info *fi,
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
spin_unlock_irq(&fi->reqlists_lock); spin_unlock_irq(&fi->reqlists_lock);
packet->generation = req->req.generation;
if (!hpsb_send_packet(packet)) { if (!hpsb_send_packet(packet)) {
req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.error = RAW1394_ERROR_SEND_ERROR;
req->req.length = 0; req->req.length = 0;
...@@ -766,7 +774,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -766,7 +774,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
fill_iso_packet(packet, req->req.length, channel & 0x3f, fill_iso_packet(packet, req->req.length, channel & 0x3f,
(req->req.misc >> 16) & 0x3, req->req.misc & 0xf); (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
packet->type = iso; packet->type = hpsb_iso;
packet->speed_code = req->req.address & 0x3; packet->speed_code = req->req.address & 0x3;
packet->host = fi->host; packet->host = fi->host;
...@@ -787,6 +795,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -787,6 +795,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
list_add_tail(&req->list, &fi->req_pending); list_add_tail(&req->list, &fi->req_pending);
spin_unlock_irq(&fi->reqlists_lock); spin_unlock_irq(&fi->reqlists_lock);
/* Update the generation of the packet just before sending. */
packet->generation = get_hpsb_generation(fi->host);
if (!hpsb_send_packet(packet)) { if (!hpsb_send_packet(packet)) {
req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.error = RAW1394_ERROR_SEND_ERROR;
queue_complete_req(req); queue_complete_req(req);
......
This diff is collapsed.
...@@ -36,13 +36,6 @@ ...@@ -36,13 +36,6 @@
#define ORB_DIRECTION_READ_FROM_MEDIA 0x1 #define ORB_DIRECTION_READ_FROM_MEDIA 0x1
#define ORB_DIRECTION_NO_DATA_TRANSFER 0x2 #define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
#define SPEED_S100 0x0
#define SPEED_S200 0x1
#define SPEED_S400 0x2
#define SPEED_S800 0x3
#define SPEED_S1600 0x4
#define SPEED_S3200 0x5
/* 2^(MAX_PAYLOAD+1) = Maximum data transfer length */ /* 2^(MAX_PAYLOAD+1) = Maximum data transfer length */
#define MAX_PAYLOAD_S100 0x7 #define MAX_PAYLOAD_S100 0x7
#define MAX_PAYLOAD_S200 0x8 #define MAX_PAYLOAD_S200 0x8
...@@ -232,8 +225,8 @@ struct sbp2_status_block { ...@@ -232,8 +225,8 @@ struct sbp2_status_block {
* Unit spec id and sw version entry for SBP-2 devices * Unit spec id and sw version entry for SBP-2 devices
*/ */
#define SBP2_UNIT_SPEC_ID_ENTRY 0x1200609e #define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x13010483 #define SBP2_SW_VERSION_ENTRY 0x00010483
/* /*
* Miscellaneous general config rom related defines * Miscellaneous general config rom related defines
...@@ -243,11 +236,8 @@ struct sbp2_status_block { ...@@ -243,11 +236,8 @@ struct sbp2_status_block {
#define CONFIG_ROM_BASE_ADDRESS 0xfffff0000400ULL #define CONFIG_ROM_BASE_ADDRESS 0xfffff0000400ULL
#define CONFIG_ROM_ROOT_DIR_BASE 0xfffff0000414ULL #define CONFIG_ROM_ROOT_DIR_BASE 0xfffff0000414ULL
#define CONFIG_ROM_SIGNATURE_ADDRESS 0xfffff0000404ULL
#define CONFIG_ROM_UNIT_DIRECTORY_OFFSET 0xfffff0000424ULL #define CONFIG_ROM_UNIT_DIRECTORY_OFFSET 0xfffff0000424ULL
#define IEEE1394_CONFIG_ROM_SIGNATURE 0x31333934
#define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800 #define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800
#define SBP2_BROKEN_FIRMWARE_MAX_TRANSFER 0x20000 #define SBP2_BROKEN_FIRMWARE_MAX_TRANSFER 0x20000
...@@ -350,6 +340,8 @@ struct sbp2_command_info { ...@@ -350,6 +340,8 @@ struct sbp2_command_info {
* Information needed on a per scsi id basis (one for each sbp2 device) * Information needed on a per scsi id basis (one for each sbp2 device)
*/ */
struct scsi_id_instance_data { struct scsi_id_instance_data {
/* SCSI ID */
int id;
/* /*
* Various sbp2 specific structures * Various sbp2 specific structures
...@@ -368,18 +360,15 @@ struct scsi_id_instance_data { ...@@ -368,18 +360,15 @@ struct scsi_id_instance_data {
/* /*
* Stuff we need to know about the sbp2 device itself * Stuff we need to know about the sbp2 device itself
*/ */
u64 node_unique_id;
u64 sbp2_management_agent_addr; u64 sbp2_management_agent_addr;
u64 sbp2_command_block_agent_addr; u64 sbp2_command_block_agent_addr;
u32 node_id;
u32 speed_code; u32 speed_code;
u32 max_payload_size; u32 max_payload_size;
/* /*
* Values pulled from the device's unit directory * Values pulled from the device's unit directory
*/ */
u32 sbp2_unit_spec_id; struct unit_directory *ud;
u32 sbp2_unit_sw_version;
u32 sbp2_command_set_spec_id; u32 sbp2_command_set_spec_id;
u32 sbp2_command_set; u32 sbp2_command_set;
u32 sbp2_unit_characteristics; u32 sbp2_unit_characteristics;
...@@ -391,12 +380,6 @@ struct scsi_id_instance_data { ...@@ -391,12 +380,6 @@ struct scsi_id_instance_data {
*/ */
wait_queue_head_t sbp2_login_wait; wait_queue_head_t sbp2_login_wait;
/*
* Flag noting whether the sbp2 device is currently validated (for use during
* bus resets).
*/
u32 validated;
/* /*
* Pool of command orbs, so we can have more than overlapped command per id * Pool of command orbs, so we can have more than overlapped command per id
*/ */
...@@ -405,6 +388,8 @@ struct scsi_id_instance_data { ...@@ -405,6 +388,8 @@ struct scsi_id_instance_data {
struct list_head sbp2_command_orb_completed; struct list_head sbp2_command_orb_completed;
u32 sbp2_total_command_orbs; u32 sbp2_total_command_orbs;
/* Node entry, as retrieved from NodeMgr entries */
struct node_entry *ne;
}; };
/* /*
...@@ -424,22 +409,6 @@ struct sbp2scsi_host_info { ...@@ -424,22 +409,6 @@ struct sbp2scsi_host_info {
spinlock_t sbp2_command_lock; spinlock_t sbp2_command_lock;
spinlock_t sbp2_request_packet_lock; spinlock_t sbp2_request_packet_lock;
/*
* Flag indicating if a bus reset (or device detection) is in progress
*/
u32 bus_reset_in_progress;
/*
* We currently use a kernel thread for dealing with bus resets and sbp2
* device detection. We use this to wake up the thread when needed.
*/
wait_queue_head_t sbp2_detection_wait;
/*
* PID of sbp2 detection kernel thread
*/
int sbp2_detection_pid;
/* /*
* Lists keeping track of inuse/free sbp2_request_packets. These structures are * Lists keeping track of inuse/free sbp2_request_packets. These structures are
* used for sending out sbp2 command and agent reset packets. We initially create * used for sending out sbp2 command and agent reset packets. We initially create
...@@ -449,13 +418,6 @@ struct sbp2scsi_host_info { ...@@ -449,13 +418,6 @@ struct sbp2scsi_host_info {
struct list_head sbp2_req_inuse; struct list_head sbp2_req_inuse;
struct list_head sbp2_req_free; struct list_head sbp2_req_free;
/*
* Stuff to keep track of the initial scsi bus scan (so that we don't miss it)
*/
u32 initial_scsi_bus_scan_complete;
Scsi_Cmnd *bus_scan_SCpnt;
void (*bus_scan_done)(Scsi_Cmnd *);
/* /*
* Here is the pool of request packets. All the hpsb packets (for 1394 bus transactions) * Here is the pool of request packets. All the hpsb packets (for 1394 bus transactions)
* are allocated at init and simply re-initialized when needed. * are allocated at init and simply re-initialized when needed.
...@@ -476,9 +438,6 @@ struct sbp2scsi_host_info { ...@@ -476,9 +438,6 @@ struct sbp2scsi_host_info {
/* /*
* Various utility prototypes * Various utility prototypes
*/ */
static int sbp2util_read_quadlet(struct sbp2scsi_host_info *hi, nodeid_t node, u64 addr,
quadlet_t *buffer);
static int sbp2util_unit_directory(struct sbp2scsi_host_info *hi, nodeid_t node, u64 *addr);
static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi); static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi);
static void sbp2util_remove_request_packet_pool(struct sbp2scsi_host_info *hi); static void sbp2util_remove_request_packet_pool(struct sbp2scsi_host_info *hi);
static struct sbp2_request_packet *sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi, static struct sbp2_request_packet *sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
...@@ -500,23 +459,19 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i ...@@ -500,23 +459,19 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
/* /*
* IEEE-1394 core driver related prototypes * IEEE-1394 core driver related prototypes
*/ */
static void sbp2_remove_unvalidated_devices(struct sbp2scsi_host_info *hi);
static int sbp2_start_device(struct sbp2scsi_host_info *hi, int node_id);
static int sbp2_check_device(struct sbp2scsi_host_info *hi, int node_id);
static void sbp2_bus_reset_handler(void *context);
static void sbp2_add_host(struct hpsb_host *host); static void sbp2_add_host(struct hpsb_host *host);
static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host); static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host);
static void sbp2_remove_host(struct hpsb_host *host); static void sbp2_remove_host(struct hpsb_host *host);
static void sbp2_host_reset(struct hpsb_host *host);
static int sbp2_detection_thread(void *__sbp2);
int sbp2_init(void); int sbp2_init(void);
void sbp2_cleanup(void); void sbp2_cleanup(void);
#if 0 static int sbp2_probe(struct unit_directory *ud);
static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, quadlet_t *data, static void sbp2_disconnect(struct unit_directory *ud);
u64 addr, unsigned int length); static void sbp2_update(struct unit_directory *ud);
static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data, static int sbp2_start_device(struct sbp2scsi_host_info *hi,
u64 addr, unsigned int length); struct unit_directory *ud);
#endif static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
struct scsi_id_instance_data *scsi_id);
/* /*
* SBP-2 protocol related prototypes * SBP-2 protocol related prototypes
*/ */
...@@ -543,7 +498,7 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense ...@@ -543,7 +498,7 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense
static void sbp2_check_sbp2_command(unchar *cmd); static void sbp2_check_sbp2_command(unchar *cmd);
static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *SCpnt); Scsi_Cmnd *SCpnt);
static int sbp2_parse_unit_directory(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id); static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id); static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id); static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
......
...@@ -488,24 +488,27 @@ static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) ...@@ -488,24 +488,27 @@ static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags)
int i; int i;
/* the first descriptor will read only 4 bytes */ /* the first descriptor will read only 4 bytes */
ir_prg[0].control = (0x280C << 16) | 4; ir_prg[0].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_BRANCH | 4;
/* set the sync flag */ /* set the sync flag */
if (flags & VIDEO1394_SYNC_FRAMES) if (flags & VIDEO1394_SYNC_FRAMES)
ir_prg[0].control |= 0x00030000; ir_prg[0].control |= DMA_CTL_WAIT;
ir_prg[0].address = kvirt_to_bus(buf); ir_prg[0].address = kvirt_to_bus(buf);
ir_prg[0].branchAddress = (virt_to_bus(&(ir_prg[1].control)) ir_prg[0].branchAddress = (virt_to_bus(&(ir_prg[1].control))
& 0xfffffff0) | 0x1; & 0xfffffff0) | 0x1;
/* the second descriptor will read PAGE_SIZE-4 bytes */ /* the second descriptor will read PAGE_SIZE-4 bytes */
ir_prg[1].control = (0x280C << 16) | (PAGE_SIZE-4); ir_prg[1].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_BRANCH | (PAGE_SIZE-4);
ir_prg[1].address = kvirt_to_bus(buf+4); ir_prg[1].address = kvirt_to_bus(buf+4);
ir_prg[1].branchAddress = (virt_to_bus(&(ir_prg[2].control)) ir_prg[1].branchAddress = (virt_to_bus(&(ir_prg[2].control))
& 0xfffffff0) | 0x1; & 0xfffffff0) | 0x1;
for (i=2;i<d->nb_cmd-1;i++) { for (i=2;i<d->nb_cmd-1;i++) {
ir_prg[i].control = (0x280C << 16) | PAGE_SIZE; ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_BRANCH | PAGE_SIZE;
ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE); ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
ir_prg[i].branchAddress = ir_prg[i].branchAddress =
...@@ -514,7 +517,8 @@ static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) ...@@ -514,7 +517,8 @@ static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags)
} }
/* the last descriptor will generate an interrupt */ /* the last descriptor will generate an interrupt */
ir_prg[i].control = (0x283C << 16) | d->left_size; ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size;
ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE); ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
} }
...@@ -691,13 +695,14 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) ...@@ -691,13 +695,14 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
d->last_used_cmd[n] = d->nb_cmd - 1; d->last_used_cmd[n] = d->nb_cmd - 1;
for (i=0;i<d->nb_cmd;i++) { for (i=0;i<d->nb_cmd;i++) {
it_prg[i].begin.control = OUTPUT_MORE_IMMEDIATE | 8 ; it_prg[i].begin.control = DMA_CTL_OUTPUT_MORE |
DMA_CTL_IMMEDIATE | 8 ;
it_prg[i].begin.address = 0; it_prg[i].begin.address = 0;
it_prg[i].begin.status = 0; it_prg[i].begin.status = 0;
it_prg[i].data[0] = it_prg[i].data[0] =
(DMA_SPEED_100 << 16) (SPEED_100 << 16)
| (/* tag */ 1 << 14) | (/* tag */ 1 << 14)
| (d->channel << 8) | (d->channel << 8)
| (TCODE_ISO_DATA << 4); | (TCODE_ISO_DATA << 4);
...@@ -706,7 +711,7 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) ...@@ -706,7 +711,7 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
it_prg[i].data[2] = 0; it_prg[i].data[2] = 0;
it_prg[i].data[3] = 0; it_prg[i].data[3] = 0;
it_prg[i].end.control = 0x100c0000; it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
it_prg[i].end.address = it_prg[i].end.address =
kvirt_to_bus(buf+i*d->packet_size); kvirt_to_bus(buf+i*d->packet_size);
...@@ -721,7 +726,8 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) ...@@ -721,7 +726,8 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
} }
else { else {
/* the last prg generates an interrupt */ /* the last prg generates an interrupt */
it_prg[i].end.control |= 0x08300000 | d->left_size; it_prg[i].end.control |= DMA_CTL_UPDATE |
DMA_CTL_IRQ | d->left_size;
/* the last prg doesn't branch */ /* the last prg doesn't branch */
it_prg[i].begin.branchAddress = 0; it_prg[i].begin.branchAddress = 0;
it_prg[i].end.branchAddress = 0; it_prg[i].end.branchAddress = 0;
...@@ -761,7 +767,7 @@ static void initialize_dma_it_prg_var_packet_queue( ...@@ -761,7 +767,7 @@ static void initialize_dma_it_prg_var_packet_queue(
size = packet_sizes[i]; size = packet_sizes[i];
} }
it_prg[i].data[1] = size << 16; it_prg[i].data[1] = size << 16;
it_prg[i].end.control = 0x100c0000; it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) { if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) {
it_prg[i].end.control |= size; it_prg[i].end.control |= size;
...@@ -773,7 +779,8 @@ static void initialize_dma_it_prg_var_packet_queue( ...@@ -773,7 +779,8 @@ static void initialize_dma_it_prg_var_packet_queue(
& 0xfffffff0) | 0x3; & 0xfffffff0) | 0x3;
} else { } else {
/* the last prg generates an interrupt */ /* the last prg generates an interrupt */
it_prg[i].end.control |= 0x08300000 | size; it_prg[i].end.control |= DMA_CTL_UPDATE |
DMA_CTL_IRQ | size;
/* the last prg doesn't branch */ /* the last prg doesn't branch */
it_prg[i].begin.branchAddress = 0; it_prg[i].begin.branchAddress = 0;
it_prg[i].end.branchAddress = 0; it_prg[i].end.branchAddress = 0;
...@@ -1560,7 +1567,6 @@ static int video1394_init(struct ti_ohci *ohci) ...@@ -1560,7 +1567,6 @@ static int video1394_init(struct ti_ohci *ohci)
static void remove_card(struct video_card *video) static void remove_card(struct video_card *video)
{ {
int i; int i;
unsigned long flags;
ohci1394_unregister_video(video->ohci, &video_tmpl); ohci1394_unregister_video(video->ohci, &video_tmpl);
...@@ -1581,9 +1587,7 @@ static void remove_card(struct video_card *video) ...@@ -1581,9 +1587,7 @@ static void remove_card(struct video_card *video)
} }
kfree(video->it_context); kfree(video->it_context);
} }
spin_lock_irqsave(&video1394_cards_lock, flags);
list_del(&video->list); list_del(&video->list);
spin_unlock_irqrestore(&video1394_cards_lock, flags);
kfree(video); kfree(video);
} }
...@@ -1607,7 +1611,7 @@ static void video1394_remove_host (struct hpsb_host *host) ...@@ -1607,7 +1611,7 @@ static void video1394_remove_host (struct hpsb_host *host)
p = list_entry(lh, struct video_card, list); p = list_entry(lh, struct video_card, list);
if (p ->ohci == ohci) { if (p ->ohci == ohci) {
remove_card(p); remove_card(p);
return; break;
} }
} }
} }
......
This diff is collapsed.
...@@ -137,7 +137,7 @@ an MMIO register read. ...@@ -137,7 +137,7 @@ an MMIO register read.
*/ */
#define DRV_NAME "8139too" #define DRV_NAME "8139too"
#define DRV_VERSION "0.9.18a" #define DRV_VERSION "0.9.19"
#include <linux/config.h> #include <linux/config.h>
...@@ -620,6 +620,7 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); ...@@ -620,6 +620,7 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static inline u32 ether_crc (int length, unsigned char *data); static inline u32 ether_crc (int length, unsigned char *data);
static void rtl8139_set_rx_mode (struct net_device *dev); static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev);
#ifdef USE_IO_OPS #ifdef USE_IO_OPS
...@@ -962,6 +963,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, ...@@ -962,6 +963,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
dev->do_ioctl = netdev_ioctl; dev->do_ioctl = netdev_ioctl;
dev->tx_timeout = rtl8139_tx_timeout; dev->tx_timeout = rtl8139_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
dev->irq = pdev->irq; dev->irq = pdev->irq;
...@@ -1725,18 +1727,21 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) ...@@ -1725,18 +1727,21 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
assert (tp->tx_info[entry].mapping == 0); assert (tp->tx_info[entry].mapping == 0);
tp->tx_info[entry].skb = skb; tp->tx_info[entry].skb = skb;
if ((long) skb->data & 3) { /* Must use alignment buffer. */ if ( !((unsigned long)skb->data & 3) && skb_shinfo(skb)->nr_frags == 0 &&
/* tp->tx_info[entry].mapping = 0; */ skb->ip_summed != CHECKSUM_HW) {
memcpy (tp->tx_buf[entry], skb->data, skb->len);
dma_addr = tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs);
} else {
tp->xstats.tx_buf_mapped++; tp->xstats.tx_buf_mapped++;
tp->tx_info[entry].mapping = tp->tx_info[entry].mapping =
pci_map_single (tp->pci_dev, skb->data, skb->len, pci_map_single (tp->pci_dev, skb->data, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
dma_addr = tp->tx_info[entry].mapping; dma_addr = tp->tx_info[entry].mapping;
} else if (skb->len < TX_BUF_SIZE) {
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
dma_addr = tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs);
} else {
dev_kfree_skb(skb);
tp->tx_info[entry].skb = NULL;
return 0;
} }
/* Note: the chip doesn't have auto-pad! */ /* Note: the chip doesn't have auto-pad! */
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
RTL_W32_F (TxAddr0 + (entry * 4), dma_addr); RTL_W32_F (TxAddr0 + (entry * 4), dma_addr);
...@@ -1847,7 +1852,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, ...@@ -1847,7 +1852,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
struct rtl8139_private *tp, void *ioaddr) struct rtl8139_private *tp, void *ioaddr)
{ {
u8 tmp8; u8 tmp8;
int tmp_work = 1000; int tmp_work;
DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n", DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
dev->name, rx_status); dev->name, rx_status);
...@@ -1863,33 +1868,52 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, ...@@ -1863,33 +1868,52 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
tp->stats.rx_length_errors++; tp->stats.rx_length_errors++;
if (rx_status & RxCRCErr) if (rx_status & RxCRCErr)
tp->stats.rx_crc_errors++; tp->stats.rx_crc_errors++;
/* Reset the receiver, based on RealTek recommendation. (Bug?) */ /* Reset the receiver, based on RealTek recommendation. (Bug?) */
tp->cur_rx = 0;
/* disable receive */ /* disable receive */
RTL_W8 (ChipCmd, CmdTxEnb); RTL_W8_F (ChipCmd, CmdTxEnb);
tmp_work = 200;
/* A.C.: Reset the multicast list. */
rtl8139_set_rx_mode (dev);
/* XXX potentially temporary hack to
* restart hung receiver */
while (--tmp_work > 0) { while (--tmp_work > 0) {
barrier(); udelay(1);
tmp8 = RTL_R8 (ChipCmd);
if (!(tmp8 & CmdRxEnb))
break;
}
if (tmp_work <= 0)
printk (KERN_WARNING PFX "rx stop wait too long\n");
/* restart receive */
tmp_work = 200;
while (--tmp_work > 0) {
RTL_W8_F (ChipCmd, CmdRxEnb | CmdTxEnb);
udelay(1);
tmp8 = RTL_R8 (ChipCmd); tmp8 = RTL_R8 (ChipCmd);
if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb)) if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
break; break;
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
} }
/* G.S.: Re-enable receiver */
/* XXX temporary hack to work around receiver hang */
rtl8139_set_rx_mode (dev);
if (tmp_work <= 0) if (tmp_work <= 0)
printk (KERN_WARNING PFX "tx/rx enable wait too long\n"); printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
}
/* and reinitialize all rx related registers */
RTL_W8_F (Cfg9346, Cfg9346_Unlock);
/* Must enable Tx/Rx before setting transfer thresholds! */
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
RTL_W32 (RxConfig, tp->rx_config);
tp->cur_rx = 0;
DPRINTK("init buffer addresses\n");
/* Lock Config[01234] and BMCR register writes */
RTL_W8 (Cfg9346, Cfg9346_Lock);
/* init Rx ring buffer DMA address */
RTL_W32_F (RxBuf, tp->rx_ring_dma);
/* A.C.: Reset the multicast list. */
__set_rx_mode (dev);
}
static void rtl8139_rx_interrupt (struct net_device *dev, static void rtl8139_rx_interrupt (struct net_device *dev,
struct rtl8139_private *tp, void *ioaddr) struct rtl8139_private *tp, void *ioaddr)
...@@ -2312,11 +2336,10 @@ static inline u32 ether_crc (int length, unsigned char *data) ...@@ -2312,11 +2336,10 @@ static inline u32 ether_crc (int length, unsigned char *data)
} }
static void rtl8139_set_rx_mode (struct net_device *dev) static void __set_rx_mode (struct net_device *dev)
{ {
struct rtl8139_private *tp = dev->priv; struct rtl8139_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr; void *ioaddr = tp->mmio_addr;
unsigned long flags;
u32 mc_filter[2]; /* Multicast hash filter */ u32 mc_filter[2]; /* Multicast hash filter */
int i, rx_mode; int i, rx_mode;
u32 tmp; u32 tmp;
...@@ -2353,22 +2376,28 @@ static void rtl8139_set_rx_mode (struct net_device *dev) ...@@ -2353,22 +2376,28 @@ static void rtl8139_set_rx_mode (struct net_device *dev)
} }
} }
spin_lock_irqsave (&tp->lock, flags);
/* We can safely update without stopping the chip. */ /* We can safely update without stopping the chip. */
tmp = rtl8139_rx_config | rx_mode; tmp = rtl8139_rx_config | rx_mode;
if (tp->rx_config != tmp) { if (tp->rx_config != tmp) {
RTL_W32 (RxConfig, tmp); RTL_W32_F (RxConfig, tmp);
tp->rx_config = tmp; tp->rx_config = tmp;
} }
RTL_W32_F (MAR0 + 0, mc_filter[0]); RTL_W32_F (MAR0 + 0, mc_filter[0]);
RTL_W32_F (MAR0 + 4, mc_filter[1]); RTL_W32_F (MAR0 + 4, mc_filter[1]);
spin_unlock_irqrestore (&tp->lock, flags);
DPRINTK ("EXIT\n"); DPRINTK ("EXIT\n");
} }
static void rtl8139_set_rx_mode (struct net_device *dev)
{
unsigned long flags;
struct rtl8139_private *tp = dev->priv;
spin_lock_irqsave (&tp->lock, flags);
__set_rx_mode(dev);
spin_unlock_irqrestore (&tp->lock, flags);
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
This diff is collapsed.
...@@ -148,10 +148,10 @@ void __devinit tulip_parse_eeprom(struct net_device *dev) ...@@ -148,10 +148,10 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
unsigned char media_block = *p++; unsigned char media_block = *p++;
int media_code = media_block & MEDIA_MASK; int media_code = media_block & MEDIA_MASK;
if (media_code & 0x40) if (media_block & 0x40)
p += 6; p += 6;
printk(KERN_INFO "%s: 21041 media #%d, %s.\n", printk(KERN_INFO "%s: 21041 media #%d, %s.\n",
dev->name, media_code & 15, medianame[media_code & 15]); dev->name, media_code, medianame[media_code]);
} }
} else { } else {
unsigned char *p = (void *)ee_data + ee_data[27]; unsigned char *p = (void *)ee_data + ee_data[27];
......
...@@ -301,7 +301,7 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ...@@ -301,7 +301,7 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
long ioaddr = dev->base_addr; long ioaddr = dev->base_addr;
int csr5; int csr5;
int entry; int entry;
int missed; int csr8;
int rx = 0; int rx = 0;
int tx = 0; int tx = 0;
int oi = 0; int oi = 0;
...@@ -434,7 +434,6 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ...@@ -434,7 +434,6 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} }
} }
if (csr5 & RxDied) { /* Missed a Rx frame. */ if (csr5 & RxDied) { /* Missed a Rx frame. */
tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
#ifdef CONFIG_NET_HW_FLOWCONTROL #ifdef CONFIG_NET_HW_FLOWCONTROL
if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) { if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
tp->stats.rx_errors++; tp->stats.rx_errors++;
...@@ -548,9 +547,8 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ...@@ -548,9 +547,8 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} }
} }
if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) { csr8 = inl(ioaddr + CSR8);
tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; tp->stats.rx_dropped += (csr8 & 0x1ffff) + ((csr8 >> 17) & 0xfff);
}
if (tulip_debug > 4) if (tulip_debug > 4)
printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n", printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
*/ */
#define DRV_NAME "tulip" #define DRV_NAME "tulip"
#define DRV_VERSION "0.9.15-pre6" #define DRV_VERSION "0.9.15-pre7"
#define DRV_RELDATE "July 2, 2001" #define DRV_RELDATE "Oct 2, 2001"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -341,6 +341,7 @@ static int do8bitIO = 0; ...@@ -341,6 +341,7 @@ static int do8bitIO = 0;
/* The RIDs */ /* The RIDs */
#define RID_CAPABILITIES 0xFF00 #define RID_CAPABILITIES 0xFF00
#define RID_RSSI 0xFF04
#define RID_CONFIG 0xFF10 #define RID_CONFIG 0xFF10
#define RID_SSID 0xFF11 #define RID_SSID 0xFF11
#define RID_APLIST 0xFF12 #define RID_APLIST 0xFF12
...@@ -627,6 +628,16 @@ typedef struct { ...@@ -627,6 +628,16 @@ typedef struct {
u16 atimWindow; u16 atimWindow;
} BSSListRid; } BSSListRid;
typedef struct {
u8 rssipct;
u8 rssidBm;
} tdsRssiEntry;
typedef struct {
u16 len;
tdsRssiEntry x[256];
} tdsRssiRid;
#pragma pack() #pragma pack()
#define TXCTL_TXOK (1<<1) /* report if tx is ok */ #define TXCTL_TXOK (1<<1) /* report if tx is ok */
...@@ -774,6 +785,7 @@ struct airo_info { ...@@ -774,6 +785,7 @@ struct airo_info {
int whichbap); int whichbap);
int (*header_parse)(struct sk_buff*, unsigned char *); int (*header_parse)(struct sk_buff*, unsigned char *);
unsigned short *flash; unsigned short *flash;
tdsRssiEntry *rssi;
#ifdef WIRELESS_EXT #ifdef WIRELESS_EXT
int need_commit; // Need to set config int need_commit; // Need to set config
struct iw_statistics wstats; // wireless stats struct iw_statistics wstats; // wireless stats
...@@ -1076,6 +1088,8 @@ void stop_airo_card( struct net_device *dev, int freeres ) ...@@ -1076,6 +1088,8 @@ void stop_airo_card( struct net_device *dev, int freeres )
struct airo_info *ai = (struct airo_info*)dev->priv; struct airo_info *ai = (struct airo_info*)dev->priv;
if (ai->flash) if (ai->flash)
kfree(ai->flash); kfree(ai->flash);
if (ai->rssi)
kfree(ai->rssi);
takedown_proc_entry( dev, ai ); takedown_proc_entry( dev, ai );
if (ai->registered) { if (ai->registered) {
unregister_netdev( dev ); unregister_netdev( dev );
...@@ -1382,7 +1396,10 @@ static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { ...@@ -1382,7 +1396,10 @@ static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
if (!memcmp(sa,apriv->spy_address[i],6)) if (!memcmp(sa,apriv->spy_address[i],6))
{ {
apriv->spy_stat[i].qual = hdr.rssi[0]; apriv->spy_stat[i].qual = hdr.rssi[0];
apriv->spy_stat[i].level = hdr.rssi[1]; if (apriv->rssi)
apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
else
apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
apriv->spy_stat[i].noise = 0; apriv->spy_stat[i].noise = 0;
apriv->spy_stat[i].updated = 3; apriv->spy_stat[i].updated = 3;
break; break;
...@@ -1568,9 +1585,29 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, ...@@ -1568,9 +1585,29 @@ static u16 setup_card(struct airo_info *ai, u8 *mac,
if ( config->len ) { if ( config->len ) {
cfg = *config; cfg = *config;
} else { } else {
tdsRssiRid rssi_rid;
// general configuration (read/modify/write) // general configuration (read/modify/write)
status = readConfigRid(ai, &cfg); status = readConfigRid(ai, &cfg);
if ( status != SUCCESS ) return ERROR; if ( status != SUCCESS ) return ERROR;
status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid));
if ( status == SUCCESS ) {
if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
}
else {
CapabilityRid cap_rid;
if (ai->rssi) {
kfree(ai->rssi);
ai->rssi = NULL;
}
status = readCapabilityRid(ai, &cap_rid);
if ((status == SUCCESS) && (cap_rid.softCap & 8))
cfg.rmode |= RXMODE_NORMALIZED_RSSI;
else
printk(KERN_WARNING "airo: unknown received signal level\n");
}
cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
/* Save off the MAC */ /* Save off the MAC */
...@@ -3814,7 +3851,7 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -3814,7 +3851,7 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* Hum... Should put the right values there */ /* Hum... Should put the right values there */
range.max_qual.qual = 10; range.max_qual.qual = 10;
range.max_qual.level = 100; range.max_qual.level = 0;
range.max_qual.noise = 0; range.max_qual.noise = 0;
range.sensitivity = 65535; range.sensitivity = 65535;
...@@ -3976,7 +4013,10 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -3976,7 +4013,10 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
loseSync = 0; loseSync = 0;
memcpy(s[i].sa_data, BSSList.bssid, 6); memcpy(s[i].sa_data, BSSList.bssid, 6);
s[i].sa_family = ARPHRD_ETHER; s[i].sa_family = ARPHRD_ETHER;
qual[i].level = BSSList.rssi; if (local->rssi)
qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
else
qual[i].level = (BSSList.rssi + 321) / 2;
qual[i].qual = qual[i].noise = 0; qual[i].qual = qual[i].noise = 0;
qual[i].updated = 2; qual[i].updated = 2;
if (BSSList.index == 0xffff) break; if (BSSList.index == 0xffff) break;
...@@ -4190,7 +4230,10 @@ struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) ...@@ -4190,7 +4230,10 @@ struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
/* Signal quality and co. But where is the noise level ??? */ /* Signal quality and co. But where is the noise level ??? */
local->wstats.qual.qual = status_rid.signalQuality; local->wstats.qual.qual = status_rid.signalQuality;
local->wstats.qual.level = status_rid.normalizedSignalStrength; if (local->rssi)
local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
else
local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
local->wstats.qual.noise = 0; local->wstats.qual.noise = 0;
local->wstats.qual.updated = 3; local->wstats.qual.updated = 3;
......
...@@ -14,8 +14,31 @@ ...@@ -14,8 +14,31 @@
* particular order). * particular order).
* *
* Copyright (C) 2000, David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au> * Copyright (C) 2000, David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
* Copyright (C) 2001, David Gibson, IBM <hermes@gibson.dropbear.id.au>
* *
* This file distributed under the GPL, version 2. */ * The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
* at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and
* limitations under the License.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License version 2 (the "GPL"), in
* which case the provisions of the GPL are applicable instead of the
* above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*/
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -30,10 +53,10 @@ ...@@ -30,10 +53,10 @@
#include "hermes.h" #include "hermes.h"
static char version[] __initdata = "hermes.c: 1 Aug 2001 David Gibson <hermes@gibson.dropbear.id.au>"; static char version[] __initdata = "hermes.c: 3 Oct 2001 David Gibson <hermes@gibson.dropbear.id.au>";
MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller"); MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>"); MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("Dual MPL/GPL");
/* These are maximum timeouts. Most often, card wil react much faster */ /* These are maximum timeouts. Most often, card wil react much faster */
#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */ #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
...@@ -42,9 +65,6 @@ MODULE_LICENSE("GPL"); ...@@ -42,9 +65,6 @@ MODULE_LICENSE("GPL");
#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
#define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */ #define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
#define MIN(a, b) ( (a) < (b) ? (a) : (b) )
/* /*
* Debugging helpers * Debugging helpers
*/ */
...@@ -292,7 +312,7 @@ int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid) ...@@ -292,7 +312,7 @@ int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid)
* from firmware * from firmware
* *
* Callable from any context */ * Callable from any context */
static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset) int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
{ {
int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0; int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0; int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
...@@ -305,9 +325,14 @@ static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset) ...@@ -305,9 +325,14 @@ static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
k = BAP_BUSY_TIMEOUT; k = BAP_BUSY_TIMEOUT;
reg = hermes_read_reg(hw, oreg); reg = hermes_read_reg(hw, oreg);
while ((reg & HERMES_OFFSET_BUSY) & k) {
k--;
udelay(1);
reg = hermes_read_reg(hw, oreg);
}
if (reg & HERMES_OFFSET_BUSY) if (reg & HERMES_OFFSET_BUSY)
return -EBUSY; return -ETIMEDOUT;
/* Now we actually set up the transfer */ /* Now we actually set up the transfer */
hermes_write_reg(hw, sreg, id); hermes_write_reg(hw, sreg, id);
...@@ -342,7 +367,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset) ...@@ -342,7 +367,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
* *
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/ */
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len, int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
uint16_t id, uint16_t offset) uint16_t id, uint16_t offset)
{ {
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
...@@ -356,7 +381,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len, ...@@ -356,7 +381,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len,
goto out; goto out;
/* Actually do the transfer */ /* Actually do the transfer */
hermes_read_data(hw, dreg, buf, len/2); hermes_read_words(hw, dreg, buf, len/2);
out: out:
return err; return err;
...@@ -368,7 +393,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len, ...@@ -368,7 +393,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len,
* *
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/ */
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len, int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
uint16_t id, uint16_t offset) uint16_t id, uint16_t offset)
{ {
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
...@@ -382,7 +407,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len, ...@@ -382,7 +407,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len,
goto out; goto out;
/* Actually do the transfer */ /* Actually do the transfer */
hermes_write_data(hw, dreg, buf, len/2); hermes_write_words(hw, dreg, buf, len/2);
out: out:
return err; return err;
...@@ -434,17 +459,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen, ...@@ -434,17 +459,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
lengths in the records seem to be wrong, frequently */ lengths in the records seem to be wrong, frequently */
count = buflen / 2; count = buflen / 2;
#if 0 hermes_read_words(hw, dreg, buf, count);
if (length)
count = (MIN(buflen, rlength) + 1) / 2;
else {
count = buflen / 2;
if (rlength != buflen)
printk(KERN_WARNING "hermes_read_ltv(): Incorrect \
record length %d instead of %d on RID 0x%04x\n", rlength, buflen, rid);
}
#endif
hermes_read_data(hw, dreg, buf, count);
out: out:
return err; return err;
...@@ -470,7 +485,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid, ...@@ -470,7 +485,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid,
count = length - 1; count = length - 1;
hermes_write_data(hw, dreg, value, count); hermes_write_words(hw, dreg, value, count);
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
rid, &resp); rid, &resp);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define HERMES_FRAME_LEN_MAX (2304) #define HERMES_FRAME_LEN_MAX (2304)
#define HERMES_MAX_MULTICAST (16) #define HERMES_MAX_MULTICAST (16)
#define HERMES_MAGIC (0x7d1f) #define HERMES_MAGIC (0x7d1f)
#define HERMES_SYMBOL_MAX_VER (14)
/* /*
* Hermes register offsets * Hermes register offsets
...@@ -202,24 +203,21 @@ ...@@ -202,24 +203,21 @@
#define HERMES_RID_WEP_AVAIL (0xfd4f) #define HERMES_RID_WEP_AVAIL (0xfd4f)
#define HERMES_RID_CURRENT_CHANNEL (0xfdc1) #define HERMES_RID_CURRENT_CHANNEL (0xfdc1)
#define HERMES_RID_DATARATES (0xfdc6) #define HERMES_RID_DATARATES (0xfdc6)
#define HERMES_RID_SYMBOL_PRIMARY_VER (0xfd03) #define HERMES_RID_SYMBOL_SECONDARY_VER (0xfd24)
#define HERMES_RID_SYMBOL_SECONDARY_VER (0xfd21)
#define HERMES_RID_SYMBOL_KEY_LENGTH (0xfc2B) #define HERMES_RID_SYMBOL_KEY_LENGTH (0xfc2B)
/* /*
* Frame structures and constants * Frame structures and constants
*/ */
#define __PACKED__ __attribute__ ((packed))
typedef struct hermes_frame_desc { typedef struct hermes_frame_desc {
/* Hermes - i.e. little-endian byte-order */ /* Hermes - i.e. little-endian byte-order */
uint16_t status __PACKED__; uint16_t status;
uint16_t res1, res2 __PACKED__; uint16_t res1, res2;
uint16_t q_info __PACKED__; uint16_t q_info;
uint16_t res3, res4 __PACKED__; uint16_t res3, res4;
uint16_t tx_ctl __PACKED__; uint16_t tx_ctl;
} hermes_frame_desc_t; } __attribute__ ((packed)) hermes_frame_desc_t;
#define HERMES_RXSTAT_ERR (0x0003) #define HERMES_RXSTAT_ERR (0x0003)
#define HERMES_RXSTAT_MACPORT (0x0700) #define HERMES_RXSTAT_MACPORT (0x0700)
...@@ -265,20 +263,16 @@ typedef struct hermes_multicast { ...@@ -265,20 +263,16 @@ typedef struct hermes_multicast {
#define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name)) #define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
#define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val))) #define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
/* Note that for the next two, the count is in 16-bit words, not bytes */
#define hermes_read_data(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
#define hermes_write_data(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
/* Function prototypes */ /* Function prototypes */
void hermes_struct_init(hermes_t *hw, uint io); void hermes_struct_init(hermes_t *hw, uint io);
int hermes_reset(hermes_t *hw); int hermes_reset(hermes_t *hw);
int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp); int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp);
int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid); int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid);
int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset);
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len, int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
uint16_t id, uint16_t offset); uint16_t id, uint16_t offset);
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len, int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
uint16_t id, uint16_t offset); uint16_t id, uint16_t offset);
int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen, int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
uint16_t *length, void *buf); uint16_t *length, void *buf);
...@@ -323,6 +317,10 @@ static inline int hermes_disable_port(hermes_t *hw, int port) ...@@ -323,6 +317,10 @@ static inline int hermes_disable_port(hermes_t *hw, int port)
#define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 ) #define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 ) #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
/* Note that for the next two, the count is in 16-bit words, not bytes */
#define hermes_read_words(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
#define hermes_write_words(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
#define HERMES_READ_RECORD(hw, bap, rid, buf) \ #define HERMES_READ_RECORD(hw, bap, rid, buf) \
(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf))) (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -99,7 +99,7 @@ decode_pathname(u32 *p, char **namp, int *lenp) ...@@ -99,7 +99,7 @@ decode_pathname(u32 *p, char **namp, int *lenp)
char *name; char *name;
int i; int i;
if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) { if ((p = xdr_decode_string(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) {
for (i = 0, name = *namp; i < *lenp; i++, name++) { for (i = 0, name = *namp; i < *lenp; i++, name++) {
if (*name == '\0') if (*name == '\0')
return NULL; return NULL;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
int ibm_partition(struct gendisk *, kdev_t, unsigned long, int); int ibm_partition(struct gendisk *, struct block_device *, unsigned long, int);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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