diff options
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 14 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c | 4 | ||||
-rw-r--r-- | drivers/firewire/core-device.c | 2 | ||||
-rw-r--r-- | drivers/firewire/core-iso.c | 28 | ||||
-rw-r--r-- | drivers/firewire/core.h | 3 | ||||
-rw-r--r-- | drivers/firewire/net.c | 6 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 14 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 18 |
8 files changed, 57 insertions, 32 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 543fccac81bb..f74edae5cb4c 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -196,8 +196,8 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) { int channel, bandwidth = 0; - fw_iso_resource_manage(card, generation, 1ULL << 31, - &channel, &bandwidth, true); + fw_iso_resource_manage(card, generation, 1ULL << 31, &channel, + &bandwidth, true, card->bm_transaction_data); if (channel == 31) { card->broadcast_channel_allocated = true; device_for_each_child(card->device, (void *)(long)generation, @@ -230,7 +230,6 @@ static void fw_card_bm_work(struct work_struct *work) bool do_reset = false; bool root_device_is_running; bool root_device_is_cmc; - __be32 lock_data[2]; spin_lock_irqsave(&card->lock, flags); @@ -273,22 +272,23 @@ static void fw_card_bm_work(struct work_struct *work) goto pick_me; } - lock_data[0] = cpu_to_be32(0x3f); - lock_data[1] = cpu_to_be32(local_id); + card->bm_transaction_data[0] = cpu_to_be32(0x3f); + card->bm_transaction_data[1] = cpu_to_be32(local_id); spin_unlock_irqrestore(&card->lock, flags); rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, - lock_data, sizeof(lock_data)); + card->bm_transaction_data, + sizeof(card->bm_transaction_data)); if (rcode == RCODE_GENERATION) /* Another bus reset, BM work has been rescheduled. */ goto out; if (rcode == RCODE_COMPLETE && - lock_data[0] != cpu_to_be32(0x3f)) { + card->bm_transaction_data[0] != cpu_to_be32(0x3f)) { /* Somebody else is BM. Only act as IRM. */ if (local_id == irm_id) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index d1d30c615b0f..ced186d7e9a9 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -125,6 +125,7 @@ struct iso_resource { int generation; u64 channels; s32 bandwidth; + __be32 transaction_data[2]; struct iso_resource_event *e_alloc, *e_dealloc; }; @@ -1049,7 +1050,8 @@ static void iso_resource_work(struct work_struct *work) r->channels, &channel, &bandwidth, todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC || - todo == ISO_RES_ALLOC_ONCE); + todo == ISO_RES_ALLOC_ONCE, + r->transaction_data); /* * Is this generation outdated already? As long as this resource sticks * in the idr, it will be scheduled again for a newer generation or at diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 97e656af2d22..9d0dfcbe2c1c 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -312,7 +312,7 @@ static void init_fw_attribute_group(struct device *dev, group->groups[0] = &group->group; group->groups[1] = NULL; group->group.attrs = group->attrs; - dev->groups = group->groups; + dev->groups = (const struct attribute_group **) group->groups; } static ssize_t modalias_show(struct device *dev, diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 166f19c6d38d..1c0b504a42f3 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -177,9 +177,8 @@ EXPORT_SYMBOL(fw_iso_context_stop); */ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, - int bandwidth, bool allocate) + int bandwidth, bool allocate, __be32 data[2]) { - __be32 data[2]; int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; /* @@ -197,7 +196,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, - data, sizeof(data))) { + data, 8)) { case RCODE_GENERATION: /* A generation change frees all bandwidth. */ return allocate ? -EAGAIN : bandwidth; @@ -215,9 +214,9 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, } static int manage_channel(struct fw_card *card, int irm_id, int generation, - u32 channels_mask, u64 offset, bool allocate) + u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) { - __be32 data[2], c, all, old; + __be32 c, all, old; int i, retry = 5; old = all = allocate ? cpu_to_be32(~0) : 0; @@ -234,7 +233,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, data[1] = old ^ c; switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, - offset, data, sizeof(data))) { + offset, data, 8)) { case RCODE_GENERATION: /* A generation change frees all channels. */ return allocate ? -EAGAIN : i; @@ -260,7 +259,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, } static void deallocate_channel(struct fw_card *card, int irm_id, - int generation, int channel) + int generation, int channel, __be32 buffer[2]) { u32 mask; u64 offset; @@ -269,7 +268,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; - manage_channel(card, irm_id, generation, mask, offset, false); + manage_channel(card, irm_id, generation, mask, offset, false, buffer); } /** @@ -298,7 +297,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, */ void fw_iso_resource_manage(struct fw_card *card, int generation, u64 channels_mask, int *channel, int *bandwidth, - bool allocate) + bool allocate, __be32 buffer[2]) { u32 channels_hi = channels_mask; /* channels 31...0 */ u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ @@ -310,10 +309,12 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, if (channels_hi) c = manage_channel(card, irm_id, generation, channels_hi, - CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate); + CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, + allocate, buffer); if (channels_lo && c < 0) { c = manage_channel(card, irm_id, generation, channels_lo, - CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate); + CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, + allocate, buffer); if (c >= 0) c += 32; } @@ -325,12 +326,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, if (*bandwidth == 0) return; - ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate); + ret = manage_bandwidth(card, irm_id, generation, *bandwidth, + allocate, buffer); if (ret < 0) *bandwidth = 0; if (allocate && ret < 0 && c >= 0) { - deallocate_channel(card, irm_id, generation, c); + deallocate_channel(card, irm_id, generation, c, buffer); *channel = ret; } } diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index c3cfc647e5e3..6052816be353 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -120,7 +120,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event); int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); void fw_iso_resource_manage(struct fw_card *card, int generation, - u64 channels_mask, int *channel, int *bandwidth, bool allocate); + u64 channels_mask, int *channel, int *bandwidth, + bool allocate, __be32 buffer[2]); /* -topology */ diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index a42209a73aed..cbaf420c36c5 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -663,8 +663,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, if (netif_queue_stopped(net)) netif_wake_queue(net); - net->last_rx = jiffies; - return 0; } @@ -1188,7 +1186,7 @@ static int fwnet_stop(struct net_device *net) return 0; } -static int fwnet_tx(struct sk_buff *skb, struct net_device *net) +static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) { struct fwnet_header hdr_buf; struct fwnet_device *dev = netdev_priv(net); @@ -1342,7 +1340,7 @@ static void fwnet_get_drvinfo(struct net_device *net, strcpy(info->bus_info, "ieee1394"); } -static struct ethtool_ops fwnet_ethtool_ops = { +static const struct ethtool_ops fwnet_ethtool_ops = { .get_drvinfo = fwnet_get_drvinfo, }; diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index ecddd11b797a..76b321bb73f9 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/pci.h> +#include <linux/pci_ids.h> #include <linux/spinlock.h> #include <linux/string.h> @@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev) #define ohci_pmac_off(dev) #endif /* CONFIG_PPC_PMAC */ +#define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT +#define PCI_DEVICE_ID_AGERE_FW643 0x5901 + static int __devinit pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { @@ -2422,6 +2426,16 @@ static int __devinit pci_probe(struct pci_dev *dev, version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; + /* dual-buffer mode is broken if more than one IR context is active */ + if (dev->vendor == PCI_VENDOR_ID_AGERE && + dev->device == PCI_DEVICE_ID_AGERE_FW643) + ohci->use_dualbuffer = false; + + /* dual-buffer mode is broken */ + if (dev->vendor == PCI_VENDOR_ID_RICOH && + dev->device == PCI_DEVICE_ID_RICOH_R5C832) + ohci->use_dualbuffer = false; + /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ #if !defined(CONFIG_X86_32) /* dual-buffer mode is broken with descriptor addresses above 2G */ diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 24c45635376a..e5df822a8130 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -201,6 +201,12 @@ static struct fw_device *target_device(struct sbp2_target *tgt) #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ /* + * There is no transport protocol limit to the CDB length, but we implement + * a fixed length only. 16 bytes is enough for disks larger than 2 TB. + */ +#define SBP2_MAX_CDB_SIZE 16 + +/* * The default maximum s/g segment size of a FireWire controller is * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to * be quadlet-aligned, we set the length limit to 0xffff & ~3. @@ -312,7 +318,7 @@ struct sbp2_command_orb { struct sbp2_pointer next; struct sbp2_pointer data_descriptor; __be32 misc; - u8 command_block[12]; + u8 command_block[SBP2_MAX_CDB_SIZE]; } request; struct scsi_cmnd *cmd; scsi_done_fn_t done; @@ -450,12 +456,12 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, } spin_unlock_irqrestore(&card->lock, flags); - if (&orb->link != &lu->orb_list) + if (&orb->link != &lu->orb_list) { orb->callback(orb, &status); - else + kref_put(&orb->kref, free_orb); + } else { fw_error("status write for unknown orb\n"); - - kref_put(&orb->kref, free_orb); + } fw_send_response(card, request, RCODE_COMPLETE); } @@ -1146,6 +1152,8 @@ static int sbp2_probe(struct device *dev) if (fw_device_enable_phys_dma(device) < 0) goto fail_shost_put; + shost->max_cmd_len = SBP2_MAX_CDB_SIZE; + if (scsi_add_host(shost, &unit->device) < 0) goto fail_shost_put; |