summaryrefslogtreecommitdiff
path: root/drivers/ieee1394
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/csr1212.c32
-rw-r--r--drivers/ieee1394/dma.c2
-rw-r--r--drivers/ieee1394/dv1394.c7
-rw-r--r--drivers/ieee1394/highlevel.c4
-rw-r--r--drivers/ieee1394/highlevel.h13
-rw-r--r--drivers/ieee1394/nodemgr.c23
-rw-r--r--drivers/ieee1394/raw1394.c24
-rw-r--r--drivers/ieee1394/sbp2.c22
-rw-r--r--drivers/ieee1394/sbp2.h1
-rw-r--r--drivers/ieee1394/video1394.c8
10 files changed, 98 insertions, 38 deletions
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index e8122def164d..9f95337139e3 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -1049,6 +1049,24 @@ int csr1212_read(struct csr1212_csr *csr, u32 offset, void *buffer, u32 len)
return -ENOENT;
}
+/*
+ * Apparently there are many different wrong implementations of the CRC
+ * algorithm. We don't fail, we just warn... approximately once per GUID.
+ */
+static void
+csr1212_check_crc(const u32 *buffer, size_t length, u16 crc, __be32 *guid)
+{
+ static u64 last_bad_eui64;
+ u64 eui64 = ((u64)be32_to_cpu(guid[0]) << 32) | be32_to_cpu(guid[1]);
+
+ if (csr1212_crc16(buffer, length) == crc ||
+ csr1212_msft_crc16(buffer, length) == crc ||
+ eui64 == last_bad_eui64)
+ return;
+
+ printk(KERN_DEBUG "ieee1394: config ROM CRC error\n");
+ last_bad_eui64 = eui64;
+}
/* Parse a chunk of data as a Config ROM */
@@ -1092,11 +1110,8 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
return ret;
}
- /* Apparently there are many different wrong implementations of the CRC
- * algorithm. We don't fail, we just warn. */
- if ((csr1212_crc16(bi->data, bi->crc_length) != bi->crc) &&
- (csr1212_msft_crc16(bi->data, bi->crc_length) != bi->crc))
- printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n");
+ csr1212_check_crc(bi->data, bi->crc_length, bi->crc,
+ &csr->bus_info_data[3]);
cr = CSR1212_MALLOC(sizeof(*cr));
if (!cr)
@@ -1205,11 +1220,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv,
&cache->data[bytes_to_quads(kv->offset - cache->offset)];
kvi_len = be16_to_cpu(kvi->length);
- /* Apparently there are many different wrong implementations of the CRC
- * algorithm. We don't fail, we just warn. */
- if ((csr1212_crc16(kvi->data, kvi_len) != kvi->crc) &&
- (csr1212_msft_crc16(kvi->data, kvi_len) != kvi->crc))
- printk(KERN_DEBUG "IEEE 1394 device has ROM CRC error\n");
+ /* GUID is wrong in here in case of extended ROM. We don't care. */
+ csr1212_check_crc(kvi->data, kvi_len, kvi->crc, &cache->data[3]);
switch (kv->key.type) {
case CSR1212_KV_TYPE_DIRECTORY:
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 73685e7dc7e4..1aba8c13fe8f 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -274,7 +274,7 @@ int dma_region_mmap(struct dma_region *dma, struct file *file,
vma->vm_ops = &dma_region_vm_ops;
vma->vm_private_data = dma;
vma->vm_file = file;
- vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_RESERVED | VM_ALWAYSDUMP;
return 0;
}
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 9d19aec5820a..b6eb2cf25914 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2296,9 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
- device_create(hpsb_protocol_class, NULL, MKDEV(
- IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
- "dv1394-%d", id);
+ device_create_drvdata(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR,
+ IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL,
+ "dv1394-%d", id);
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
index fa2bfec0fca2..918ffc4fc8ac 100644
--- a/drivers/ieee1394/highlevel.c
+++ b/drivers/ieee1394/highlevel.c
@@ -228,10 +228,8 @@ void hpsb_register_highlevel(struct hpsb_highlevel *hl)
{
unsigned long flags;
+ hpsb_init_highlevel(hl);
INIT_LIST_HEAD(&hl->addr_list);
- INIT_LIST_HEAD(&hl->host_info_list);
-
- rwlock_init(&hl->host_info_lock);
down_write(&hl_drivers_sem);
list_add_tail(&hl->hl_list, &hl_drivers);
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h
index eb9fe321e09a..bc5d0854c17e 100644
--- a/drivers/ieee1394/highlevel.h
+++ b/drivers/ieee1394/highlevel.h
@@ -2,7 +2,7 @@
#define IEEE1394_HIGHLEVEL_H
#include <linux/list.h>
-#include <linux/spinlock_types.h>
+#include <linux/spinlock.h>
#include <linux/types.h>
struct module;
@@ -103,6 +103,17 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
void *data, size_t length);
+/**
+ * hpsb_init_highlevel - initialize a struct hpsb_highlevel
+ *
+ * This is only necessary if hpsb_get_hostinfo_bykey can be called
+ * before hpsb_register_highlevel.
+ */
+static inline void hpsb_init_highlevel(struct hpsb_highlevel *hl)
+{
+ rwlock_init(&hl->host_info_lock);
+ INIT_LIST_HEAD(&hl->host_info_list);
+}
void hpsb_register_highlevel(struct hpsb_highlevel *hl);
void hpsb_unregister_highlevel(struct hpsb_highlevel *hl);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 05710c7c1220..994a21e5a0aa 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -754,7 +754,8 @@ static void nodemgr_remove_uds(struct node_entry *ne)
*/
mutex_lock(&nodemgr_serialize_remove_uds);
for (;;) {
- dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
+ dev = class_find_device(&nodemgr_ud_class, NULL, ne,
+ __match_ne);
if (!dev)
break;
ud = container_of(dev, struct unit_directory, unit_dev);
@@ -901,7 +902,8 @@ static struct node_entry *find_entry_by_guid(u64 guid)
struct device *dev;
struct node_entry *ne;
- dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
+ dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
+ __match_ne_guid);
if (!dev)
return NULL;
ne = container_of(dev, struct node_entry, node_dev);
@@ -940,7 +942,8 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
param.host = host;
param.nodeid = nodeid;
- dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
+ dev = class_find_device(&nodemgr_ne_class, NULL, &param,
+ __match_ne_nodeid);
if (!dev)
return NULL;
ne = container_of(dev, struct node_entry, node_dev);
@@ -1453,7 +1456,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
ne->in_limbo = 1;
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend);
+ class_for_each_device(&nodemgr_ud_class, NULL, ne,
+ __nodemgr_driver_suspend);
}
@@ -1462,7 +1466,8 @@ static void nodemgr_resume_ne(struct node_entry *ne)
ne->in_limbo = 0;
device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume);
+ class_for_each_device(&nodemgr_ud_class, NULL, ne,
+ __nodemgr_driver_resume);
HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
}
@@ -1498,7 +1503,8 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
static void nodemgr_update_pdrv(struct node_entry *ne)
{
- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
+ class_for_each_device(&nodemgr_ud_class, NULL, ne,
+ __nodemgr_update_pdrv);
}
@@ -1591,7 +1597,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
* while probes are time-consuming. (Well, those probes need some
* improvement...) */
- class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
+ class_for_each_device(&nodemgr_ne_class, NULL, &param,
+ __nodemgr_node_probe);
/* If we had a bus reset while we were scanning the bus, it is
* possible that we did not probe all nodes. In that case, we
@@ -1826,7 +1833,7 @@ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
hip.cb = cb;
hip.data = data;
- error = class_for_each_device(&hpsb_host_class, &hip,
+ error = class_for_each_device(&hpsb_host_class, NULL, &hip,
__nodemgr_for_each_host);
return error;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index ec2a0adbedb2..6fa9e4a21840 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2549,8 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
}
/* ioctl is only used for rawiso operations */
-static int raw1394_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct file_info *fi = file->private_data;
void __user *argp = (void __user *)arg;
@@ -2656,6 +2656,16 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
+static long raw1394_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret;
+ lock_kernel();
+ ret = do_raw1394_ioctl(file, cmd, arg);
+ unlock_kernel();
+ return ret;
+}
+
#ifdef CONFIG_COMPAT
struct raw1394_iso_packets32 {
__u32 n_packets;
@@ -2690,7 +2700,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
!copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
infos = compat_ptr(infos32);
if (!copy_to_user(&dst->infos, &infos, sizeof infos))
- err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
+ err = do_raw1394_ioctl(file, cmd, (unsigned long)dst);
}
return err;
}
@@ -2731,7 +2741,7 @@ static long raw1394_compat_ioctl(struct file *file,
case RAW1394_IOC_ISO_GET_STATUS:
case RAW1394_IOC_ISO_SHUTDOWN:
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
- err = raw1394_ioctl(NULL, file, cmd, arg);
+ err = do_raw1394_ioctl(file, cmd, arg);
break;
/* These request have different format. */
case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2984,7 +2994,7 @@ static const struct file_operations raw1394_fops = {
.read = raw1394_read,
.write = raw1394_write,
.mmap = raw1394_mmap,
- .ioctl = raw1394_ioctl,
+ .unlocked_ioctl = raw1394_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = raw1394_compat_ioctl,
#endif
@@ -3000,10 +3010,10 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
if (IS_ERR
- (device_create(
+ (device_create_drvdata(
hpsb_protocol_class, NULL,
MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
- RAW1394_DEVICE_NAME))) {
+ NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
goto out_unreg;
}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index a5ceff287a28..9cbf3154d243 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -186,6 +186,11 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
* - delay inquiry
* Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
*
+ * - power condition
+ * Set the power condition field in the START STOP UNIT commands sent by
+ * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on).
+ * Some disks need this to spin down or to resume properly.
+ *
* - override internal blacklist
* Instead of adding to the built-in blacklist, use only the workarounds
* specified in the module load parameter.
@@ -199,6 +204,8 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
+ ", set power condition in start stop unit = "
+ __stringify(SBP2_WORKAROUND_POWER_CONDITION)
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
@@ -359,18 +366,25 @@ static const struct {
.firmware_revision = 0x002800,
.model_id = 0x001010,
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
- SBP2_WORKAROUND_MODE_SENSE_8,
+ SBP2_WORKAROUND_MODE_SENSE_8 |
+ SBP2_WORKAROUND_POWER_CONDITION,
},
/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
.firmware_revision = 0x002800,
.model_id = 0x000000,
- .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY |
+ SBP2_WORKAROUND_POWER_CONDITION,
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
.model_id = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
+ /* PL-3507 bridge with Prolific firmware */ {
+ .firmware_revision = 0x012800,
+ .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .workarounds = SBP2_WORKAROUND_POWER_CONDITION,
+ },
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
.model_id = SBP2_ROM_VALUE_WILDCARD,
@@ -1995,6 +2009,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
sdev->use_10_for_rw = 1;
+ if (sbp2_exclusive_login)
+ sdev->manage_start_stop = 1;
if (sdev->type == TYPE_ROM)
sdev->use_10_for_ms = 1;
if (sdev->type == TYPE_DISK &&
@@ -2002,6 +2018,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
sdev->skip_ms_page_8 = 1;
if (lu->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
sdev->fix_capacity = 1;
+ if (lu->workarounds & SBP2_WORKAROUND_POWER_CONDITION)
+ sdev->start_stop_pwr_cond = 1;
if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
return 0;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index 80d8e097b065..875428bc8d29 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -345,6 +345,7 @@ enum sbp2lu_state_types {
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
#define SBP2_INQUIRY_DELAY 12
+#define SBP2_WORKAROUND_POWER_CONDITION 0x20
#define SBP2_WORKAROUND_OVERRIDE 0x100
#endif /* SBP2_H */
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index e24772d336e1..25db6e67fa4e 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1341,9 +1341,9 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
- device_create(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, minor),
- "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+ device_create_drvdata(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR, minor), NULL,
+ "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
@@ -1503,6 +1503,8 @@ static int __init video1394_init_module (void)
{
int ret;
+ hpsb_init_highlevel(&video1394_highlevel);
+
cdev_init(&video1394_cdev, &video1394_fops);
video1394_cdev.owner = THIS_MODULE;
ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16);