diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firewire/fw-card.c | 32 | ||||
-rw-r--r-- | drivers/firewire/fw-device.c | 5 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 1 | ||||
-rw-r--r-- | drivers/firewire/fw-ohci.c | 1 | ||||
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 25 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.c | 32 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.h | 34 | ||||
-rw-r--r-- | drivers/ieee1394/csr1212.c | 32 | ||||
-rw-r--r-- | drivers/ieee1394/dma.c | 2 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.c | 4 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.h | 13 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.c | 20 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 22 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 1 | ||||
-rw-r--r-- | drivers/ieee1394/video1394.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs_mcast.c | 3 | ||||
-rw-r--r-- | drivers/net/macvlan.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 5 |
19 files changed, 177 insertions, 60 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 5b4c0d9f517..da873d795aa 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -16,12 +16,15 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <linux/module.h> -#include <linux/errno.h> +#include <linux/completion.h> +#include <linux/crc-itu-t.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/errno.h> +#include <linux/kref.h> +#include <linux/module.h> #include <linux/mutex.h> -#include <linux/crc-itu-t.h> + #include "fw-transaction.h" #include "fw-topology.h" #include "fw-device.h" @@ -396,14 +399,16 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, { static atomic_t index = ATOMIC_INIT(-1); - atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->driver = driver; card->device = device; card->current_tlabel = 0; card->tlabel_mask = 0; card->color = 0; + card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; + kref_init(&card->kref); + init_completion(&card->done); INIT_LIST_HEAD(&card->transaction_list); spin_lock_init(&card->lock); setup_timer(&card->flush_timer, @@ -496,7 +501,6 @@ dummy_enable_phys_dma(struct fw_card *card, } static struct fw_card_driver dummy_driver = { - .name = "dummy", .enable = dummy_enable, .update_phy_reg = dummy_update_phy_reg, .set_config_rom = dummy_set_config_rom, @@ -507,6 +511,14 @@ static struct fw_card_driver dummy_driver = { }; void +fw_card_release(struct kref *kref) +{ + struct fw_card *card = container_of(kref, struct fw_card, kref); + + complete(&card->done); +} + +void fw_core_remove_card(struct fw_card *card) { card->driver->update_phy_reg(card, 4, @@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; fw_destroy_nodes(card); - /* - * Wait for all device workqueue jobs to finish. Otherwise the - * firewire-core module could be unloaded before the jobs ran. - */ - while (atomic_read(&card->device_count) > 0) - msleep(100); + + /* Wait for all users, especially device workqueue jobs, to finish. */ + fw_card_put(card); + wait_for_completion(&card->done); cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index d9c8daf7ae7..0855fb5568e 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -168,7 +168,7 @@ static void fw_device_release(struct device *dev) fw_node_put(device->node); kfree(device->config_rom); kfree(device); - atomic_dec(&card->device_count); + fw_card_put(card); } int fw_device_enable_phys_dma(struct fw_device *device) @@ -946,8 +946,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); - atomic_inc(&card->device_count); - device->card = card; + device->card = fw_card_get(card); device->node = fw_node_get(node); device->node_id = node->node_id; device->generation = card->generation; diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 5f131f5129d..42305bbac72 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -62,7 +62,6 @@ struct fw_device { bool cmc; struct fw_card *card; struct device device; - struct list_head link; struct list_head client_list; u32 *config_rom; size_t config_rom_length; diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 0b66306af47..333b12544dd 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -2292,7 +2292,6 @@ ohci_queue_iso(struct fw_iso_context *base, } static const struct fw_card_driver ohci_driver = { - .name = ohci_driver_name, .enable = ohci_enable, .update_phy_reg = ohci_update_phy_reg, .set_config_rom = ohci_set_config_rom, diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 227d2e036cd..53fc5a641e6 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -86,6 +86,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. @@ -97,6 +102,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " #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 static int sbp2_param_workarounds; @@ -107,6 +113,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)"); @@ -310,18 +318,25 @@ static const struct { .firmware_revision = 0x002800, .model = 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 = 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 = ~0, .workarounds = SBP2_WORKAROUND_INQUIRY_36, }, + /* PL-3507 bridge with Prolific firmware */ { + .firmware_revision = 0x012800, + .model = ~0, + .workarounds = SBP2_WORKAROUND_POWER_CONDITION, + }, /* Symbios bridge */ { .firmware_revision = 0xa0b800, .model = ~0, @@ -1530,6 +1545,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) sdev->use_10_for_rw = 1; + if (sbp2_param_exclusive_login) + sdev->manage_start_stop = 1; + if (sdev->type == TYPE_ROM) sdev->use_10_for_ms = 1; @@ -1540,6 +1558,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) sdev->fix_capacity = 1; + if (lu->tgt->workarounds & SBP2_WORKAROUND_POWER_CONDITION) + sdev->start_stop_pwr_cond = 1; + if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 03ae8a77c47..40db8075227 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -55,6 +55,9 @@ #define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff) #define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff) +#define HEADER_DESTINATION_IS_BROADCAST(q) \ + (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f)) + #define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22)) #define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) #define PHY_IDENTIFIER(id) ((id) << 30) @@ -624,12 +627,9 @@ allocate_request(struct fw_packet *p) void fw_send_response(struct fw_card *card, struct fw_request *request, int rcode) { - /* - * Broadcast packets are reported as ACK_COMPLETE, so this - * check is sufficient to ensure we don't send response to - * broadcast packets or posted writes. - */ - if (request->ack != ACK_PENDING) { + /* unified transaction or broadcast transaction: don't respond */ + if (request->ack != ACK_PENDING || + HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { kfree(request); return; } @@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request, int reg = offset & ~CSR_REGISTER_BASE; unsigned long long bus_time; __be32 *data = payload; + int rcode = RCODE_COMPLETE; switch (reg) { case CSR_CYCLE_TIME: case CSR_BUS_TIME: if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { - fw_send_response(card, request, RCODE_TYPE_ERROR); + rcode = RCODE_TYPE_ERROR; break; } @@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request, *data = cpu_to_be32(bus_time); else *data = cpu_to_be32(bus_time >> 25); - fw_send_response(card, request, RCODE_COMPLETE); + break; + + case CSR_BROADCAST_CHANNEL: + if (tcode == TCODE_READ_QUADLET_REQUEST) + *data = cpu_to_be32(card->broadcast_channel); + else if (tcode == TCODE_WRITE_QUADLET_REQUEST) + card->broadcast_channel = + (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) | + BROADCAST_CHANNEL_INITIAL; + else + rcode = RCODE_TYPE_ERROR; break; case CSR_BUS_MANAGER_ID: @@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request, case CSR_BUSY_TIMEOUT: /* FIXME: Implement this. */ + default: - fw_send_response(card, request, RCODE_ADDRESS_ERROR); + rcode = RCODE_ADDRESS_ERROR; break; } + + fw_send_response(card, request, rcode); } static struct fw_address_handler registers = { diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 04d3854f656..2ae1b0d6cb7 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -19,14 +19,15 @@ #ifndef __fw_transaction_h #define __fw_transaction_h +#include <linux/completion.h> #include <linux/device.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/list.h> -#include <linux/fs.h> #include <linux/dma-mapping.h> #include <linux/firewire-constants.h> -#include <asm/atomic.h> +#include <linux/kref.h> +#include <linux/list.h> +#include <linux/spinlock_types.h> +#include <linux/timer.h> +#include <linux/workqueue.h> #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) @@ -80,6 +81,9 @@ #define CSR_SPEED_MAP 0x2000 #define CSR_SPEED_MAP_END 0x3000 +#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) +#define BROADCAST_CHANNEL_VALID (1 << 30) + #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) @@ -216,7 +220,8 @@ extern struct bus_type fw_bus_type; struct fw_card { const struct fw_card_driver *driver; struct device *device; - atomic_t device_count; + struct kref kref; + struct completion done; int node_id; int generation; @@ -236,6 +241,7 @@ struct fw_card { */ int self_id_count; u32 topology_map[252 + 3]; + u32 broadcast_channel; spinlock_t lock; /* Take this lock when handling the lists in * this struct. */ @@ -256,6 +262,20 @@ struct fw_card { int bm_generation; }; +static inline struct fw_card *fw_card_get(struct fw_card *card) +{ + kref_get(&card->kref); + + return card; +} + +void fw_card_release(struct kref *kref); + +static inline void fw_card_put(struct fw_card *card) +{ + kref_put(&card->kref, fw_card_release); +} + /* * The iso packet format allows for an immediate header/payload part * stored in 'header' immediately after the packet info plus an @@ -348,8 +368,6 @@ int fw_iso_context_stop(struct fw_iso_context *ctx); struct fw_card_driver { - const char *name; - /* * Enable the given card with the given initial config rom. * This function is expected to activate the card, and either diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c index e8122def164..9f95337139e 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 73685e7dc7e..1aba8c13fe8 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/highlevel.c b/drivers/ieee1394/highlevel.c index fa2bfec0fca..918ffc4fc8a 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 eb9fe321e09..bc5d0854c17 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/raw1394.c b/drivers/ieee1394/raw1394.c index ec2a0adbedb..96f2847b040 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 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index a5ceff287a2..9cbf3154d24 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 80d8e097b06..875428bc8d2 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 e24772d336e..069b9f6bf16 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -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); diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 9e23ab0b51a..55c71882882 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -35,6 +35,7 @@ #include <rdma/ib_user_verbs.h> #include <linux/io.h> #include <linux/utsname.h> +#include <linux/rculist.h> #include "ipath_kernel.h" #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c index 9e5abf9c309..d73e3223287 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c @@ -31,8 +31,7 @@ * SOFTWARE. */ -#include <linux/list.h> -#include <linux/rcupdate.h> +#include <linux/rculist.h> #include "ipath_verbs.h" diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c36a03ae9bf..860d75d81f8 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -20,7 +20,7 @@ #include <linux/errno.h> #include <linux/slab.h> #include <linux/string.h> -#include <linux/list.h> +#include <linux/rculist.h> #include <linux/notifier.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 01cefbb2d53..d53312c4254 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1124,6 +1124,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) cmd[1] = 1; /* Return immediately */ memset((void *) &cmd[2], 0, 8); cmd[4] = 1; /* Start spin cycle */ + if (sdkp->device->start_stop_pwr_cond) + cmd[4] |= 1 << 4; scsi_execute_req(sdkp->device, cmd, DMA_NONE, NULL, 0, &sshdr, SD_TIMEOUT, SD_MAX_RETRIES); @@ -1790,6 +1792,9 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) if (start) cmd[4] |= 1; /* START */ + if (sdp->start_stop_pwr_cond) + cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */ + if (!scsi_device_online(sdp)) return -ENODEV; |