diff options
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/csr1212.c | 32 | ||||
-rw-r--r-- | drivers/ieee1394/dma.c | 2 | ||||
-rw-r--r-- | drivers/ieee1394/dv1394.c | 7 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.c | 4 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.h | 13 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 23 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.c | 24 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 22 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 1 | ||||
-rw-r--r-- | drivers/ieee1394/video1394.c | 8 |
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, ¶m, __match_ne_nodeid); + dev = class_find_device(&nodemgr_ne_class, NULL, ¶m, + __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, ¶m, __nodemgr_node_probe); + class_for_each_device(&nodemgr_ne_class, NULL, ¶m, + __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); |