Commit 26a3e565 authored by Ben Collins's avatar Ben Collins

ieee1394: CSR1212 Extended ROM bug fixes

  - Use vmalloc instead of kmalloc
  - Change delayed_reset_bus() to operate in a work_queue instead of a timer
    interrupt.
  - Fix hpsb_allocate_and_register_addrspace() to not allocate space on top
    of already allocated space.
  - Fix problems in csr1212.c filling ConfigROM images when extend ROMs are
    present.
Signed-off-by: default avatarSteve Kinneberg <kberg@linux1394.org>
Signed-off-by: default avatarBen Collins <bcollins@debian.org>
parent bd8f3917
...@@ -1061,6 +1061,10 @@ void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache) ...@@ -1061,6 +1061,10 @@ void csr1212_fill_cache(struct csr1212_csr_rom_cache *cache)
} }
nkv = kv->next; nkv = kv->next;
if (kv->prev)
kv->prev->next = NULL;
if (kv->next)
kv->next->prev = NULL;
kv->prev = NULL; kv->prev = NULL;
kv->next = NULL; kv->next = NULL;
} }
...@@ -1134,7 +1138,7 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr) ...@@ -1134,7 +1138,7 @@ int csr1212_generate_csr_image(struct csr1212_csr *csr)
/* Make sure the Extended ROM leaf is a multiple of /* Make sure the Extended ROM leaf is a multiple of
* max_rom in size. */ * max_rom in size. */
leaf_size = (cache->len + (csr->max_rom - 1)) & leaf_size = (cache->len + (csr->max_rom - 1)) &
(csr->max_rom - 1); ~(csr->max_rom - 1);
/* Zero out the unused ROM region */ /* Zero out the unused ROM region */
memset(cache->data + bytes_to_quads(cache->len), 0x00, memset(cache->data + bytes_to_quads(cache->len), 0x00,
......
...@@ -38,9 +38,11 @@ ...@@ -38,9 +38,11 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/vmalloc.h>
#include <asm/pgalloc.h>
#define CSR1212_MALLOC(size) kmalloc((size), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) #define CSR1212_MALLOC(size) vmalloc((size))
#define CSR1212_FREE(ptr) kfree(ptr) #define CSR1212_FREE(ptr) vfree(ptr)
#define CSR1212_BE16_TO_CPU(quad) be16_to_cpu(quad) #define CSR1212_BE16_TO_CPU(quad) be16_to_cpu(quad)
#define CSR1212_CPU_TO_BE16(quad) cpu_to_be16(quad) #define CSR1212_CPU_TO_BE16(quad) cpu_to_be16(quad)
#define CSR1212_BE32_TO_CPU(quad) be32_to_cpu(quad) #define CSR1212_BE32_TO_CPU(quad) be32_to_cpu(quad)
......
...@@ -383,7 +383,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl, ...@@ -383,7 +383,7 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
a2sa = a2->start & align_mask; a2sa = a2->start & align_mask;
a2ea = (a2->end + alignment -1) & align_mask; a2ea = (a2->end + alignment -1) & align_mask;
if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (end - a1ea >= size)) { if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (a2sa > start)) {
as->start = max(start, a1ea); as->start = max(start, a1ea);
as->end = as->start + size; as->end = as->start + size;
list_add(&as->host_list, entry); list_add(&as->host_list, entry);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "config_roms.h" #include "config_roms.h"
static void delayed_reset_bus(unsigned long __reset_info) static void delayed_reset_bus(void * __reset_info)
{ {
struct hpsb_host *host = (struct hpsb_host*)__reset_info; struct hpsb_host *host = (struct hpsb_host*)__reset_info;
int generation = host->csr.generation + 1; int generation = host->csr.generation + 1;
...@@ -129,9 +129,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, ...@@ -129,9 +129,6 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
skb_queue_head_init(&h->pending_packet_queue); skb_queue_head_init(&h->pending_packet_queue);
INIT_LIST_HEAD(&h->addr_space); INIT_LIST_HEAD(&h->addr_space);
init_timer(&h->delayed_reset);
h->delayed_reset.function = delayed_reset_bus;
h->delayed_reset.data = (unsigned long)h;
for (i = 2; i < 16; i++) for (i = 2; i < 16; i++)
h->csr.gen_timestamp[i] = jiffies - 60 * HZ; h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
...@@ -140,6 +137,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, ...@@ -140,6 +137,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
atomic_set(&h->generation, 0); atomic_set(&h->generation, 0);
INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
init_timer(&h->timeout); init_timer(&h->timeout);
h->timeout.data = (unsigned long) h; h->timeout.data = (unsigned long) h;
h->timeout.function = abort_timedouts; h->timeout.function = abort_timedouts;
...@@ -188,7 +187,8 @@ void hpsb_remove_host(struct hpsb_host *host) ...@@ -188,7 +187,8 @@ void hpsb_remove_host(struct hpsb_host *host)
{ {
host->is_shutdown = 1; host->is_shutdown = 1;
del_timer_sync(&host->delayed_reset); cancel_delayed_work(&host->delayed_reset);
flush_scheduled_work();
host->driver = &dummy_driver; host->driver = &dummy_driver;
...@@ -202,7 +202,7 @@ void hpsb_remove_host(struct hpsb_host *host) ...@@ -202,7 +202,7 @@ void hpsb_remove_host(struct hpsb_host *host)
int hpsb_update_config_rom_image(struct hpsb_host *host) int hpsb_update_config_rom_image(struct hpsb_host *host)
{ {
unsigned long reset_time; unsigned long reset_delay;
int next_gen = host->csr.generation + 1; int next_gen = host->csr.generation + 1;
if (!host->update_config_rom) if (!host->update_config_rom)
...@@ -213,21 +213,21 @@ int hpsb_update_config_rom_image(struct hpsb_host *host) ...@@ -213,21 +213,21 @@ int hpsb_update_config_rom_image(struct hpsb_host *host)
/* Stop the delayed interrupt, we're about to change the config rom and /* Stop the delayed interrupt, we're about to change the config rom and
* it would be a waste to do a bus reset twice. */ * it would be a waste to do a bus reset twice. */
del_timer_sync(&host->delayed_reset); cancel_delayed_work(&host->delayed_reset);
/* IEEE 1394a-2000 prohibits using the same generation number /* IEEE 1394a-2000 prohibits using the same generation number
* twice in a 60 second period. */ * twice in a 60 second period. */
if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ) if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ)
/* Wait 60 seconds from the last time this generation number was /* Wait 60 seconds from the last time this generation number was
* used. */ * used. */
reset_time = (60 * HZ) + host->csr.gen_timestamp[next_gen]; reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
else else
/* Wait 1 second in case some other code wants to change the /* Wait 1 second in case some other code wants to change the
* Config ROM in the near future. */ * Config ROM in the near future. */
reset_time = jiffies + HZ; reset_delay = HZ;
/* This will add the timer as well as modify it */ PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host);
mod_timer(&host->delayed_reset, reset_time); schedule_delayed_work(&host->delayed_reset, reset_delay);
return 0; return 0;
} }
...@@ -66,7 +66,7 @@ struct hpsb_host { ...@@ -66,7 +66,7 @@ struct hpsb_host {
struct class_device class_dev; struct class_device class_dev;
int update_config_rom; int update_config_rom;
struct timer_list delayed_reset; struct work_struct delayed_reset;
unsigned int config_roms; unsigned int config_roms;
......
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