summaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/dv1394.c10
-rw-r--r--drivers/ieee1394/highlevel.c25
-rw-r--r--drivers/ieee1394/hosts.c4
-rw-r--r--drivers/ieee1394/hosts.h4
-rw-r--r--drivers/ieee1394/nodemgr.c22
-rw-r--r--drivers/ieee1394/raw1394.c9
-rw-r--r--drivers/ieee1394/sbp2.c14
7 files changed, 55 insertions, 33 deletions
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 965cfdb84ebc..c19f23267157 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1270,8 +1270,14 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma)
struct video_card *video = file_to_video_card(file);
int retval = -EINVAL;
- /* serialize mmap */
- mutex_lock(&video->mtx);
+ /*
+ * We cannot use the blocking variant mutex_lock here because .mmap
+ * is called with mmap_sem held, while .ioctl, .read, .write acquire
+ * video->mtx and subsequently call copy_to/from_user which will
+ * grab mmap_sem in case of a page fault.
+ */
+ if (!mutex_trylock(&video->mtx))
+ return -EAGAIN;
if ( ! video_card_initialized(video) ) {
retval = do_dv1394_init_default(video);
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
index 918ffc4fc8ac..272543a42a43 100644
--- a/drivers/ieee1394/highlevel.c
+++ b/drivers/ieee1394/highlevel.c
@@ -46,10 +46,6 @@ static DEFINE_RWLOCK(hl_irqs_lock);
static DEFINE_RWLOCK(addr_space_lock);
-/* addr_space list will have zero and max already included as bounds */
-static struct hpsb_address_ops dummy_ops = { NULL, NULL, NULL, NULL };
-static struct hpsb_address_serve dummy_zero_addr, dummy_max_addr;
-
static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
struct hpsb_host *host)
@@ -481,20 +477,23 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
return retval;
}
+static struct hpsb_address_ops dummy_ops;
+
+/* dummy address spaces as lower and upper bounds of the host's a.s. list */
static void init_hpsb_highlevel(struct hpsb_host *host)
{
- INIT_LIST_HEAD(&dummy_zero_addr.host_list);
- INIT_LIST_HEAD(&dummy_zero_addr.hl_list);
- INIT_LIST_HEAD(&dummy_max_addr.host_list);
- INIT_LIST_HEAD(&dummy_max_addr.hl_list);
+ INIT_LIST_HEAD(&host->dummy_zero_addr.host_list);
+ INIT_LIST_HEAD(&host->dummy_zero_addr.hl_list);
+ INIT_LIST_HEAD(&host->dummy_max_addr.host_list);
+ INIT_LIST_HEAD(&host->dummy_max_addr.hl_list);
- dummy_zero_addr.op = dummy_max_addr.op = &dummy_ops;
+ host->dummy_zero_addr.op = host->dummy_max_addr.op = &dummy_ops;
- dummy_zero_addr.start = dummy_zero_addr.end = 0;
- dummy_max_addr.start = dummy_max_addr.end = ((u64) 1) << 48;
+ host->dummy_zero_addr.start = host->dummy_zero_addr.end = 0;
+ host->dummy_max_addr.start = host->dummy_max_addr.end = ((u64) 1) << 48;
- list_add_tail(&dummy_zero_addr.host_list, &host->addr_space);
- list_add_tail(&dummy_max_addr.host_list, &host->addr_space);
+ list_add_tail(&host->dummy_zero_addr.host_list, &host->addr_space);
+ list_add_tail(&host->dummy_max_addr.host_list, &host->addr_space);
}
void highlevel_add_host(struct hpsb_host *host)
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index 8dd09d850419..237d0c9d69c6 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -155,11 +155,11 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
h->device.parent = dev;
set_dev_node(&h->device, dev_to_node(dev));
- snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
+ dev_set_name(&h->device, "fw-host%d", h->id);
h->host_dev.parent = &h->device;
h->host_dev.class = &hpsb_host_class;
- snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
+ dev_set_name(&h->host_dev, "fw-host%d", h->id);
if (device_register(&h->device))
goto fail;
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index e4e8aeb4d778..dd229950acca 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -13,6 +13,7 @@ struct module;
#include "ieee1394_types.h"
#include "csr.h"
+#include "highlevel.h"
struct hpsb_packet;
struct hpsb_iso;
@@ -72,6 +73,9 @@ struct hpsb_host {
struct { DECLARE_BITMAP(map, 64); } tl_pool[ALL_NODES];
struct csr_control csr;
+
+ struct hpsb_address_serve dummy_zero_addr;
+ struct hpsb_address_serve dummy_max_addr;
};
enum devctl_cmd {
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 2376b729e876..79ef5fd928ae 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -115,8 +115,14 @@ static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
return error;
}
+#define OUI_FREECOM_TECHNOLOGIES_GMBH 0x0001db
+
static int nodemgr_get_max_rom(quadlet_t *bus_info_data, void *__ci)
{
+ /* Freecom FireWire Hard Drive firmware bug */
+ if (be32_to_cpu(bus_info_data[3]) >> 8 == OUI_FREECOM_TECHNOLOGIES_GMBH)
+ return 0;
+
return (be32_to_cpu(bus_info_data[2]) >> 8) & 0x3;
}
@@ -826,13 +832,11 @@ static struct node_entry *nodemgr_create_node(octlet_t guid,
memcpy(&ne->device, &nodemgr_dev_template_ne,
sizeof(ne->device));
ne->device.parent = &host->device;
- snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
- (unsigned long long)(ne->guid));
+ dev_set_name(&ne->device, "%016Lx", (unsigned long long)(ne->guid));
ne->node_dev.parent = &ne->device;
ne->node_dev.class = &nodemgr_ne_class;
- snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx",
- (unsigned long long)(ne->guid));
+ dev_set_name(&ne->node_dev, "%016Lx", (unsigned long long)(ne->guid));
if (device_register(&ne->device))
goto fail_devreg;
@@ -932,13 +936,11 @@ static void nodemgr_register_device(struct node_entry *ne,
ud->device.parent = parent;
- snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
- ne->device.bus_id, ud->id);
+ dev_set_name(&ud->device, "%s-%u", dev_name(&ne->device), ud->id);
ud->unit_dev.parent = &ud->device;
ud->unit_dev.class = &nodemgr_ud_class;
- snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u",
- ne->device.bus_id, ud->id);
+ dev_set_name(&ud->unit_dev, "%s-%u", dev_name(&ne->device), ud->id);
if (device_register(&ud->device))
goto fail_devreg;
@@ -953,7 +955,7 @@ static void nodemgr_register_device(struct node_entry *ne,
fail_classdevreg:
device_unregister(&ud->device);
fail_devreg:
- HPSB_ERR("Failed to create unit %s", ud->device.bus_id);
+ HPSB_ERR("Failed to create unit %s", dev_name(&ud->device));
}
@@ -1689,6 +1691,7 @@ static int nodemgr_host_thread(void *data)
g = get_hpsb_generation(host);
for (i = 0; i < 4 ; i++) {
msleep_interruptible(63);
+ try_to_freeze();
if (kthread_should_stop())
goto exit;
@@ -1729,6 +1732,7 @@ static int nodemgr_host_thread(void *data)
/* Sleep 3 seconds */
for (i = 3000/200; i; i--) {
msleep_interruptible(200);
+ try_to_freeze();
if (kthread_should_stop())
goto exit;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 9f19ac492106..bf7e761c12b1 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2268,7 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
return -EFAULT;
}
- mutex_lock(&fi->state_mutex);
+ if (!mutex_trylock(&fi->state_mutex))
+ return -EAGAIN;
switch (fi->state) {
case opened:
@@ -2548,7 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
struct file_info *fi = file->private_data;
int ret;
- mutex_lock(&fi->state_mutex);
+ if (!mutex_trylock(&fi->state_mutex))
+ return -EAGAIN;
if (fi->iso_state == RAW1394_ISO_INACTIVE)
ret = -EINVAL;
@@ -2669,7 +2671,8 @@ static long raw1394_ioctl(struct file *file, unsigned int cmd,
break;
}
- mutex_lock(&fi->state_mutex);
+ if (!mutex_trylock(&fi->state_mutex))
+ return -EAGAIN;
switch (fi->iso_state) {
case RAW1394_ISO_INACTIVE:
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index c52f6e6e8af2..a373c18cf7b8 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -402,6 +402,11 @@ static const struct {
},
/* iPod mini */ {
.firmware_revision = 0x0a2700,
+ .model_id = 0x000022,
+ .workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
+ },
+ /* iPod mini */ {
+ .firmware_revision = 0x0a2700,
.model_id = 0x000023,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
@@ -890,12 +895,13 @@ static void sbp2_host_reset(struct hpsb_host *host)
return;
read_lock_irqsave(&sbp2_hi_logical_units_lock, flags);
+
list_for_each_entry(lu, &hi->logical_units, lu_list)
- if (likely(atomic_read(&lu->state) !=
- SBP2LU_STATE_IN_SHUTDOWN)) {
- atomic_set(&lu->state, SBP2LU_STATE_IN_RESET);
+ if (atomic_cmpxchg(&lu->state,
+ SBP2LU_STATE_RUNNING, SBP2LU_STATE_IN_RESET)
+ == SBP2LU_STATE_RUNNING)
scsi_block_requests(lu->shost);
- }
+
read_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags);
}