aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:49:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:49:48 -0400
commit441c196e84b11aad3123baa9320eee7abc6b5c98 (patch)
treeea51d689c9ac09cce10a5758f19d6adbd8a7a9d7 /drivers/firewire
parent951cc93a7493a81a47e20231441bc6cf17c98a37 (diff)
parent9a00c24ae7cb08dcd46edf1327a47871e8466444 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: firewire: document the sysfs ABIs firewire: cdev: ABI documentation enhancements firewire: cdev: prevent race between first get_info ioctl and bus reset event queuing firewire: cdev: return -ENOTTY for unimplemented ioctls, not -EINVAL firewire: ohci: skip soft reset retries after card ejection firewire: ohci: fix PHY reg access after card ejection firewire: ohci: add a comment on PHY reg access serialization firewire: ohci: reduce potential context_stop latency firewire: ohci: remove superfluous posted write flushes firewire: net: replacing deprecated __attribute__((packed)) with __packed
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-cdev.c20
-rw-r--r--drivers/firewire/net.c5
-rw-r--r--drivers/firewire/ohci.c42
3 files changed, 41 insertions, 26 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index b1c11775839c..e6ad3bb6c1a6 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -253,14 +253,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
253 init_waitqueue_head(&client->wait); 253 init_waitqueue_head(&client->wait);
254 init_waitqueue_head(&client->tx_flush_wait); 254 init_waitqueue_head(&client->tx_flush_wait);
255 INIT_LIST_HEAD(&client->phy_receiver_link); 255 INIT_LIST_HEAD(&client->phy_receiver_link);
256 INIT_LIST_HEAD(&client->link);
256 kref_init(&client->kref); 257 kref_init(&client->kref);
257 258
258 file->private_data = client; 259 file->private_data = client;
259 260
260 mutex_lock(&device->client_list_mutex);
261 list_add_tail(&client->link, &device->client_list);
262 mutex_unlock(&device->client_list_mutex);
263
264 return nonseekable_open(inode, file); 261 return nonseekable_open(inode, file);
265} 262}
266 263
@@ -451,15 +448,20 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
451 if (ret != 0) 448 if (ret != 0)
452 return -EFAULT; 449 return -EFAULT;
453 450
451 mutex_lock(&client->device->client_list_mutex);
452
454 client->bus_reset_closure = a->bus_reset_closure; 453 client->bus_reset_closure = a->bus_reset_closure;
455 if (a->bus_reset != 0) { 454 if (a->bus_reset != 0) {
456 fill_bus_reset_event(&bus_reset, client); 455 fill_bus_reset_event(&bus_reset, client);
457 if (copy_to_user(u64_to_uptr(a->bus_reset), 456 ret = copy_to_user(u64_to_uptr(a->bus_reset),
458 &bus_reset, sizeof(bus_reset))) 457 &bus_reset, sizeof(bus_reset));
459 return -EFAULT;
460 } 458 }
459 if (ret == 0 && list_empty(&client->link))
460 list_add_tail(&client->link, &client->device->client_list);
461 461
462 return 0; 462 mutex_unlock(&client->device->client_list_mutex);
463
464 return ret ? -EFAULT : 0;
463} 465}
464 466
465static int add_client_resource(struct client *client, 467static int add_client_resource(struct client *client,
@@ -1583,7 +1585,7 @@ static int dispatch_ioctl(struct client *client,
1583 if (_IOC_TYPE(cmd) != '#' || 1585 if (_IOC_TYPE(cmd) != '#' ||
1584 _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || 1586 _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
1585 _IOC_SIZE(cmd) > sizeof(buffer)) 1587 _IOC_SIZE(cmd) > sizeof(buffer))
1586 return -EINVAL; 1588 return -ENOTTY;
1587 1589
1588 if (_IOC_DIR(cmd) == _IOC_READ) 1590 if (_IOC_DIR(cmd) == _IOC_READ)
1589 memset(&buffer, 0, _IOC_SIZE(cmd)); 1591 memset(&buffer, 0, _IOC_SIZE(cmd));
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index eced1c25bf58..03a7a85d0424 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/bug.h> 9#include <linux/bug.h>
10#include <linux/compiler.h>
10#include <linux/delay.h> 11#include <linux/delay.h>
11#include <linux/device.h> 12#include <linux/device.h>
12#include <linux/ethtool.h> 13#include <linux/ethtool.h>
@@ -73,7 +74,7 @@ struct rfc2734_arp {
73 __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */ 74 __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
74 __be32 sip; /* Sender's IP Address */ 75 __be32 sip; /* Sender's IP Address */
75 __be32 tip; /* IP Address of requested hw addr */ 76 __be32 tip; /* IP Address of requested hw addr */
76} __attribute__((packed)); 77} __packed;
77 78
78/* This header format is specific to this driver implementation. */ 79/* This header format is specific to this driver implementation. */
79#define FWNET_ALEN 8 80#define FWNET_ALEN 8
@@ -81,7 +82,7 @@ struct rfc2734_arp {
81struct fwnet_header { 82struct fwnet_header {
82 u8 h_dest[FWNET_ALEN]; /* destination address */ 83 u8 h_dest[FWNET_ALEN]; /* destination address */
83 __be16 h_proto; /* packet type ID field */ 84 __be16 h_proto; /* packet type ID field */
84} __attribute__((packed)); 85} __packed;
85 86
86/* IPv4 and IPv6 encapsulation header */ 87/* IPv4 and IPv6 encapsulation header */
87struct rfc2734_header { 88struct rfc2734_header {
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index ebb897329c1e..bcf792fac442 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -253,7 +253,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
253#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 253#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
254 254
255#define OHCI1394_REGISTER_SIZE 0x800 255#define OHCI1394_REGISTER_SIZE 0x800
256#define OHCI_LOOP_COUNT 500
257#define OHCI1394_PCI_HCI_Control 0x40 256#define OHCI1394_PCI_HCI_Control 0x40
258#define SELF_ID_BUF_SIZE 0x800 257#define SELF_ID_BUF_SIZE 0x800
259#define OHCI_TCODE_PHY_PACKET 0x0e 258#define OHCI_TCODE_PHY_PACKET 0x0e
@@ -514,6 +513,12 @@ static inline void flush_writes(const struct fw_ohci *ohci)
514 reg_read(ohci, OHCI1394_Version); 513 reg_read(ohci, OHCI1394_Version);
515} 514}
516 515
516/*
517 * Beware! read_phy_reg(), write_phy_reg(), update_phy_reg(), and
518 * read_paged_phy_reg() require the caller to hold ohci->phy_reg_mutex.
519 * In other words, only use ohci_read_phy_reg() and ohci_update_phy_reg()
520 * directly. Exceptions are intrinsically serialized contexts like pci_probe.
521 */
517static int read_phy_reg(struct fw_ohci *ohci, int addr) 522static int read_phy_reg(struct fw_ohci *ohci, int addr)
518{ 523{
519 u32 val; 524 u32 val;
@@ -522,6 +527,9 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr)
522 reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); 527 reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr));
523 for (i = 0; i < 3 + 100; i++) { 528 for (i = 0; i < 3 + 100; i++) {
524 val = reg_read(ohci, OHCI1394_PhyControl); 529 val = reg_read(ohci, OHCI1394_PhyControl);
530 if (!~val)
531 return -ENODEV; /* Card was ejected. */
532
525 if (val & OHCI1394_PhyControl_ReadDone) 533 if (val & OHCI1394_PhyControl_ReadDone)
526 return OHCI1394_PhyControl_ReadData(val); 534 return OHCI1394_PhyControl_ReadData(val);
527 535
@@ -545,6 +553,9 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val)
545 OHCI1394_PhyControl_Write(addr, val)); 553 OHCI1394_PhyControl_Write(addr, val));
546 for (i = 0; i < 3 + 100; i++) { 554 for (i = 0; i < 3 + 100; i++) {
547 val = reg_read(ohci, OHCI1394_PhyControl); 555 val = reg_read(ohci, OHCI1394_PhyControl);
556 if (!~val)
557 return -ENODEV; /* Card was ejected. */
558
548 if (!(val & OHCI1394_PhyControl_WritePending)) 559 if (!(val & OHCI1394_PhyControl_WritePending))
549 return 0; 560 return 0;
550 561
@@ -630,7 +641,6 @@ static void ar_context_link_page(struct ar_context *ctx, unsigned int index)
630 ctx->last_buffer_index = index; 641 ctx->last_buffer_index = index;
631 642
632 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); 643 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
633 flush_writes(ctx->ohci);
634} 644}
635 645
636static void ar_context_release(struct ar_context *ctx) 646static void ar_context_release(struct ar_context *ctx)
@@ -1002,7 +1012,6 @@ static void ar_context_run(struct ar_context *ctx)
1002 1012
1003 reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1); 1013 reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1);
1004 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); 1014 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
1005 flush_writes(ctx->ohci);
1006} 1015}
1007 1016
1008static struct descriptor *find_branch_descriptor(struct descriptor *d, int z) 1017static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
@@ -1202,14 +1211,14 @@ static void context_stop(struct context *ctx)
1202 1211
1203 reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); 1212 reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
1204 ctx->running = false; 1213 ctx->running = false;
1205 flush_writes(ctx->ohci);
1206 1214
1207 for (i = 0; i < 10; i++) { 1215 for (i = 0; i < 1000; i++) {
1208 reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); 1216 reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
1209 if ((reg & CONTEXT_ACTIVE) == 0) 1217 if ((reg & CONTEXT_ACTIVE) == 0)
1210 return; 1218 return;
1211 1219
1212 mdelay(1); 1220 if (i)
1221 udelay(10);
1213 } 1222 }
1214 fw_error("Error: DMA context still active (0x%08x)\n", reg); 1223 fw_error("Error: DMA context still active (0x%08x)\n", reg);
1215} 1224}
@@ -1346,12 +1355,10 @@ static int at_context_queue_packet(struct context *ctx,
1346 1355
1347 context_append(ctx, d, z, 4 - z); 1356 context_append(ctx, d, z, 4 - z);
1348 1357
1349 if (ctx->running) { 1358 if (ctx->running)
1350 reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); 1359 reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
1351 flush_writes(ohci); 1360 else
1352 } else {
1353 context_run(ctx, 0); 1361 context_run(ctx, 0);
1354 }
1355 1362
1356 return 0; 1363 return 0;
1357} 1364}
@@ -1960,14 +1967,18 @@ static irqreturn_t irq_handler(int irq, void *data)
1960 1967
1961static int software_reset(struct fw_ohci *ohci) 1968static int software_reset(struct fw_ohci *ohci)
1962{ 1969{
1970 u32 val;
1963 int i; 1971 int i;
1964 1972
1965 reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); 1973 reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
1974 for (i = 0; i < 500; i++) {
1975 val = reg_read(ohci, OHCI1394_HCControlSet);
1976 if (!~val)
1977 return -ENODEV; /* Card was ejected. */
1966 1978
1967 for (i = 0; i < OHCI_LOOP_COUNT; i++) { 1979 if (!(val & OHCI1394_HCControl_softReset))
1968 if ((reg_read(ohci, OHCI1394_HCControlSet) &
1969 OHCI1394_HCControl_softReset) == 0)
1970 return 0; 1980 return 0;
1981
1971 msleep(1); 1982 msleep(1);
1972 } 1983 }
1973 1984
@@ -2197,7 +2208,9 @@ static int ohci_enable(struct fw_card *card,
2197 OHCI1394_LinkControl_rcvPhyPkt); 2208 OHCI1394_LinkControl_rcvPhyPkt);
2198 2209
2199 ar_context_run(&ohci->ar_request_ctx); 2210 ar_context_run(&ohci->ar_request_ctx);
2200 ar_context_run(&ohci->ar_response_ctx); /* also flushes writes */ 2211 ar_context_run(&ohci->ar_response_ctx);
2212
2213 flush_writes(ohci);
2201 2214
2202 /* We are ready to go, reset bus to finish initialization. */ 2215 /* We are ready to go, reset bus to finish initialization. */
2203 fw_schedule_bus_reset(&ohci->card, false, true); 2216 fw_schedule_bus_reset(&ohci->card, false, true);
@@ -3129,7 +3142,6 @@ static void ohci_flush_queue_iso(struct fw_iso_context *base)
3129 &container_of(base, struct iso_context, base)->context; 3142 &container_of(base, struct iso_context, base)->context;
3130 3143
3131 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); 3144 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
3132 flush_writes(ctx->ohci);
3133} 3145}
3134 3146
3135static const struct fw_card_driver ohci_driver = { 3147static const struct fw_card_driver ohci_driver = {