diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/firewire | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/Kconfig | 44 | ||||
-rw-r--r-- | drivers/firewire/core-card.c | 104 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c | 500 | ||||
-rw-r--r-- | drivers/firewire/core-device.c | 303 | ||||
-rw-r--r-- | drivers/firewire/core-iso.c | 20 | ||||
-rw-r--r-- | drivers/firewire/core-topology.c | 19 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c | 154 | ||||
-rw-r--r-- | drivers/firewire/core.h | 11 | ||||
-rw-r--r-- | drivers/firewire/net.c | 54 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 437 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 16 |
11 files changed, 885 insertions, 777 deletions
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 13efcd362072..a9371b36a9b9 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig | |||
@@ -1,5 +1,10 @@ | |||
1 | menu "IEEE 1394 (FireWire) support" | ||
2 | depends on PCI || BROKEN | ||
3 | # firewire-core does not depend on PCI but is | ||
4 | # not useful without PCI controller driver | ||
5 | |||
1 | comment "You can enable one or both FireWire driver stacks." | 6 | comment "You can enable one or both FireWire driver stacks." |
2 | comment "See the help texts for more information." | 7 | comment "The newer stack is recommended." |
3 | 8 | ||
4 | config FIREWIRE | 9 | config FIREWIRE |
5 | tristate "FireWire driver stack" | 10 | tristate "FireWire driver stack" |
@@ -15,16 +20,6 @@ config FIREWIRE | |||
15 | To compile this driver as a module, say M here: the module will be | 20 | To compile this driver as a module, say M here: the module will be |
16 | called firewire-core. | 21 | called firewire-core. |
17 | 22 | ||
18 | This module functionally replaces ieee1394, raw1394, and video1394. | ||
19 | To access it from application programs, you generally need at least | ||
20 | libraw1394 v2. IIDC/DCAM applications need libdc1394 v2. | ||
21 | No libraries are required to access storage devices through the | ||
22 | firewire-sbp2 driver. | ||
23 | |||
24 | NOTE: | ||
25 | FireWire audio devices currently require the old drivers (ieee1394, | ||
26 | ohci1394, raw1394). | ||
27 | |||
28 | config FIREWIRE_OHCI | 23 | config FIREWIRE_OHCI |
29 | tristate "OHCI-1394 controllers" | 24 | tristate "OHCI-1394 controllers" |
30 | depends on PCI && FIREWIRE | 25 | depends on PCI && FIREWIRE |
@@ -34,22 +29,7 @@ config FIREWIRE_OHCI | |||
34 | is the only chipset in use, so say Y here. | 29 | is the only chipset in use, so say Y here. |
35 | 30 | ||
36 | To compile this driver as a module, say M here: The module will be | 31 | To compile this driver as a module, say M here: The module will be |
37 | called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 | 32 | called firewire-ohci. |
38 | stack. | ||
39 | |||
40 | NOTE: | ||
41 | If you want to install firewire-ohci and ohci1394 together, you | ||
42 | should configure them only as modules and blacklist the driver(s) | ||
43 | which you don't want to have auto-loaded. Add either | ||
44 | |||
45 | blacklist firewire-ohci | ||
46 | or | ||
47 | blacklist ohci1394 | ||
48 | blacklist video1394 | ||
49 | blacklist dv1394 | ||
50 | |||
51 | to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf | ||
52 | depending on your distribution. | ||
53 | 33 | ||
54 | config FIREWIRE_OHCI_DEBUG | 34 | config FIREWIRE_OHCI_DEBUG |
55 | bool | 35 | bool |
@@ -66,8 +46,7 @@ config FIREWIRE_SBP2 | |||
66 | like scanners. | 46 | like scanners. |
67 | 47 | ||
68 | To compile this driver as a module, say M here: The module will be | 48 | To compile this driver as a module, say M here: The module will be |
69 | called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394 | 49 | called firewire-sbp2. |
70 | stack. | ||
71 | 50 | ||
72 | You should also enable support for disks, CD-ROMs, etc. in the SCSI | 51 | You should also enable support for disks, CD-ROMs, etc. in the SCSI |
73 | configuration section. | 52 | configuration section. |
@@ -83,5 +62,8 @@ config FIREWIRE_NET | |||
83 | NOTE, this driver is not stable yet! | 62 | NOTE, this driver is not stable yet! |
84 | 63 | ||
85 | To compile this driver as a module, say M here: The module will be | 64 | To compile this driver as a module, say M here: The module will be |
86 | called firewire-net. It replaces eth1394 of the classic IEEE 1394 | 65 | called firewire-net. |
87 | stack. | 66 | |
67 | source "drivers/ieee1394/Kconfig" | ||
68 | |||
69 | endmenu | ||
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index e4864e894e4f..5045156c5313 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -38,15 +38,14 @@ | |||
38 | 38 | ||
39 | #include "core.h" | 39 | #include "core.h" |
40 | 40 | ||
41 | int fw_compute_block_crc(u32 *block) | 41 | int fw_compute_block_crc(__be32 *block) |
42 | { | 42 | { |
43 | __be32 be32_block[256]; | 43 | int length; |
44 | int i, length; | 44 | u16 crc; |
45 | 45 | ||
46 | length = (*block >> 16) & 0xff; | 46 | length = (be32_to_cpu(block[0]) >> 16) & 0xff; |
47 | for (i = 0; i < length; i++) | 47 | crc = crc_itu_t(0, (u8 *)&block[1], length * 4); |
48 | be32_block[i] = cpu_to_be32(block[i + 1]); | 48 | *block |= cpu_to_be32(crc); |
49 | *block |= crc_itu_t(0, (u8 *) be32_block, length * 4); | ||
50 | 49 | ||
51 | return length; | 50 | return length; |
52 | } | 51 | } |
@@ -57,6 +56,10 @@ static LIST_HEAD(card_list); | |||
57 | static LIST_HEAD(descriptor_list); | 56 | static LIST_HEAD(descriptor_list); |
58 | static int descriptor_count; | 57 | static int descriptor_count; |
59 | 58 | ||
59 | static __be32 tmp_config_rom[256]; | ||
60 | /* ROM header, bus info block, root dir header, capabilities = 7 quadlets */ | ||
61 | static size_t config_rom_length = 1 + 4 + 1 + 1; | ||
62 | |||
60 | #define BIB_CRC(v) ((v) << 0) | 63 | #define BIB_CRC(v) ((v) << 0) |
61 | #define BIB_CRC_LENGTH(v) ((v) << 16) | 64 | #define BIB_CRC_LENGTH(v) ((v) << 16) |
62 | #define BIB_INFO_LENGTH(v) ((v) << 24) | 65 | #define BIB_INFO_LENGTH(v) ((v) << 24) |
@@ -72,11 +75,10 @@ static int descriptor_count; | |||
72 | #define BIB_CMC ((1) << 30) | 75 | #define BIB_CMC ((1) << 30) |
73 | #define BIB_IMC ((1) << 31) | 76 | #define BIB_IMC ((1) << 31) |
74 | 77 | ||
75 | static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | 78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
76 | { | 79 | { |
77 | struct fw_descriptor *desc; | 80 | struct fw_descriptor *desc; |
78 | static u32 config_rom[256]; | 81 | int i, j, k, length; |
79 | int i, j, length; | ||
80 | 82 | ||
81 | /* | 83 | /* |
82 | * Initialize contents of config rom buffer. On the OHCI | 84 | * Initialize contents of config rom buffer. On the OHCI |
@@ -87,40 +89,39 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | |||
87 | * the version stored in the OHCI registers. | 89 | * the version stored in the OHCI registers. |
88 | */ | 90 | */ |
89 | 91 | ||
90 | memset(config_rom, 0, sizeof(config_rom)); | 92 | config_rom[0] = cpu_to_be32( |
91 | config_rom[0] = BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0); | 93 | BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); |
92 | config_rom[1] = 0x31333934; | 94 | config_rom[1] = cpu_to_be32(0x31333934); |
93 | 95 | config_rom[2] = cpu_to_be32( | |
94 | config_rom[2] = | ||
95 | BIB_LINK_SPEED(card->link_speed) | | 96 | BIB_LINK_SPEED(card->link_speed) | |
96 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | | 97 | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | |
97 | BIB_MAX_ROM(2) | | 98 | BIB_MAX_ROM(2) | |
98 | BIB_MAX_RECEIVE(card->max_receive) | | 99 | BIB_MAX_RECEIVE(card->max_receive) | |
99 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC; | 100 | BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC); |
100 | config_rom[3] = card->guid >> 32; | 101 | config_rom[3] = cpu_to_be32(card->guid >> 32); |
101 | config_rom[4] = card->guid; | 102 | config_rom[4] = cpu_to_be32(card->guid); |
102 | 103 | ||
103 | /* Generate root directory. */ | 104 | /* Generate root directory. */ |
104 | i = 5; | 105 | config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */ |
105 | config_rom[i++] = 0; | 106 | i = 7; |
106 | config_rom[i++] = 0x0c0083c0; /* node capabilities */ | 107 | j = 7 + descriptor_count; |
107 | j = i + descriptor_count; | ||
108 | 108 | ||
109 | /* Generate root directory entries for descriptors. */ | 109 | /* Generate root directory entries for descriptors. */ |
110 | list_for_each_entry (desc, &descriptor_list, link) { | 110 | list_for_each_entry (desc, &descriptor_list, link) { |
111 | if (desc->immediate > 0) | 111 | if (desc->immediate > 0) |
112 | config_rom[i++] = desc->immediate; | 112 | config_rom[i++] = cpu_to_be32(desc->immediate); |
113 | config_rom[i] = desc->key | (j - i); | 113 | config_rom[i] = cpu_to_be32(desc->key | (j - i)); |
114 | i++; | 114 | i++; |
115 | j += desc->length; | 115 | j += desc->length; |
116 | } | 116 | } |
117 | 117 | ||
118 | /* Update root directory length. */ | 118 | /* Update root directory length. */ |
119 | config_rom[5] = (i - 5 - 1) << 16; | 119 | config_rom[5] = cpu_to_be32((i - 5 - 1) << 16); |
120 | 120 | ||
121 | /* End of root directory, now copy in descriptors. */ | 121 | /* End of root directory, now copy in descriptors. */ |
122 | list_for_each_entry (desc, &descriptor_list, link) { | 122 | list_for_each_entry (desc, &descriptor_list, link) { |
123 | memcpy(&config_rom[i], desc->data, desc->length * 4); | 123 | for (k = 0; k < desc->length; k++) |
124 | config_rom[i + k] = cpu_to_be32(desc->data[k]); | ||
124 | i += desc->length; | 125 | i += desc->length; |
125 | } | 126 | } |
126 | 127 | ||
@@ -131,26 +132,30 @@ static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length) | |||
131 | for (i = 0; i < j; i += length + 1) | 132 | for (i = 0; i < j; i += length + 1) |
132 | length = fw_compute_block_crc(config_rom + i); | 133 | length = fw_compute_block_crc(config_rom + i); |
133 | 134 | ||
134 | *config_rom_length = j; | 135 | WARN_ON(j != config_rom_length); |
135 | |||
136 | return config_rom; | ||
137 | } | 136 | } |
138 | 137 | ||
139 | static void update_config_roms(void) | 138 | static void update_config_roms(void) |
140 | { | 139 | { |
141 | struct fw_card *card; | 140 | struct fw_card *card; |
142 | u32 *config_rom; | ||
143 | size_t length; | ||
144 | 141 | ||
145 | list_for_each_entry (card, &card_list, link) { | 142 | list_for_each_entry (card, &card_list, link) { |
146 | config_rom = generate_config_rom(card, &length); | 143 | generate_config_rom(card, tmp_config_rom); |
147 | card->driver->set_config_rom(card, config_rom, length); | 144 | card->driver->set_config_rom(card, tmp_config_rom, |
145 | config_rom_length); | ||
148 | } | 146 | } |
149 | } | 147 | } |
150 | 148 | ||
149 | static size_t required_space(struct fw_descriptor *desc) | ||
150 | { | ||
151 | /* descriptor + entry into root dir + optional immediate entry */ | ||
152 | return desc->length + 1 + (desc->immediate > 0 ? 1 : 0); | ||
153 | } | ||
154 | |||
151 | int fw_core_add_descriptor(struct fw_descriptor *desc) | 155 | int fw_core_add_descriptor(struct fw_descriptor *desc) |
152 | { | 156 | { |
153 | size_t i; | 157 | size_t i; |
158 | int ret; | ||
154 | 159 | ||
155 | /* | 160 | /* |
156 | * Check descriptor is valid; the length of all blocks in the | 161 | * Check descriptor is valid; the length of all blocks in the |
@@ -166,15 +171,21 @@ int fw_core_add_descriptor(struct fw_descriptor *desc) | |||
166 | 171 | ||
167 | mutex_lock(&card_mutex); | 172 | mutex_lock(&card_mutex); |
168 | 173 | ||
169 | list_add_tail(&desc->link, &descriptor_list); | 174 | if (config_rom_length + required_space(desc) > 256) { |
170 | descriptor_count++; | 175 | ret = -EBUSY; |
171 | if (desc->immediate > 0) | 176 | } else { |
177 | list_add_tail(&desc->link, &descriptor_list); | ||
178 | config_rom_length += required_space(desc); | ||
172 | descriptor_count++; | 179 | descriptor_count++; |
173 | update_config_roms(); | 180 | if (desc->immediate > 0) |
181 | descriptor_count++; | ||
182 | update_config_roms(); | ||
183 | ret = 0; | ||
184 | } | ||
174 | 185 | ||
175 | mutex_unlock(&card_mutex); | 186 | mutex_unlock(&card_mutex); |
176 | 187 | ||
177 | return 0; | 188 | return ret; |
178 | } | 189 | } |
179 | EXPORT_SYMBOL(fw_core_add_descriptor); | 190 | EXPORT_SYMBOL(fw_core_add_descriptor); |
180 | 191 | ||
@@ -183,6 +194,7 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc) | |||
183 | mutex_lock(&card_mutex); | 194 | mutex_lock(&card_mutex); |
184 | 195 | ||
185 | list_del(&desc->link); | 196 | list_del(&desc->link); |
197 | config_rom_length -= required_space(desc); | ||
186 | descriptor_count--; | 198 | descriptor_count--; |
187 | if (desc->immediate > 0) | 199 | if (desc->immediate > 0) |
188 | descriptor_count--; | 200 | descriptor_count--; |
@@ -211,11 +223,8 @@ static const char gap_count_table[] = { | |||
211 | 223 | ||
212 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) | 224 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) |
213 | { | 225 | { |
214 | int scheduled; | ||
215 | |||
216 | fw_card_get(card); | 226 | fw_card_get(card); |
217 | scheduled = schedule_delayed_work(&card->work, delay); | 227 | if (!schedule_delayed_work(&card->work, delay)) |
218 | if (!scheduled) | ||
219 | fw_card_put(card); | 228 | fw_card_put(card); |
220 | } | 229 | } |
221 | 230 | ||
@@ -435,8 +444,6 @@ EXPORT_SYMBOL(fw_card_initialize); | |||
435 | int fw_card_add(struct fw_card *card, | 444 | int fw_card_add(struct fw_card *card, |
436 | u32 max_receive, u32 link_speed, u64 guid) | 445 | u32 max_receive, u32 link_speed, u64 guid) |
437 | { | 446 | { |
438 | u32 *config_rom; | ||
439 | size_t length; | ||
440 | int ret; | 447 | int ret; |
441 | 448 | ||
442 | card->max_receive = max_receive; | 449 | card->max_receive = max_receive; |
@@ -445,8 +452,8 @@ int fw_card_add(struct fw_card *card, | |||
445 | 452 | ||
446 | mutex_lock(&card_mutex); | 453 | mutex_lock(&card_mutex); |
447 | 454 | ||
448 | config_rom = generate_config_rom(card, &length); | 455 | generate_config_rom(card, tmp_config_rom); |
449 | ret = card->driver->enable(card, config_rom, length); | 456 | ret = card->driver->enable(card, tmp_config_rom, config_rom_length); |
450 | if (ret == 0) | 457 | if (ret == 0) |
451 | list_add_tail(&card->link, &card_list); | 458 | list_add_tail(&card->link, &card_list); |
452 | 459 | ||
@@ -465,7 +472,8 @@ EXPORT_SYMBOL(fw_card_add); | |||
465 | * shutdown still need to be provided by the card driver. | 472 | * shutdown still need to be provided by the card driver. |
466 | */ | 473 | */ |
467 | 474 | ||
468 | static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length) | 475 | static int dummy_enable(struct fw_card *card, |
476 | const __be32 *config_rom, size_t length) | ||
469 | { | 477 | { |
470 | BUG(); | 478 | BUG(); |
471 | return -1; | 479 | return -1; |
@@ -478,7 +486,7 @@ static int dummy_update_phy_reg(struct fw_card *card, int address, | |||
478 | } | 486 | } |
479 | 487 | ||
480 | static int dummy_set_config_rom(struct fw_card *card, | 488 | static int dummy_set_config_rom(struct fw_card *card, |
481 | u32 *config_rom, size_t length) | 489 | const __be32 *config_rom, size_t length) |
482 | { | 490 | { |
483 | /* | 491 | /* |
484 | * We take the card out of card_list before setting the dummy | 492 | * We take the card out of card_list before setting the dummy |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 5089331544ed..14a34d99eea2 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/firewire.h> | 25 | #include <linux/firewire.h> |
26 | #include <linux/firewire-cdev.h> | 26 | #include <linux/firewire-cdev.h> |
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <linux/irqflags.h> | ||
28 | #include <linux/jiffies.h> | 29 | #include <linux/jiffies.h> |
29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
30 | #include <linux/kref.h> | 31 | #include <linux/kref.h> |
@@ -32,9 +33,10 @@ | |||
32 | #include <linux/module.h> | 33 | #include <linux/module.h> |
33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
34 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
35 | #include <linux/preempt.h> | ||
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/slab.h> | ||
37 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/string.h> | ||
38 | #include <linux/time.h> | 40 | #include <linux/time.h> |
39 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
40 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
@@ -130,9 +132,22 @@ struct iso_resource { | |||
130 | struct iso_resource_event *e_alloc, *e_dealloc; | 132 | struct iso_resource_event *e_alloc, *e_dealloc; |
131 | }; | 133 | }; |
132 | 134 | ||
133 | static void schedule_iso_resource(struct iso_resource *); | ||
134 | static void release_iso_resource(struct client *, struct client_resource *); | 135 | static void release_iso_resource(struct client *, struct client_resource *); |
135 | 136 | ||
137 | static void schedule_iso_resource(struct iso_resource *r, unsigned long delay) | ||
138 | { | ||
139 | client_get(r->client); | ||
140 | if (!schedule_delayed_work(&r->work, delay)) | ||
141 | client_put(r->client); | ||
142 | } | ||
143 | |||
144 | static void schedule_if_iso_resource(struct client_resource *resource) | ||
145 | { | ||
146 | if (resource->release == release_iso_resource) | ||
147 | schedule_iso_resource(container_of(resource, | ||
148 | struct iso_resource, resource), 0); | ||
149 | } | ||
150 | |||
136 | /* | 151 | /* |
137 | * dequeue_event() just kfree()'s the event, so the event has to be | 152 | * dequeue_event() just kfree()'s the event, so the event has to be |
138 | * the first field in a struct XYZ_event. | 153 | * the first field in a struct XYZ_event. |
@@ -166,7 +181,7 @@ struct iso_interrupt_event { | |||
166 | 181 | ||
167 | struct iso_resource_event { | 182 | struct iso_resource_event { |
168 | struct event event; | 183 | struct event event; |
169 | struct fw_cdev_event_iso_resource resource; | 184 | struct fw_cdev_event_iso_resource iso_resource; |
170 | }; | 185 | }; |
171 | 186 | ||
172 | static inline void __user *u64_to_uptr(__u64 value) | 187 | static inline void __user *u64_to_uptr(__u64 value) |
@@ -314,11 +329,8 @@ static void for_each_client(struct fw_device *device, | |||
314 | 329 | ||
315 | static int schedule_reallocations(int id, void *p, void *data) | 330 | static int schedule_reallocations(int id, void *p, void *data) |
316 | { | 331 | { |
317 | struct client_resource *r = p; | 332 | schedule_if_iso_resource(p); |
318 | 333 | ||
319 | if (r->release == release_iso_resource) | ||
320 | schedule_iso_resource(container_of(r, | ||
321 | struct iso_resource, resource)); | ||
322 | return 0; | 334 | return 0; |
323 | } | 335 | } |
324 | 336 | ||
@@ -357,39 +369,56 @@ void fw_device_cdev_remove(struct fw_device *device) | |||
357 | for_each_client(device, wake_up_client); | 369 | for_each_client(device, wake_up_client); |
358 | } | 370 | } |
359 | 371 | ||
360 | static int ioctl_get_info(struct client *client, void *buffer) | 372 | union ioctl_arg { |
373 | struct fw_cdev_get_info get_info; | ||
374 | struct fw_cdev_send_request send_request; | ||
375 | struct fw_cdev_allocate allocate; | ||
376 | struct fw_cdev_deallocate deallocate; | ||
377 | struct fw_cdev_send_response send_response; | ||
378 | struct fw_cdev_initiate_bus_reset initiate_bus_reset; | ||
379 | struct fw_cdev_add_descriptor add_descriptor; | ||
380 | struct fw_cdev_remove_descriptor remove_descriptor; | ||
381 | struct fw_cdev_create_iso_context create_iso_context; | ||
382 | struct fw_cdev_queue_iso queue_iso; | ||
383 | struct fw_cdev_start_iso start_iso; | ||
384 | struct fw_cdev_stop_iso stop_iso; | ||
385 | struct fw_cdev_get_cycle_timer get_cycle_timer; | ||
386 | struct fw_cdev_allocate_iso_resource allocate_iso_resource; | ||
387 | struct fw_cdev_send_stream_packet send_stream_packet; | ||
388 | struct fw_cdev_get_cycle_timer2 get_cycle_timer2; | ||
389 | }; | ||
390 | |||
391 | static int ioctl_get_info(struct client *client, union ioctl_arg *arg) | ||
361 | { | 392 | { |
362 | struct fw_cdev_get_info *get_info = buffer; | 393 | struct fw_cdev_get_info *a = &arg->get_info; |
363 | struct fw_cdev_event_bus_reset bus_reset; | 394 | struct fw_cdev_event_bus_reset bus_reset; |
364 | unsigned long ret = 0; | 395 | unsigned long ret = 0; |
365 | 396 | ||
366 | client->version = get_info->version; | 397 | client->version = a->version; |
367 | get_info->version = FW_CDEV_VERSION; | 398 | a->version = FW_CDEV_VERSION; |
368 | get_info->card = client->device->card->index; | 399 | a->card = client->device->card->index; |
369 | 400 | ||
370 | down_read(&fw_device_rwsem); | 401 | down_read(&fw_device_rwsem); |
371 | 402 | ||
372 | if (get_info->rom != 0) { | 403 | if (a->rom != 0) { |
373 | void __user *uptr = u64_to_uptr(get_info->rom); | 404 | size_t want = a->rom_length; |
374 | size_t want = get_info->rom_length; | ||
375 | size_t have = client->device->config_rom_length * 4; | 405 | size_t have = client->device->config_rom_length * 4; |
376 | 406 | ||
377 | ret = copy_to_user(uptr, client->device->config_rom, | 407 | ret = copy_to_user(u64_to_uptr(a->rom), |
378 | min(want, have)); | 408 | client->device->config_rom, min(want, have)); |
379 | } | 409 | } |
380 | get_info->rom_length = client->device->config_rom_length * 4; | 410 | a->rom_length = client->device->config_rom_length * 4; |
381 | 411 | ||
382 | up_read(&fw_device_rwsem); | 412 | up_read(&fw_device_rwsem); |
383 | 413 | ||
384 | if (ret != 0) | 414 | if (ret != 0) |
385 | return -EFAULT; | 415 | return -EFAULT; |
386 | 416 | ||
387 | client->bus_reset_closure = get_info->bus_reset_closure; | 417 | client->bus_reset_closure = a->bus_reset_closure; |
388 | if (get_info->bus_reset != 0) { | 418 | if (a->bus_reset != 0) { |
389 | void __user *uptr = u64_to_uptr(get_info->bus_reset); | ||
390 | |||
391 | fill_bus_reset_event(&bus_reset, client); | 419 | fill_bus_reset_event(&bus_reset, client); |
392 | if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) | 420 | if (copy_to_user(u64_to_uptr(a->bus_reset), |
421 | &bus_reset, sizeof(bus_reset))) | ||
393 | return -EFAULT; | 422 | return -EFAULT; |
394 | } | 423 | } |
395 | 424 | ||
@@ -414,9 +443,7 @@ static int add_client_resource(struct client *client, | |||
414 | &resource->handle); | 443 | &resource->handle); |
415 | if (ret >= 0) { | 444 | if (ret >= 0) { |
416 | client_get(client); | 445 | client_get(client); |
417 | if (resource->release == release_iso_resource) | 446 | schedule_if_iso_resource(resource); |
418 | schedule_iso_resource(container_of(resource, | ||
419 | struct iso_resource, resource)); | ||
420 | } | 447 | } |
421 | spin_unlock_irqrestore(&client->lock, flags); | 448 | spin_unlock_irqrestore(&client->lock, flags); |
422 | 449 | ||
@@ -428,26 +455,26 @@ static int add_client_resource(struct client *client, | |||
428 | 455 | ||
429 | static int release_client_resource(struct client *client, u32 handle, | 456 | static int release_client_resource(struct client *client, u32 handle, |
430 | client_resource_release_fn_t release, | 457 | client_resource_release_fn_t release, |
431 | struct client_resource **resource) | 458 | struct client_resource **return_resource) |
432 | { | 459 | { |
433 | struct client_resource *r; | 460 | struct client_resource *resource; |
434 | 461 | ||
435 | spin_lock_irq(&client->lock); | 462 | spin_lock_irq(&client->lock); |
436 | if (client->in_shutdown) | 463 | if (client->in_shutdown) |
437 | r = NULL; | 464 | resource = NULL; |
438 | else | 465 | else |
439 | r = idr_find(&client->resource_idr, handle); | 466 | resource = idr_find(&client->resource_idr, handle); |
440 | if (r && r->release == release) | 467 | if (resource && resource->release == release) |
441 | idr_remove(&client->resource_idr, handle); | 468 | idr_remove(&client->resource_idr, handle); |
442 | spin_unlock_irq(&client->lock); | 469 | spin_unlock_irq(&client->lock); |
443 | 470 | ||
444 | if (!(r && r->release == release)) | 471 | if (!(resource && resource->release == release)) |
445 | return -EINVAL; | 472 | return -EINVAL; |
446 | 473 | ||
447 | if (resource) | 474 | if (return_resource) |
448 | *resource = r; | 475 | *return_resource = resource; |
449 | else | 476 | else |
450 | r->release(client, r); | 477 | resource->release(client, resource); |
451 | 478 | ||
452 | client_put(client); | 479 | client_put(client); |
453 | 480 | ||
@@ -562,11 +589,9 @@ static int init_request(struct client *client, | |||
562 | return ret; | 589 | return ret; |
563 | } | 590 | } |
564 | 591 | ||
565 | static int ioctl_send_request(struct client *client, void *buffer) | 592 | static int ioctl_send_request(struct client *client, union ioctl_arg *arg) |
566 | { | 593 | { |
567 | struct fw_cdev_send_request *request = buffer; | 594 | switch (arg->send_request.tcode) { |
568 | |||
569 | switch (request->tcode) { | ||
570 | case TCODE_WRITE_QUADLET_REQUEST: | 595 | case TCODE_WRITE_QUADLET_REQUEST: |
571 | case TCODE_WRITE_BLOCK_REQUEST: | 596 | case TCODE_WRITE_BLOCK_REQUEST: |
572 | case TCODE_READ_QUADLET_REQUEST: | 597 | case TCODE_READ_QUADLET_REQUEST: |
@@ -583,18 +608,26 @@ static int ioctl_send_request(struct client *client, void *buffer) | |||
583 | return -EINVAL; | 608 | return -EINVAL; |
584 | } | 609 | } |
585 | 610 | ||
586 | return init_request(client, request, client->device->node_id, | 611 | return init_request(client, &arg->send_request, client->device->node_id, |
587 | client->device->max_speed); | 612 | client->device->max_speed); |
588 | } | 613 | } |
589 | 614 | ||
615 | static inline bool is_fcp_request(struct fw_request *request) | ||
616 | { | ||
617 | return request == NULL; | ||
618 | } | ||
619 | |||
590 | static void release_request(struct client *client, | 620 | static void release_request(struct client *client, |
591 | struct client_resource *resource) | 621 | struct client_resource *resource) |
592 | { | 622 | { |
593 | struct inbound_transaction_resource *r = container_of(resource, | 623 | struct inbound_transaction_resource *r = container_of(resource, |
594 | struct inbound_transaction_resource, resource); | 624 | struct inbound_transaction_resource, resource); |
595 | 625 | ||
596 | fw_send_response(client->device->card, r->request, | 626 | if (is_fcp_request(r->request)) |
597 | RCODE_CONFLICT_ERROR); | 627 | kfree(r->data); |
628 | else | ||
629 | fw_send_response(client->device->card, r->request, | ||
630 | RCODE_CONFLICT_ERROR); | ||
598 | kfree(r); | 631 | kfree(r); |
599 | } | 632 | } |
600 | 633 | ||
@@ -607,6 +640,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
607 | struct address_handler_resource *handler = callback_data; | 640 | struct address_handler_resource *handler = callback_data; |
608 | struct inbound_transaction_resource *r; | 641 | struct inbound_transaction_resource *r; |
609 | struct inbound_transaction_event *e; | 642 | struct inbound_transaction_event *e; |
643 | void *fcp_frame = NULL; | ||
610 | int ret; | 644 | int ret; |
611 | 645 | ||
612 | r = kmalloc(sizeof(*r), GFP_ATOMIC); | 646 | r = kmalloc(sizeof(*r), GFP_ATOMIC); |
@@ -618,6 +652,18 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
618 | r->data = payload; | 652 | r->data = payload; |
619 | r->length = length; | 653 | r->length = length; |
620 | 654 | ||
655 | if (is_fcp_request(request)) { | ||
656 | /* | ||
657 | * FIXME: Let core-transaction.c manage a | ||
658 | * single reference-counted copy? | ||
659 | */ | ||
660 | fcp_frame = kmemdup(payload, length, GFP_ATOMIC); | ||
661 | if (fcp_frame == NULL) | ||
662 | goto failed; | ||
663 | |||
664 | r->data = fcp_frame; | ||
665 | } | ||
666 | |||
621 | r->resource.release = release_request; | 667 | r->resource.release = release_request; |
622 | ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); | 668 | ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); |
623 | if (ret < 0) | 669 | if (ret < 0) |
@@ -631,13 +677,16 @@ static void handle_request(struct fw_card *card, struct fw_request *request, | |||
631 | e->request.closure = handler->closure; | 677 | e->request.closure = handler->closure; |
632 | 678 | ||
633 | queue_event(handler->client, &e->event, | 679 | queue_event(handler->client, &e->event, |
634 | &e->request, sizeof(e->request), payload, length); | 680 | &e->request, sizeof(e->request), r->data, length); |
635 | return; | 681 | return; |
636 | 682 | ||
637 | failed: | 683 | failed: |
638 | kfree(r); | 684 | kfree(r); |
639 | kfree(e); | 685 | kfree(e); |
640 | fw_send_response(card, request, RCODE_CONFLICT_ERROR); | 686 | kfree(fcp_frame); |
687 | |||
688 | if (!is_fcp_request(request)) | ||
689 | fw_send_response(card, request, RCODE_CONFLICT_ERROR); | ||
641 | } | 690 | } |
642 | 691 | ||
643 | static void release_address_handler(struct client *client, | 692 | static void release_address_handler(struct client *client, |
@@ -650,9 +699,9 @@ static void release_address_handler(struct client *client, | |||
650 | kfree(r); | 699 | kfree(r); |
651 | } | 700 | } |
652 | 701 | ||
653 | static int ioctl_allocate(struct client *client, void *buffer) | 702 | static int ioctl_allocate(struct client *client, union ioctl_arg *arg) |
654 | { | 703 | { |
655 | struct fw_cdev_allocate *request = buffer; | 704 | struct fw_cdev_allocate *a = &arg->allocate; |
656 | struct address_handler_resource *r; | 705 | struct address_handler_resource *r; |
657 | struct fw_address_region region; | 706 | struct fw_address_region region; |
658 | int ret; | 707 | int ret; |
@@ -661,13 +710,13 @@ static int ioctl_allocate(struct client *client, void *buffer) | |||
661 | if (r == NULL) | 710 | if (r == NULL) |
662 | return -ENOMEM; | 711 | return -ENOMEM; |
663 | 712 | ||
664 | region.start = request->offset; | 713 | region.start = a->offset; |
665 | region.end = request->offset + request->length; | 714 | region.end = a->offset + a->length; |
666 | r->handler.length = request->length; | 715 | r->handler.length = a->length; |
667 | r->handler.address_callback = handle_request; | 716 | r->handler.address_callback = handle_request; |
668 | r->handler.callback_data = r; | 717 | r->handler.callback_data = r; |
669 | r->closure = request->closure; | 718 | r->closure = a->closure; |
670 | r->client = client; | 719 | r->client = client; |
671 | 720 | ||
672 | ret = fw_core_add_address_handler(&r->handler, ®ion); | 721 | ret = fw_core_add_address_handler(&r->handler, ®ion); |
673 | if (ret < 0) { | 722 | if (ret < 0) { |
@@ -681,50 +730,51 @@ static int ioctl_allocate(struct client *client, void *buffer) | |||
681 | release_address_handler(client, &r->resource); | 730 | release_address_handler(client, &r->resource); |
682 | return ret; | 731 | return ret; |
683 | } | 732 | } |
684 | request->handle = r->resource.handle; | 733 | a->handle = r->resource.handle; |
685 | 734 | ||
686 | return 0; | 735 | return 0; |
687 | } | 736 | } |
688 | 737 | ||
689 | static int ioctl_deallocate(struct client *client, void *buffer) | 738 | static int ioctl_deallocate(struct client *client, union ioctl_arg *arg) |
690 | { | 739 | { |
691 | struct fw_cdev_deallocate *request = buffer; | 740 | return release_client_resource(client, arg->deallocate.handle, |
692 | |||
693 | return release_client_resource(client, request->handle, | ||
694 | release_address_handler, NULL); | 741 | release_address_handler, NULL); |
695 | } | 742 | } |
696 | 743 | ||
697 | static int ioctl_send_response(struct client *client, void *buffer) | 744 | static int ioctl_send_response(struct client *client, union ioctl_arg *arg) |
698 | { | 745 | { |
699 | struct fw_cdev_send_response *request = buffer; | 746 | struct fw_cdev_send_response *a = &arg->send_response; |
700 | struct client_resource *resource; | 747 | struct client_resource *resource; |
701 | struct inbound_transaction_resource *r; | 748 | struct inbound_transaction_resource *r; |
749 | int ret = 0; | ||
702 | 750 | ||
703 | if (release_client_resource(client, request->handle, | 751 | if (release_client_resource(client, a->handle, |
704 | release_request, &resource) < 0) | 752 | release_request, &resource) < 0) |
705 | return -EINVAL; | 753 | return -EINVAL; |
706 | 754 | ||
707 | r = container_of(resource, struct inbound_transaction_resource, | 755 | r = container_of(resource, struct inbound_transaction_resource, |
708 | resource); | 756 | resource); |
709 | if (request->length < r->length) | 757 | if (is_fcp_request(r->request)) |
710 | r->length = request->length; | 758 | goto out; |
711 | if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) | ||
712 | return -EFAULT; | ||
713 | 759 | ||
714 | fw_send_response(client->device->card, r->request, request->rcode); | 760 | if (a->length < r->length) |
761 | r->length = a->length; | ||
762 | if (copy_from_user(r->data, u64_to_uptr(a->data), r->length)) { | ||
763 | ret = -EFAULT; | ||
764 | kfree(r->request); | ||
765 | goto out; | ||
766 | } | ||
767 | fw_send_response(client->device->card, r->request, a->rcode); | ||
768 | out: | ||
715 | kfree(r); | 769 | kfree(r); |
716 | 770 | ||
717 | return 0; | 771 | return ret; |
718 | } | 772 | } |
719 | 773 | ||
720 | static int ioctl_initiate_bus_reset(struct client *client, void *buffer) | 774 | static int ioctl_initiate_bus_reset(struct client *client, union ioctl_arg *arg) |
721 | { | 775 | { |
722 | struct fw_cdev_initiate_bus_reset *request = buffer; | 776 | return fw_core_initiate_bus_reset(client->device->card, |
723 | int short_reset; | 777 | arg->initiate_bus_reset.type == FW_CDEV_SHORT_RESET); |
724 | |||
725 | short_reset = (request->type == FW_CDEV_SHORT_RESET); | ||
726 | |||
727 | return fw_core_initiate_bus_reset(client->device->card, short_reset); | ||
728 | } | 778 | } |
729 | 779 | ||
730 | static void release_descriptor(struct client *client, | 780 | static void release_descriptor(struct client *client, |
@@ -737,9 +787,9 @@ static void release_descriptor(struct client *client, | |||
737 | kfree(r); | 787 | kfree(r); |
738 | } | 788 | } |
739 | 789 | ||
740 | static int ioctl_add_descriptor(struct client *client, void *buffer) | 790 | static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg) |
741 | { | 791 | { |
742 | struct fw_cdev_add_descriptor *request = buffer; | 792 | struct fw_cdev_add_descriptor *a = &arg->add_descriptor; |
743 | struct descriptor_resource *r; | 793 | struct descriptor_resource *r; |
744 | int ret; | 794 | int ret; |
745 | 795 | ||
@@ -747,22 +797,21 @@ static int ioctl_add_descriptor(struct client *client, void *buffer) | |||
747 | if (!client->device->is_local) | 797 | if (!client->device->is_local) |
748 | return -ENOSYS; | 798 | return -ENOSYS; |
749 | 799 | ||
750 | if (request->length > 256) | 800 | if (a->length > 256) |
751 | return -EINVAL; | 801 | return -EINVAL; |
752 | 802 | ||
753 | r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL); | 803 | r = kmalloc(sizeof(*r) + a->length * 4, GFP_KERNEL); |
754 | if (r == NULL) | 804 | if (r == NULL) |
755 | return -ENOMEM; | 805 | return -ENOMEM; |
756 | 806 | ||
757 | if (copy_from_user(r->data, | 807 | if (copy_from_user(r->data, u64_to_uptr(a->data), a->length * 4)) { |
758 | u64_to_uptr(request->data), request->length * 4)) { | ||
759 | ret = -EFAULT; | 808 | ret = -EFAULT; |
760 | goto failed; | 809 | goto failed; |
761 | } | 810 | } |
762 | 811 | ||
763 | r->descriptor.length = request->length; | 812 | r->descriptor.length = a->length; |
764 | r->descriptor.immediate = request->immediate; | 813 | r->descriptor.immediate = a->immediate; |
765 | r->descriptor.key = request->key; | 814 | r->descriptor.key = a->key; |
766 | r->descriptor.data = r->data; | 815 | r->descriptor.data = r->data; |
767 | 816 | ||
768 | ret = fw_core_add_descriptor(&r->descriptor); | 817 | ret = fw_core_add_descriptor(&r->descriptor); |
@@ -775,7 +824,7 @@ static int ioctl_add_descriptor(struct client *client, void *buffer) | |||
775 | fw_core_remove_descriptor(&r->descriptor); | 824 | fw_core_remove_descriptor(&r->descriptor); |
776 | goto failed; | 825 | goto failed; |
777 | } | 826 | } |
778 | request->handle = r->resource.handle; | 827 | a->handle = r->resource.handle; |
779 | 828 | ||
780 | return 0; | 829 | return 0; |
781 | failed: | 830 | failed: |
@@ -784,11 +833,9 @@ static int ioctl_add_descriptor(struct client *client, void *buffer) | |||
784 | return ret; | 833 | return ret; |
785 | } | 834 | } |
786 | 835 | ||
787 | static int ioctl_remove_descriptor(struct client *client, void *buffer) | 836 | static int ioctl_remove_descriptor(struct client *client, union ioctl_arg *arg) |
788 | { | 837 | { |
789 | struct fw_cdev_remove_descriptor *request = buffer; | 838 | return release_client_resource(client, arg->remove_descriptor.handle, |
790 | |||
791 | return release_client_resource(client, request->handle, | ||
792 | release_descriptor, NULL); | 839 | release_descriptor, NULL); |
793 | } | 840 | } |
794 | 841 | ||
@@ -811,49 +858,44 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle, | |||
811 | sizeof(e->interrupt) + header_length, NULL, 0); | 858 | sizeof(e->interrupt) + header_length, NULL, 0); |
812 | } | 859 | } |
813 | 860 | ||
814 | static int ioctl_create_iso_context(struct client *client, void *buffer) | 861 | static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg) |
815 | { | 862 | { |
816 | struct fw_cdev_create_iso_context *request = buffer; | 863 | struct fw_cdev_create_iso_context *a = &arg->create_iso_context; |
817 | struct fw_iso_context *context; | 864 | struct fw_iso_context *context; |
818 | 865 | ||
819 | /* We only support one context at this time. */ | 866 | /* We only support one context at this time. */ |
820 | if (client->iso_context != NULL) | 867 | if (client->iso_context != NULL) |
821 | return -EBUSY; | 868 | return -EBUSY; |
822 | 869 | ||
823 | if (request->channel > 63) | 870 | if (a->channel > 63) |
824 | return -EINVAL; | 871 | return -EINVAL; |
825 | 872 | ||
826 | switch (request->type) { | 873 | switch (a->type) { |
827 | case FW_ISO_CONTEXT_RECEIVE: | 874 | case FW_ISO_CONTEXT_RECEIVE: |
828 | if (request->header_size < 4 || (request->header_size & 3)) | 875 | if (a->header_size < 4 || (a->header_size & 3)) |
829 | return -EINVAL; | 876 | return -EINVAL; |
830 | |||
831 | break; | 877 | break; |
832 | 878 | ||
833 | case FW_ISO_CONTEXT_TRANSMIT: | 879 | case FW_ISO_CONTEXT_TRANSMIT: |
834 | if (request->speed > SCODE_3200) | 880 | if (a->speed > SCODE_3200) |
835 | return -EINVAL; | 881 | return -EINVAL; |
836 | |||
837 | break; | 882 | break; |
838 | 883 | ||
839 | default: | 884 | default: |
840 | return -EINVAL; | 885 | return -EINVAL; |
841 | } | 886 | } |
842 | 887 | ||
843 | context = fw_iso_context_create(client->device->card, | 888 | context = fw_iso_context_create(client->device->card, a->type, |
844 | request->type, | 889 | a->channel, a->speed, a->header_size, |
845 | request->channel, | 890 | iso_callback, client); |
846 | request->speed, | ||
847 | request->header_size, | ||
848 | iso_callback, client); | ||
849 | if (IS_ERR(context)) | 891 | if (IS_ERR(context)) |
850 | return PTR_ERR(context); | 892 | return PTR_ERR(context); |
851 | 893 | ||
852 | client->iso_closure = request->closure; | 894 | client->iso_closure = a->closure; |
853 | client->iso_context = context; | 895 | client->iso_context = context; |
854 | 896 | ||
855 | /* We only support one context at this time. */ | 897 | /* We only support one context at this time. */ |
856 | request->handle = 0; | 898 | a->handle = 0; |
857 | 899 | ||
858 | return 0; | 900 | return 0; |
859 | } | 901 | } |
@@ -866,9 +908,9 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) | |||
866 | #define GET_SY(v) (((v) >> 20) & 0x0f) | 908 | #define GET_SY(v) (((v) >> 20) & 0x0f) |
867 | #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) | 909 | #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) |
868 | 910 | ||
869 | static int ioctl_queue_iso(struct client *client, void *buffer) | 911 | static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) |
870 | { | 912 | { |
871 | struct fw_cdev_queue_iso *request = buffer; | 913 | struct fw_cdev_queue_iso *a = &arg->queue_iso; |
872 | struct fw_cdev_iso_packet __user *p, *end, *next; | 914 | struct fw_cdev_iso_packet __user *p, *end, *next; |
873 | struct fw_iso_context *ctx = client->iso_context; | 915 | struct fw_iso_context *ctx = client->iso_context; |
874 | unsigned long payload, buffer_end, header_length; | 916 | unsigned long payload, buffer_end, header_length; |
@@ -879,7 +921,7 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
879 | u8 header[256]; | 921 | u8 header[256]; |
880 | } u; | 922 | } u; |
881 | 923 | ||
882 | if (ctx == NULL || request->handle != 0) | 924 | if (ctx == NULL || a->handle != 0) |
883 | return -EINVAL; | 925 | return -EINVAL; |
884 | 926 | ||
885 | /* | 927 | /* |
@@ -889,23 +931,23 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
889 | * set them both to 0, which will still let packets with | 931 | * set them both to 0, which will still let packets with |
890 | * payload_length == 0 through. In other words, if no packets | 932 | * payload_length == 0 through. In other words, if no packets |
891 | * use the indirect payload, the iso buffer need not be mapped | 933 | * use the indirect payload, the iso buffer need not be mapped |
892 | * and the request->data pointer is ignored. | 934 | * and the a->data pointer is ignored. |
893 | */ | 935 | */ |
894 | 936 | ||
895 | payload = (unsigned long)request->data - client->vm_start; | 937 | payload = (unsigned long)a->data - client->vm_start; |
896 | buffer_end = client->buffer.page_count << PAGE_SHIFT; | 938 | buffer_end = client->buffer.page_count << PAGE_SHIFT; |
897 | if (request->data == 0 || client->buffer.pages == NULL || | 939 | if (a->data == 0 || client->buffer.pages == NULL || |
898 | payload >= buffer_end) { | 940 | payload >= buffer_end) { |
899 | payload = 0; | 941 | payload = 0; |
900 | buffer_end = 0; | 942 | buffer_end = 0; |
901 | } | 943 | } |
902 | 944 | ||
903 | p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request->packets); | 945 | p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(a->packets); |
904 | 946 | ||
905 | if (!access_ok(VERIFY_READ, p, request->size)) | 947 | if (!access_ok(VERIFY_READ, p, a->size)) |
906 | return -EFAULT; | 948 | return -EFAULT; |
907 | 949 | ||
908 | end = (void __user *)p + request->size; | 950 | end = (void __user *)p + a->size; |
909 | count = 0; | 951 | count = 0; |
910 | while (p < end) { | 952 | while (p < end) { |
911 | if (get_user(control, &p->control)) | 953 | if (get_user(control, &p->control)) |
@@ -918,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
918 | u.packet.header_length = GET_HEADER_LENGTH(control); | 960 | u.packet.header_length = GET_HEADER_LENGTH(control); |
919 | 961 | ||
920 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { | 962 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { |
963 | if (u.packet.header_length % 4 != 0) | ||
964 | return -EINVAL; | ||
921 | header_length = u.packet.header_length; | 965 | header_length = u.packet.header_length; |
922 | } else { | 966 | } else { |
923 | /* | 967 | /* |
@@ -927,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
927 | if (ctx->header_size == 0) { | 971 | if (ctx->header_size == 0) { |
928 | if (u.packet.header_length > 0) | 972 | if (u.packet.header_length > 0) |
929 | return -EINVAL; | 973 | return -EINVAL; |
930 | } else if (u.packet.header_length % ctx->header_size != 0) { | 974 | } else if (u.packet.header_length == 0 || |
975 | u.packet.header_length % ctx->header_size != 0) { | ||
931 | return -EINVAL; | 976 | return -EINVAL; |
932 | } | 977 | } |
933 | header_length = 0; | 978 | header_length = 0; |
@@ -955,61 +1000,78 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
955 | count++; | 1000 | count++; |
956 | } | 1001 | } |
957 | 1002 | ||
958 | request->size -= uptr_to_u64(p) - request->packets; | 1003 | a->size -= uptr_to_u64(p) - a->packets; |
959 | request->packets = uptr_to_u64(p); | 1004 | a->packets = uptr_to_u64(p); |
960 | request->data = client->vm_start + payload; | 1005 | a->data = client->vm_start + payload; |
961 | 1006 | ||
962 | return count; | 1007 | return count; |
963 | } | 1008 | } |
964 | 1009 | ||
965 | static int ioctl_start_iso(struct client *client, void *buffer) | 1010 | static int ioctl_start_iso(struct client *client, union ioctl_arg *arg) |
966 | { | 1011 | { |
967 | struct fw_cdev_start_iso *request = buffer; | 1012 | struct fw_cdev_start_iso *a = &arg->start_iso; |
968 | 1013 | ||
969 | if (client->iso_context == NULL || request->handle != 0) | 1014 | if (client->iso_context == NULL || a->handle != 0) |
970 | return -EINVAL; | 1015 | return -EINVAL; |
971 | 1016 | ||
972 | if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) { | 1017 | if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE && |
973 | if (request->tags == 0 || request->tags > 15) | 1018 | (a->tags == 0 || a->tags > 15 || a->sync > 15)) |
974 | return -EINVAL; | 1019 | return -EINVAL; |
975 | |||
976 | if (request->sync > 15) | ||
977 | return -EINVAL; | ||
978 | } | ||
979 | 1020 | ||
980 | return fw_iso_context_start(client->iso_context, request->cycle, | 1021 | return fw_iso_context_start(client->iso_context, |
981 | request->sync, request->tags); | 1022 | a->cycle, a->sync, a->tags); |
982 | } | 1023 | } |
983 | 1024 | ||
984 | static int ioctl_stop_iso(struct client *client, void *buffer) | 1025 | static int ioctl_stop_iso(struct client *client, union ioctl_arg *arg) |
985 | { | 1026 | { |
986 | struct fw_cdev_stop_iso *request = buffer; | 1027 | struct fw_cdev_stop_iso *a = &arg->stop_iso; |
987 | 1028 | ||
988 | if (client->iso_context == NULL || request->handle != 0) | 1029 | if (client->iso_context == NULL || a->handle != 0) |
989 | return -EINVAL; | 1030 | return -EINVAL; |
990 | 1031 | ||
991 | return fw_iso_context_stop(client->iso_context); | 1032 | return fw_iso_context_stop(client->iso_context); |
992 | } | 1033 | } |
993 | 1034 | ||
994 | static int ioctl_get_cycle_timer(struct client *client, void *buffer) | 1035 | static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg) |
995 | { | 1036 | { |
996 | struct fw_cdev_get_cycle_timer *request = buffer; | 1037 | struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2; |
997 | struct fw_card *card = client->device->card; | 1038 | struct fw_card *card = client->device->card; |
998 | unsigned long long bus_time; | 1039 | struct timespec ts = {0, 0}; |
999 | struct timeval tv; | 1040 | u32 cycle_time; |
1000 | unsigned long flags; | 1041 | int ret = 0; |
1042 | |||
1043 | local_irq_disable(); | ||
1044 | |||
1045 | cycle_time = card->driver->get_cycle_time(card); | ||
1046 | |||
1047 | switch (a->clk_id) { | ||
1048 | case CLOCK_REALTIME: getnstimeofday(&ts); break; | ||
1049 | case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break; | ||
1050 | case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break; | ||
1051 | default: | ||
1052 | ret = -EINVAL; | ||
1053 | } | ||
1054 | |||
1055 | local_irq_enable(); | ||
1056 | |||
1057 | a->tv_sec = ts.tv_sec; | ||
1058 | a->tv_nsec = ts.tv_nsec; | ||
1059 | a->cycle_timer = cycle_time; | ||
1001 | 1060 | ||
1002 | preempt_disable(); | 1061 | return ret; |
1003 | local_irq_save(flags); | 1062 | } |
1004 | 1063 | ||
1005 | bus_time = card->driver->get_bus_time(card); | 1064 | static int ioctl_get_cycle_timer(struct client *client, union ioctl_arg *arg) |
1006 | do_gettimeofday(&tv); | 1065 | { |
1066 | struct fw_cdev_get_cycle_timer *a = &arg->get_cycle_timer; | ||
1067 | struct fw_cdev_get_cycle_timer2 ct2; | ||
1007 | 1068 | ||
1008 | local_irq_restore(flags); | 1069 | ct2.clk_id = CLOCK_REALTIME; |
1009 | preempt_enable(); | 1070 | ioctl_get_cycle_timer2(client, (union ioctl_arg *)&ct2); |
1071 | |||
1072 | a->local_time = ct2.tv_sec * USEC_PER_SEC + ct2.tv_nsec / NSEC_PER_USEC; | ||
1073 | a->cycle_timer = ct2.cycle_timer; | ||
1010 | 1074 | ||
1011 | request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec; | ||
1012 | request->cycle_timer = bus_time & 0xffffffff; | ||
1013 | return 0; | 1075 | return 0; |
1014 | } | 1076 | } |
1015 | 1077 | ||
@@ -1028,8 +1090,7 @@ static void iso_resource_work(struct work_struct *work) | |||
1028 | /* Allow 1000ms grace period for other reallocations. */ | 1090 | /* Allow 1000ms grace period for other reallocations. */ |
1029 | if (todo == ISO_RES_ALLOC && | 1091 | if (todo == ISO_RES_ALLOC && |
1030 | time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) { | 1092 | time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) { |
1031 | if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3))) | 1093 | schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3)); |
1032 | client_get(client); | ||
1033 | skip = true; | 1094 | skip = true; |
1034 | } else { | 1095 | } else { |
1035 | /* We could be called twice within the same generation. */ | 1096 | /* We could be called twice within the same generation. */ |
@@ -1097,12 +1158,12 @@ static void iso_resource_work(struct work_struct *work) | |||
1097 | e = r->e_dealloc; | 1158 | e = r->e_dealloc; |
1098 | r->e_dealloc = NULL; | 1159 | r->e_dealloc = NULL; |
1099 | } | 1160 | } |
1100 | e->resource.handle = r->resource.handle; | 1161 | e->iso_resource.handle = r->resource.handle; |
1101 | e->resource.channel = channel; | 1162 | e->iso_resource.channel = channel; |
1102 | e->resource.bandwidth = bandwidth; | 1163 | e->iso_resource.bandwidth = bandwidth; |
1103 | 1164 | ||
1104 | queue_event(client, &e->event, | 1165 | queue_event(client, &e->event, |
1105 | &e->resource, sizeof(e->resource), NULL, 0); | 1166 | &e->iso_resource, sizeof(e->iso_resource), NULL, 0); |
1106 | 1167 | ||
1107 | if (free) { | 1168 | if (free) { |
1108 | cancel_delayed_work(&r->work); | 1169 | cancel_delayed_work(&r->work); |
@@ -1114,13 +1175,6 @@ static void iso_resource_work(struct work_struct *work) | |||
1114 | client_put(client); | 1175 | client_put(client); |
1115 | } | 1176 | } |
1116 | 1177 | ||
1117 | static void schedule_iso_resource(struct iso_resource *r) | ||
1118 | { | ||
1119 | client_get(r->client); | ||
1120 | if (!schedule_delayed_work(&r->work, 0)) | ||
1121 | client_put(r->client); | ||
1122 | } | ||
1123 | |||
1124 | static void release_iso_resource(struct client *client, | 1178 | static void release_iso_resource(struct client *client, |
1125 | struct client_resource *resource) | 1179 | struct client_resource *resource) |
1126 | { | 1180 | { |
@@ -1129,7 +1183,7 @@ static void release_iso_resource(struct client *client, | |||
1129 | 1183 | ||
1130 | spin_lock_irq(&client->lock); | 1184 | spin_lock_irq(&client->lock); |
1131 | r->todo = ISO_RES_DEALLOC; | 1185 | r->todo = ISO_RES_DEALLOC; |
1132 | schedule_iso_resource(r); | 1186 | schedule_iso_resource(r, 0); |
1133 | spin_unlock_irq(&client->lock); | 1187 | spin_unlock_irq(&client->lock); |
1134 | } | 1188 | } |
1135 | 1189 | ||
@@ -1162,10 +1216,10 @@ static int init_iso_resource(struct client *client, | |||
1162 | r->e_alloc = e1; | 1216 | r->e_alloc = e1; |
1163 | r->e_dealloc = e2; | 1217 | r->e_dealloc = e2; |
1164 | 1218 | ||
1165 | e1->resource.closure = request->closure; | 1219 | e1->iso_resource.closure = request->closure; |
1166 | e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; | 1220 | e1->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; |
1167 | e2->resource.closure = request->closure; | 1221 | e2->iso_resource.closure = request->closure; |
1168 | e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; | 1222 | e2->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; |
1169 | 1223 | ||
1170 | if (todo == ISO_RES_ALLOC) { | 1224 | if (todo == ISO_RES_ALLOC) { |
1171 | r->resource.release = release_iso_resource; | 1225 | r->resource.release = release_iso_resource; |
@@ -1175,7 +1229,7 @@ static int init_iso_resource(struct client *client, | |||
1175 | } else { | 1229 | } else { |
1176 | r->resource.release = NULL; | 1230 | r->resource.release = NULL; |
1177 | r->resource.handle = -1; | 1231 | r->resource.handle = -1; |
1178 | schedule_iso_resource(r); | 1232 | schedule_iso_resource(r, 0); |
1179 | } | 1233 | } |
1180 | request->handle = r->resource.handle; | 1234 | request->handle = r->resource.handle; |
1181 | 1235 | ||
@@ -1188,33 +1242,32 @@ static int init_iso_resource(struct client *client, | |||
1188 | return ret; | 1242 | return ret; |
1189 | } | 1243 | } |
1190 | 1244 | ||
1191 | static int ioctl_allocate_iso_resource(struct client *client, void *buffer) | 1245 | static int ioctl_allocate_iso_resource(struct client *client, |
1246 | union ioctl_arg *arg) | ||
1192 | { | 1247 | { |
1193 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1248 | return init_iso_resource(client, |
1194 | 1249 | &arg->allocate_iso_resource, ISO_RES_ALLOC); | |
1195 | return init_iso_resource(client, request, ISO_RES_ALLOC); | ||
1196 | } | 1250 | } |
1197 | 1251 | ||
1198 | static int ioctl_deallocate_iso_resource(struct client *client, void *buffer) | 1252 | static int ioctl_deallocate_iso_resource(struct client *client, |
1253 | union ioctl_arg *arg) | ||
1199 | { | 1254 | { |
1200 | struct fw_cdev_deallocate *request = buffer; | 1255 | return release_client_resource(client, |
1201 | 1256 | arg->deallocate.handle, release_iso_resource, NULL); | |
1202 | return release_client_resource(client, request->handle, | ||
1203 | release_iso_resource, NULL); | ||
1204 | } | 1257 | } |
1205 | 1258 | ||
1206 | static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer) | 1259 | static int ioctl_allocate_iso_resource_once(struct client *client, |
1260 | union ioctl_arg *arg) | ||
1207 | { | 1261 | { |
1208 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1262 | return init_iso_resource(client, |
1209 | 1263 | &arg->allocate_iso_resource, ISO_RES_ALLOC_ONCE); | |
1210 | return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE); | ||
1211 | } | 1264 | } |
1212 | 1265 | ||
1213 | static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer) | 1266 | static int ioctl_deallocate_iso_resource_once(struct client *client, |
1267 | union ioctl_arg *arg) | ||
1214 | { | 1268 | { |
1215 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1269 | return init_iso_resource(client, |
1216 | 1270 | &arg->allocate_iso_resource, ISO_RES_DEALLOC_ONCE); | |
1217 | return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE); | ||
1218 | } | 1271 | } |
1219 | 1272 | ||
1220 | /* | 1273 | /* |
@@ -1222,16 +1275,17 @@ static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffe | |||
1222 | * limited by the device's link speed, the local node's link speed, | 1275 | * limited by the device's link speed, the local node's link speed, |
1223 | * and all PHY port speeds between the two links. | 1276 | * and all PHY port speeds between the two links. |
1224 | */ | 1277 | */ |
1225 | static int ioctl_get_speed(struct client *client, void *buffer) | 1278 | static int ioctl_get_speed(struct client *client, union ioctl_arg *arg) |
1226 | { | 1279 | { |
1227 | return client->device->max_speed; | 1280 | return client->device->max_speed; |
1228 | } | 1281 | } |
1229 | 1282 | ||
1230 | static int ioctl_send_broadcast_request(struct client *client, void *buffer) | 1283 | static int ioctl_send_broadcast_request(struct client *client, |
1284 | union ioctl_arg *arg) | ||
1231 | { | 1285 | { |
1232 | struct fw_cdev_send_request *request = buffer; | 1286 | struct fw_cdev_send_request *a = &arg->send_request; |
1233 | 1287 | ||
1234 | switch (request->tcode) { | 1288 | switch (a->tcode) { |
1235 | case TCODE_WRITE_QUADLET_REQUEST: | 1289 | case TCODE_WRITE_QUADLET_REQUEST: |
1236 | case TCODE_WRITE_BLOCK_REQUEST: | 1290 | case TCODE_WRITE_BLOCK_REQUEST: |
1237 | break; | 1291 | break; |
@@ -1240,36 +1294,36 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer) | |||
1240 | } | 1294 | } |
1241 | 1295 | ||
1242 | /* Security policy: Only allow accesses to Units Space. */ | 1296 | /* Security policy: Only allow accesses to Units Space. */ |
1243 | if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) | 1297 | if (a->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) |
1244 | return -EACCES; | 1298 | return -EACCES; |
1245 | 1299 | ||
1246 | return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); | 1300 | return init_request(client, a, LOCAL_BUS | 0x3f, SCODE_100); |
1247 | } | 1301 | } |
1248 | 1302 | ||
1249 | static int ioctl_send_stream_packet(struct client *client, void *buffer) | 1303 | static int ioctl_send_stream_packet(struct client *client, union ioctl_arg *arg) |
1250 | { | 1304 | { |
1251 | struct fw_cdev_send_stream_packet *p = buffer; | 1305 | struct fw_cdev_send_stream_packet *a = &arg->send_stream_packet; |
1252 | struct fw_cdev_send_request request; | 1306 | struct fw_cdev_send_request request; |
1253 | int dest; | 1307 | int dest; |
1254 | 1308 | ||
1255 | if (p->speed > client->device->card->link_speed || | 1309 | if (a->speed > client->device->card->link_speed || |
1256 | p->length > 1024 << p->speed) | 1310 | a->length > 1024 << a->speed) |
1257 | return -EIO; | 1311 | return -EIO; |
1258 | 1312 | ||
1259 | if (p->tag > 3 || p->channel > 63 || p->sy > 15) | 1313 | if (a->tag > 3 || a->channel > 63 || a->sy > 15) |
1260 | return -EINVAL; | 1314 | return -EINVAL; |
1261 | 1315 | ||
1262 | dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy); | 1316 | dest = fw_stream_packet_destination_id(a->tag, a->channel, a->sy); |
1263 | request.tcode = TCODE_STREAM_DATA; | 1317 | request.tcode = TCODE_STREAM_DATA; |
1264 | request.length = p->length; | 1318 | request.length = a->length; |
1265 | request.closure = p->closure; | 1319 | request.closure = a->closure; |
1266 | request.data = p->data; | 1320 | request.data = a->data; |
1267 | request.generation = p->generation; | 1321 | request.generation = a->generation; |
1268 | 1322 | ||
1269 | return init_request(client, &request, dest, p->speed); | 1323 | return init_request(client, &request, dest, a->speed); |
1270 | } | 1324 | } |
1271 | 1325 | ||
1272 | static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | 1326 | static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = { |
1273 | ioctl_get_info, | 1327 | ioctl_get_info, |
1274 | ioctl_send_request, | 1328 | ioctl_send_request, |
1275 | ioctl_allocate, | 1329 | ioctl_allocate, |
@@ -1290,33 +1344,37 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | |||
1290 | ioctl_get_speed, | 1344 | ioctl_get_speed, |
1291 | ioctl_send_broadcast_request, | 1345 | ioctl_send_broadcast_request, |
1292 | ioctl_send_stream_packet, | 1346 | ioctl_send_stream_packet, |
1347 | ioctl_get_cycle_timer2, | ||
1293 | }; | 1348 | }; |
1294 | 1349 | ||
1295 | static int dispatch_ioctl(struct client *client, | 1350 | static int dispatch_ioctl(struct client *client, |
1296 | unsigned int cmd, void __user *arg) | 1351 | unsigned int cmd, void __user *arg) |
1297 | { | 1352 | { |
1298 | char buffer[256]; | 1353 | union ioctl_arg buffer; |
1299 | int ret; | 1354 | int ret; |
1300 | 1355 | ||
1356 | if (fw_device_is_shutdown(client->device)) | ||
1357 | return -ENODEV; | ||
1358 | |||
1301 | if (_IOC_TYPE(cmd) != '#' || | 1359 | if (_IOC_TYPE(cmd) != '#' || |
1302 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) | 1360 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || |
1361 | _IOC_SIZE(cmd) > sizeof(buffer)) | ||
1303 | return -EINVAL; | 1362 | return -EINVAL; |
1304 | 1363 | ||
1305 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 1364 | if (_IOC_DIR(cmd) == _IOC_READ) |
1306 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1365 | memset(&buffer, 0, _IOC_SIZE(cmd)); |
1307 | copy_from_user(buffer, arg, _IOC_SIZE(cmd))) | 1366 | |
1367 | if (_IOC_DIR(cmd) & _IOC_WRITE) | ||
1368 | if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) | ||
1308 | return -EFAULT; | 1369 | return -EFAULT; |
1309 | } | ||
1310 | 1370 | ||
1311 | ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer); | 1371 | ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer); |
1312 | if (ret < 0) | 1372 | if (ret < 0) |
1313 | return ret; | 1373 | return ret; |
1314 | 1374 | ||
1315 | if (_IOC_DIR(cmd) & _IOC_READ) { | 1375 | if (_IOC_DIR(cmd) & _IOC_READ) |
1316 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1376 | if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) |
1317 | copy_to_user(arg, buffer, _IOC_SIZE(cmd))) | ||
1318 | return -EFAULT; | 1377 | return -EFAULT; |
1319 | } | ||
1320 | 1378 | ||
1321 | return ret; | 1379 | return ret; |
1322 | } | 1380 | } |
@@ -1324,24 +1382,14 @@ static int dispatch_ioctl(struct client *client, | |||
1324 | static long fw_device_op_ioctl(struct file *file, | 1382 | static long fw_device_op_ioctl(struct file *file, |
1325 | unsigned int cmd, unsigned long arg) | 1383 | unsigned int cmd, unsigned long arg) |
1326 | { | 1384 | { |
1327 | struct client *client = file->private_data; | 1385 | return dispatch_ioctl(file->private_data, cmd, (void __user *)arg); |
1328 | |||
1329 | if (fw_device_is_shutdown(client->device)) | ||
1330 | return -ENODEV; | ||
1331 | |||
1332 | return dispatch_ioctl(client, cmd, (void __user *) arg); | ||
1333 | } | 1386 | } |
1334 | 1387 | ||
1335 | #ifdef CONFIG_COMPAT | 1388 | #ifdef CONFIG_COMPAT |
1336 | static long fw_device_op_compat_ioctl(struct file *file, | 1389 | static long fw_device_op_compat_ioctl(struct file *file, |
1337 | unsigned int cmd, unsigned long arg) | 1390 | unsigned int cmd, unsigned long arg) |
1338 | { | 1391 | { |
1339 | struct client *client = file->private_data; | 1392 | return dispatch_ioctl(file->private_data, cmd, compat_ptr(arg)); |
1340 | |||
1341 | if (fw_device_is_shutdown(client->device)) | ||
1342 | return -ENODEV; | ||
1343 | |||
1344 | return dispatch_ioctl(client, cmd, compat_ptr(arg)); | ||
1345 | } | 1393 | } |
1346 | #endif | 1394 | #endif |
1347 | 1395 | ||
@@ -1390,10 +1438,10 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) | |||
1390 | 1438 | ||
1391 | static int shutdown_resource(int id, void *p, void *data) | 1439 | static int shutdown_resource(int id, void *p, void *data) |
1392 | { | 1440 | { |
1393 | struct client_resource *r = p; | 1441 | struct client_resource *resource = p; |
1394 | struct client *client = data; | 1442 | struct client *client = data; |
1395 | 1443 | ||
1396 | r->release(client, r); | 1444 | resource->release(client, resource); |
1397 | client_put(client); | 1445 | client_put(client); |
1398 | 1446 | ||
1399 | return 0; | 1447 | return 0; |
@@ -1402,7 +1450,7 @@ static int shutdown_resource(int id, void *p, void *data) | |||
1402 | static int fw_device_op_release(struct inode *inode, struct file *file) | 1450 | static int fw_device_op_release(struct inode *inode, struct file *file) |
1403 | { | 1451 | { |
1404 | struct client *client = file->private_data; | 1452 | struct client *client = file->private_data; |
1405 | struct event *e, *next_e; | 1453 | struct event *event, *next_event; |
1406 | 1454 | ||
1407 | mutex_lock(&client->device->client_list_mutex); | 1455 | mutex_lock(&client->device->client_list_mutex); |
1408 | list_del(&client->link); | 1456 | list_del(&client->link); |
@@ -1423,8 +1471,8 @@ static int fw_device_op_release(struct inode *inode, struct file *file) | |||
1423 | idr_remove_all(&client->resource_idr); | 1471 | idr_remove_all(&client->resource_idr); |
1424 | idr_destroy(&client->resource_idr); | 1472 | idr_destroy(&client->resource_idr); |
1425 | 1473 | ||
1426 | list_for_each_entry_safe(e, next_e, &client->event_list, link) | 1474 | list_for_each_entry_safe(event, next_event, &client->event_list, link) |
1427 | kfree(e); | 1475 | kfree(event); |
1428 | 1476 | ||
1429 | client_put(client); | 1477 | client_put(client); |
1430 | 1478 | ||
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9d0dfcbe2c1c..4b8523f00dce 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/bug.h> | ||
21 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
22 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
23 | #include <linux/device.h> | 24 | #include <linux/device.h> |
@@ -32,7 +33,7 @@ | |||
32 | #include <linux/module.h> | 33 | #include <linux/module.h> |
33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
34 | #include <linux/rwsem.h> | 35 | #include <linux/rwsem.h> |
35 | #include <linux/semaphore.h> | 36 | #include <linux/slab.h> |
36 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
37 | #include <linux/string.h> | 38 | #include <linux/string.h> |
38 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
@@ -43,7 +44,7 @@ | |||
43 | 44 | ||
44 | #include "core.h" | 45 | #include "core.h" |
45 | 46 | ||
46 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p) | 47 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p) |
47 | { | 48 | { |
48 | ci->p = p + 1; | 49 | ci->p = p + 1; |
49 | ci->end = ci->p + (p[0] >> 16); | 50 | ci->end = ci->p + (p[0] >> 16); |
@@ -59,97 +60,141 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value) | |||
59 | } | 60 | } |
60 | EXPORT_SYMBOL(fw_csr_iterator_next); | 61 | EXPORT_SYMBOL(fw_csr_iterator_next); |
61 | 62 | ||
62 | static bool is_fw_unit(struct device *dev); | 63 | static const u32 *search_leaf(const u32 *directory, int search_key) |
63 | |||
64 | static int match_unit_directory(u32 *directory, u32 match_flags, | ||
65 | const struct ieee1394_device_id *id) | ||
66 | { | 64 | { |
67 | struct fw_csr_iterator ci; | 65 | struct fw_csr_iterator ci; |
68 | int key, value, match; | 66 | int last_key = 0, key, value; |
69 | 67 | ||
70 | match = 0; | ||
71 | fw_csr_iterator_init(&ci, directory); | 68 | fw_csr_iterator_init(&ci, directory); |
72 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 69 | while (fw_csr_iterator_next(&ci, &key, &value)) { |
73 | if (key == CSR_VENDOR && value == id->vendor_id) | 70 | if (last_key == search_key && |
74 | match |= IEEE1394_MATCH_VENDOR_ID; | 71 | key == (CSR_DESCRIPTOR | CSR_LEAF)) |
75 | if (key == CSR_MODEL && value == id->model_id) | 72 | return ci.p - 1 + value; |
76 | match |= IEEE1394_MATCH_MODEL_ID; | 73 | |
77 | if (key == CSR_SPECIFIER_ID && value == id->specifier_id) | 74 | last_key = key; |
78 | match |= IEEE1394_MATCH_SPECIFIER_ID; | ||
79 | if (key == CSR_VERSION && value == id->version) | ||
80 | match |= IEEE1394_MATCH_VERSION; | ||
81 | } | 75 | } |
82 | 76 | ||
83 | return (match & match_flags) == match_flags; | 77 | return NULL; |
84 | } | 78 | } |
85 | 79 | ||
86 | static int fw_unit_match(struct device *dev, struct device_driver *drv) | 80 | static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) |
87 | { | 81 | { |
88 | struct fw_unit *unit = fw_unit(dev); | 82 | unsigned int quadlets, i; |
89 | struct fw_device *device; | 83 | char c; |
90 | const struct ieee1394_device_id *id; | ||
91 | |||
92 | /* We only allow binding to fw_units. */ | ||
93 | if (!is_fw_unit(dev)) | ||
94 | return 0; | ||
95 | 84 | ||
96 | device = fw_parent_device(unit); | 85 | if (!size || !buf) |
97 | id = container_of(drv, struct fw_driver, driver)->id_table; | 86 | return -EINVAL; |
98 | 87 | ||
99 | for (; id->match_flags != 0; id++) { | 88 | quadlets = min(block[0] >> 16, 256U); |
100 | if (match_unit_directory(unit->directory, id->match_flags, id)) | 89 | if (quadlets < 2) |
101 | return 1; | 90 | return -ENODATA; |
102 | 91 | ||
103 | /* Also check vendor ID in the root directory. */ | 92 | if (block[1] != 0 || block[2] != 0) |
104 | if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) && | 93 | /* unknown language/character set */ |
105 | match_unit_directory(&device->config_rom[5], | 94 | return -ENODATA; |
106 | IEEE1394_MATCH_VENDOR_ID, id) && | 95 | |
107 | match_unit_directory(unit->directory, id->match_flags | 96 | block += 3; |
108 | & ~IEEE1394_MATCH_VENDOR_ID, id)) | 97 | quadlets -= 2; |
109 | return 1; | 98 | for (i = 0; i < quadlets * 4 && i < size - 1; i++) { |
99 | c = block[i / 4] >> (24 - 8 * (i % 4)); | ||
100 | if (c == '\0') | ||
101 | break; | ||
102 | buf[i] = c; | ||
110 | } | 103 | } |
104 | buf[i] = '\0'; | ||
111 | 105 | ||
112 | return 0; | 106 | return i; |
113 | } | 107 | } |
114 | 108 | ||
115 | static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) | 109 | /** |
110 | * fw_csr_string - reads a string from the configuration ROM | ||
111 | * @directory: e.g. root directory or unit directory | ||
112 | * @key: the key of the preceding directory entry | ||
113 | * @buf: where to put the string | ||
114 | * @size: size of @buf, in bytes | ||
115 | * | ||
116 | * The string is taken from a minimal ASCII text descriptor leaf after | ||
117 | * the immediate entry with @key. The string is zero-terminated. | ||
118 | * Returns strlen(buf) or a negative error code. | ||
119 | */ | ||
120 | int fw_csr_string(const u32 *directory, int key, char *buf, size_t size) | ||
116 | { | 121 | { |
117 | struct fw_device *device = fw_parent_device(unit); | 122 | const u32 *leaf = search_leaf(directory, key); |
118 | struct fw_csr_iterator ci; | 123 | if (!leaf) |
124 | return -ENOENT; | ||
125 | |||
126 | return textual_leaf_to_string(leaf, buf, size); | ||
127 | } | ||
128 | EXPORT_SYMBOL(fw_csr_string); | ||
119 | 129 | ||
130 | static void get_ids(const u32 *directory, int *id) | ||
131 | { | ||
132 | struct fw_csr_iterator ci; | ||
120 | int key, value; | 133 | int key, value; |
121 | int vendor = 0; | ||
122 | int model = 0; | ||
123 | int specifier_id = 0; | ||
124 | int version = 0; | ||
125 | 134 | ||
126 | fw_csr_iterator_init(&ci, &device->config_rom[5]); | 135 | fw_csr_iterator_init(&ci, directory); |
127 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 136 | while (fw_csr_iterator_next(&ci, &key, &value)) { |
128 | switch (key) { | 137 | switch (key) { |
129 | case CSR_VENDOR: | 138 | case CSR_VENDOR: id[0] = value; break; |
130 | vendor = value; | 139 | case CSR_MODEL: id[1] = value; break; |
131 | break; | 140 | case CSR_SPECIFIER_ID: id[2] = value; break; |
132 | case CSR_MODEL: | 141 | case CSR_VERSION: id[3] = value; break; |
133 | model = value; | ||
134 | break; | ||
135 | } | 142 | } |
136 | } | 143 | } |
144 | } | ||
137 | 145 | ||
138 | fw_csr_iterator_init(&ci, unit->directory); | 146 | static void get_modalias_ids(struct fw_unit *unit, int *id) |
139 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 147 | { |
140 | switch (key) { | 148 | get_ids(&fw_parent_device(unit)->config_rom[5], id); |
141 | case CSR_SPECIFIER_ID: | 149 | get_ids(unit->directory, id); |
142 | specifier_id = value; | 150 | } |
143 | break; | 151 | |
144 | case CSR_VERSION: | 152 | static bool match_ids(const struct ieee1394_device_id *id_table, int *id) |
145 | version = value; | 153 | { |
146 | break; | 154 | int match = 0; |
147 | } | 155 | |
148 | } | 156 | if (id[0] == id_table->vendor_id) |
157 | match |= IEEE1394_MATCH_VENDOR_ID; | ||
158 | if (id[1] == id_table->model_id) | ||
159 | match |= IEEE1394_MATCH_MODEL_ID; | ||
160 | if (id[2] == id_table->specifier_id) | ||
161 | match |= IEEE1394_MATCH_SPECIFIER_ID; | ||
162 | if (id[3] == id_table->version) | ||
163 | match |= IEEE1394_MATCH_VERSION; | ||
164 | |||
165 | return (match & id_table->match_flags) == id_table->match_flags; | ||
166 | } | ||
167 | |||
168 | static bool is_fw_unit(struct device *dev); | ||
169 | |||
170 | static int fw_unit_match(struct device *dev, struct device_driver *drv) | ||
171 | { | ||
172 | const struct ieee1394_device_id *id_table = | ||
173 | container_of(drv, struct fw_driver, driver)->id_table; | ||
174 | int id[] = {0, 0, 0, 0}; | ||
175 | |||
176 | /* We only allow binding to fw_units. */ | ||
177 | if (!is_fw_unit(dev)) | ||
178 | return 0; | ||
179 | |||
180 | get_modalias_ids(fw_unit(dev), id); | ||
181 | |||
182 | for (; id_table->match_flags != 0; id_table++) | ||
183 | if (match_ids(id_table, id)) | ||
184 | return 1; | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) | ||
190 | { | ||
191 | int id[] = {0, 0, 0, 0}; | ||
192 | |||
193 | get_modalias_ids(unit, id); | ||
149 | 194 | ||
150 | return snprintf(buffer, buffer_size, | 195 | return snprintf(buffer, buffer_size, |
151 | "ieee1394:ven%08Xmo%08Xsp%08Xver%08X", | 196 | "ieee1394:ven%08Xmo%08Xsp%08Xver%08X", |
152 | vendor, model, specifier_id, version); | 197 | id[0], id[1], id[2], id[3]); |
153 | } | 198 | } |
154 | 199 | ||
155 | static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env) | 200 | static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env) |
@@ -195,7 +240,7 @@ static ssize_t show_immediate(struct device *dev, | |||
195 | struct config_rom_attribute *attr = | 240 | struct config_rom_attribute *attr = |
196 | container_of(dattr, struct config_rom_attribute, attr); | 241 | container_of(dattr, struct config_rom_attribute, attr); |
197 | struct fw_csr_iterator ci; | 242 | struct fw_csr_iterator ci; |
198 | u32 *dir; | 243 | const u32 *dir; |
199 | int key, value, ret = -ENOENT; | 244 | int key, value, ret = -ENOENT; |
200 | 245 | ||
201 | down_read(&fw_device_rwsem); | 246 | down_read(&fw_device_rwsem); |
@@ -226,10 +271,10 @@ static ssize_t show_text_leaf(struct device *dev, | |||
226 | { | 271 | { |
227 | struct config_rom_attribute *attr = | 272 | struct config_rom_attribute *attr = |
228 | container_of(dattr, struct config_rom_attribute, attr); | 273 | container_of(dattr, struct config_rom_attribute, attr); |
229 | struct fw_csr_iterator ci; | 274 | const u32 *dir; |
230 | u32 *dir, *block = NULL, *p, *end; | 275 | size_t bufsize; |
231 | int length, key, value, last_key = 0, ret = -ENOENT; | 276 | char dummy_buf[2]; |
232 | char *b; | 277 | int ret; |
233 | 278 | ||
234 | down_read(&fw_device_rwsem); | 279 | down_read(&fw_device_rwsem); |
235 | 280 | ||
@@ -238,40 +283,23 @@ static ssize_t show_text_leaf(struct device *dev, | |||
238 | else | 283 | else |
239 | dir = fw_device(dev)->config_rom + 5; | 284 | dir = fw_device(dev)->config_rom + 5; |
240 | 285 | ||
241 | fw_csr_iterator_init(&ci, dir); | 286 | if (buf) { |
242 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 287 | bufsize = PAGE_SIZE - 1; |
243 | if (attr->key == last_key && | 288 | } else { |
244 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | 289 | buf = dummy_buf; |
245 | block = ci.p - 1 + value; | 290 | bufsize = 1; |
246 | last_key = key; | ||
247 | } | 291 | } |
248 | 292 | ||
249 | if (block == NULL) | 293 | ret = fw_csr_string(dir, attr->key, buf, bufsize); |
250 | goto out; | ||
251 | |||
252 | length = min(block[0] >> 16, 256U); | ||
253 | if (length < 3) | ||
254 | goto out; | ||
255 | |||
256 | if (block[1] != 0 || block[2] != 0) | ||
257 | /* Unknown encoding. */ | ||
258 | goto out; | ||
259 | 294 | ||
260 | if (buf == NULL) { | 295 | if (ret >= 0) { |
261 | ret = length * 4; | 296 | /* Strip trailing whitespace and add newline. */ |
262 | goto out; | 297 | while (ret > 0 && isspace(buf[ret - 1])) |
298 | ret--; | ||
299 | strcpy(buf + ret, "\n"); | ||
300 | ret++; | ||
263 | } | 301 | } |
264 | 302 | ||
265 | b = buf; | ||
266 | end = &block[length + 1]; | ||
267 | for (p = &block[3]; p < end; p++, b += 4) | ||
268 | * (u32 *) b = (__force u32) __cpu_to_be32(*p); | ||
269 | |||
270 | /* Strip trailing whitespace and add newline. */ | ||
271 | while (b--, (isspace(*b) || *b == '\0') && b > buf); | ||
272 | strcpy(b + 1, "\n"); | ||
273 | ret = b + 2 - buf; | ||
274 | out: | ||
275 | up_read(&fw_device_rwsem); | 303 | up_read(&fw_device_rwsem); |
276 | 304 | ||
277 | return ret; | 305 | return ret; |
@@ -371,7 +399,7 @@ static ssize_t guid_show(struct device *dev, | |||
371 | return ret; | 399 | return ret; |
372 | } | 400 | } |
373 | 401 | ||
374 | static int units_sprintf(char *buf, u32 *directory) | 402 | static int units_sprintf(char *buf, const u32 *directory) |
375 | { | 403 | { |
376 | struct fw_csr_iterator ci; | 404 | struct fw_csr_iterator ci; |
377 | int key, value; | 405 | int key, value; |
@@ -441,28 +469,29 @@ static int read_rom(struct fw_device *device, | |||
441 | return rcode; | 469 | return rcode; |
442 | } | 470 | } |
443 | 471 | ||
444 | #define READ_BIB_ROM_SIZE 256 | 472 | #define MAX_CONFIG_ROM_SIZE 256 |
445 | #define READ_BIB_STACK_SIZE 16 | ||
446 | 473 | ||
447 | /* | 474 | /* |
448 | * Read the bus info block, perform a speed probe, and read all of the rest of | 475 | * Read the bus info block, perform a speed probe, and read all of the rest of |
449 | * the config ROM. We do all this with a cached bus generation. If the bus | 476 | * the config ROM. We do all this with a cached bus generation. If the bus |
450 | * generation changes under us, read_bus_info_block will fail and get retried. | 477 | * generation changes under us, read_config_rom will fail and get retried. |
451 | * It's better to start all over in this case because the node from which we | 478 | * It's better to start all over in this case because the node from which we |
452 | * are reading the ROM may have changed the ROM during the reset. | 479 | * are reading the ROM may have changed the ROM during the reset. |
453 | */ | 480 | */ |
454 | static int read_bus_info_block(struct fw_device *device, int generation) | 481 | static int read_config_rom(struct fw_device *device, int generation) |
455 | { | 482 | { |
456 | u32 *rom, *stack, *old_rom, *new_rom; | 483 | const u32 *old_rom, *new_rom; |
484 | u32 *rom, *stack; | ||
457 | u32 sp, key; | 485 | u32 sp, key; |
458 | int i, end, length, ret = -1; | 486 | int i, end, length, ret = -1; |
459 | 487 | ||
460 | rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE + | 488 | rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE + |
461 | sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL); | 489 | sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL); |
462 | if (rom == NULL) | 490 | if (rom == NULL) |
463 | return -ENOMEM; | 491 | return -ENOMEM; |
464 | 492 | ||
465 | stack = &rom[READ_BIB_ROM_SIZE]; | 493 | stack = &rom[MAX_CONFIG_ROM_SIZE]; |
494 | memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE); | ||
466 | 495 | ||
467 | device->max_speed = SCODE_100; | 496 | device->max_speed = SCODE_100; |
468 | 497 | ||
@@ -529,40 +558,54 @@ static int read_bus_info_block(struct fw_device *device, int generation) | |||
529 | */ | 558 | */ |
530 | key = stack[--sp]; | 559 | key = stack[--sp]; |
531 | i = key & 0xffffff; | 560 | i = key & 0xffffff; |
532 | if (i >= READ_BIB_ROM_SIZE) | 561 | if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) |
533 | /* | ||
534 | * The reference points outside the standard | ||
535 | * config rom area, something's fishy. | ||
536 | */ | ||
537 | goto out; | 562 | goto out; |
538 | 563 | ||
539 | /* Read header quadlet for the block to get the length. */ | 564 | /* Read header quadlet for the block to get the length. */ |
540 | if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) | 565 | if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) |
541 | goto out; | 566 | goto out; |
542 | end = i + (rom[i] >> 16) + 1; | 567 | end = i + (rom[i] >> 16) + 1; |
543 | i++; | 568 | if (end > MAX_CONFIG_ROM_SIZE) { |
544 | if (end > READ_BIB_ROM_SIZE) | ||
545 | /* | 569 | /* |
546 | * This block extends outside standard config | 570 | * This block extends outside the config ROM which is |
547 | * area (and the array we're reading it | 571 | * a firmware bug. Ignore this whole block, i.e. |
548 | * into). That's broken, so ignore this | 572 | * simply set a fake block length of 0. |
549 | * device. | ||
550 | */ | 573 | */ |
551 | goto out; | 574 | fw_error("skipped invalid ROM block %x at %llx\n", |
575 | rom[i], | ||
576 | i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM); | ||
577 | rom[i] = 0; | ||
578 | end = i; | ||
579 | } | ||
580 | i++; | ||
552 | 581 | ||
553 | /* | 582 | /* |
554 | * Now read in the block. If this is a directory | 583 | * Now read in the block. If this is a directory |
555 | * block, check the entries as we read them to see if | 584 | * block, check the entries as we read them to see if |
556 | * it references another block, and push it in that case. | 585 | * it references another block, and push it in that case. |
557 | */ | 586 | */ |
558 | while (i < end) { | 587 | for (; i < end; i++) { |
559 | if (read_rom(device, generation, i, &rom[i]) != | 588 | if (read_rom(device, generation, i, &rom[i]) != |
560 | RCODE_COMPLETE) | 589 | RCODE_COMPLETE) |
561 | goto out; | 590 | goto out; |
562 | if ((key >> 30) == 3 && (rom[i] >> 30) > 1 && | 591 | |
563 | sp < READ_BIB_STACK_SIZE) | 592 | if ((key >> 30) != 3 || (rom[i] >> 30) < 2) |
564 | stack[sp++] = i + rom[i]; | 593 | continue; |
565 | i++; | 594 | /* |
595 | * Offset points outside the ROM. May be a firmware | ||
596 | * bug or an Extended ROM entry (IEEE 1212-2001 clause | ||
597 | * 7.7.18). Simply overwrite this pointer here by a | ||
598 | * fake immediate entry so that later iterators over | ||
599 | * the ROM don't have to check offsets all the time. | ||
600 | */ | ||
601 | if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) { | ||
602 | fw_error("skipped unsupported ROM entry %x at %llx\n", | ||
603 | rom[i], | ||
604 | i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM); | ||
605 | rom[i] = 0; | ||
606 | continue; | ||
607 | } | ||
608 | stack[sp++] = i + rom[i]; | ||
566 | } | 609 | } |
567 | if (length < i) | 610 | if (length < i) |
568 | length = i; | 611 | length = i; |
@@ -762,9 +805,9 @@ static int update_unit(struct device *dev, void *data) | |||
762 | struct fw_driver *driver = (struct fw_driver *)dev->driver; | 805 | struct fw_driver *driver = (struct fw_driver *)dev->driver; |
763 | 806 | ||
764 | if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) { | 807 | if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) { |
765 | down(&dev->sem); | 808 | device_lock(dev); |
766 | driver->update(unit); | 809 | driver->update(unit); |
767 | up(&dev->sem); | 810 | device_unlock(dev); |
768 | } | 811 | } |
769 | 812 | ||
770 | return 0; | 813 | return 0; |
@@ -905,7 +948,7 @@ static void fw_device_init(struct work_struct *work) | |||
905 | * device. | 948 | * device. |
906 | */ | 949 | */ |
907 | 950 | ||
908 | if (read_bus_info_block(device, device->generation) < 0) { | 951 | if (read_config_rom(device, device->generation) < 0) { |
909 | if (device->config_rom_retries < MAX_RETRIES && | 952 | if (device->config_rom_retries < MAX_RETRIES && |
910 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 953 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
911 | device->config_rom_retries++; | 954 | device->config_rom_retries++; |
@@ -1022,7 +1065,7 @@ enum { | |||
1022 | }; | 1065 | }; |
1023 | 1066 | ||
1024 | /* Reread and compare bus info block and header of root directory */ | 1067 | /* Reread and compare bus info block and header of root directory */ |
1025 | static int reread_bus_info_block(struct fw_device *device, int generation) | 1068 | static int reread_config_rom(struct fw_device *device, int generation) |
1026 | { | 1069 | { |
1027 | u32 q; | 1070 | u32 q; |
1028 | int i; | 1071 | int i; |
@@ -1048,7 +1091,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1048 | struct fw_card *card = device->card; | 1091 | struct fw_card *card = device->card; |
1049 | int node_id = device->node_id; | 1092 | int node_id = device->node_id; |
1050 | 1093 | ||
1051 | switch (reread_bus_info_block(device, device->generation)) { | 1094 | switch (reread_config_rom(device, device->generation)) { |
1052 | case REREAD_BIB_ERROR: | 1095 | case REREAD_BIB_ERROR: |
1053 | if (device->config_rom_retries < MAX_RETRIES / 2 && | 1096 | if (device->config_rom_retries < MAX_RETRIES / 2 && |
1054 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1097 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
@@ -1082,7 +1125,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1082 | */ | 1125 | */ |
1083 | device_for_each_child(&device->device, NULL, shutdown_unit); | 1126 | device_for_each_child(&device->device, NULL, shutdown_unit); |
1084 | 1127 | ||
1085 | if (read_bus_info_block(device, device->generation) < 0) { | 1128 | if (read_config_rom(device, device->generation) < 0) { |
1086 | if (device->config_rom_retries < MAX_RETRIES && | 1129 | if (device->config_rom_retries < MAX_RETRIES && |
1087 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1130 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
1088 | device->config_rom_retries++; | 1131 | device->config_rom_retries++; |
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 1c0b504a42f3..8f5aebfb29df 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/firewire-constants.h> | 26 | #include <linux/firewire-constants.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
30 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
31 | 32 | ||
@@ -189,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | |||
189 | for (try = 0; try < 5; try++) { | 190 | for (try = 0; try < 5; try++) { |
190 | new = allocate ? old - bandwidth : old + bandwidth; | 191 | new = allocate ? old - bandwidth : old + bandwidth; |
191 | if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL) | 192 | if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL) |
192 | break; | 193 | return -EBUSY; |
193 | 194 | ||
194 | data[0] = cpu_to_be32(old); | 195 | data[0] = cpu_to_be32(old); |
195 | data[1] = cpu_to_be32(new); | 196 | data[1] = cpu_to_be32(new); |
@@ -217,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
217 | u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) | 218 | u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) |
218 | { | 219 | { |
219 | __be32 c, all, old; | 220 | __be32 c, all, old; |
220 | int i, retry = 5; | 221 | int i, ret = -EIO, retry = 5; |
221 | 222 | ||
222 | old = all = allocate ? cpu_to_be32(~0) : 0; | 223 | old = all = allocate ? cpu_to_be32(~0) : 0; |
223 | 224 | ||
@@ -225,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
225 | if (!(channels_mask & 1 << i)) | 226 | if (!(channels_mask & 1 << i)) |
226 | continue; | 227 | continue; |
227 | 228 | ||
229 | ret = -EBUSY; | ||
230 | |||
228 | c = cpu_to_be32(1 << (31 - i)); | 231 | c = cpu_to_be32(1 << (31 - i)); |
229 | if ((old & c) != (all & c)) | 232 | if ((old & c) != (all & c)) |
230 | continue; | 233 | continue; |
@@ -250,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
250 | 253 | ||
251 | /* 1394-1995 IRM, fall through to retry. */ | 254 | /* 1394-1995 IRM, fall through to retry. */ |
252 | default: | 255 | default: |
253 | if (retry--) | 256 | if (retry) { |
257 | retry--; | ||
254 | i--; | 258 | i--; |
259 | } else { | ||
260 | ret = -EIO; | ||
261 | } | ||
255 | } | 262 | } |
256 | } | 263 | } |
257 | 264 | ||
258 | return -EIO; | 265 | return ret; |
259 | } | 266 | } |
260 | 267 | ||
261 | static void deallocate_channel(struct fw_card *card, int irm_id, | 268 | static void deallocate_channel(struct fw_card *card, int irm_id, |
@@ -331,8 +338,9 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, | |||
331 | if (ret < 0) | 338 | if (ret < 0) |
332 | *bandwidth = 0; | 339 | *bandwidth = 0; |
333 | 340 | ||
334 | if (allocate && ret < 0 && c >= 0) { | 341 | if (allocate && ret < 0) { |
335 | deallocate_channel(card, irm_id, generation, c, buffer); | 342 | if (c >= 0) |
343 | deallocate_channel(card, irm_id, generation, c, buffer); | ||
336 | *channel = ret; | 344 | *channel = ret; |
337 | } | 345 | } |
338 | } | 346 | } |
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index fddf2b358936..93ec64cdeef7 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/string.h> | ||
32 | 31 | ||
33 | #include <asm/atomic.h> | 32 | #include <asm/atomic.h> |
33 | #include <asm/byteorder.h> | ||
34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
35 | 35 | ||
36 | #include "core.h" | 36 | #include "core.h" |
@@ -183,7 +183,7 @@ static inline struct fw_node *fw_node(struct list_head *l) | |||
183 | * This function builds the tree representation of the topology given | 183 | * This function builds the tree representation of the topology given |
184 | * by the self IDs from the latest bus reset. During the construction | 184 | * by the self IDs from the latest bus reset. During the construction |
185 | * of the tree, the function checks that the self IDs are valid and | 185 | * of the tree, the function checks that the self IDs are valid and |
186 | * internally consistent. On succcess this function returns the | 186 | * internally consistent. On success this function returns the |
187 | * fw_node corresponding to the local card otherwise NULL. | 187 | * fw_node corresponding to the local card otherwise NULL. |
188 | */ | 188 | */ |
189 | static struct fw_node *build_tree(struct fw_card *card, | 189 | static struct fw_node *build_tree(struct fw_card *card, |
@@ -510,13 +510,16 @@ static void update_tree(struct fw_card *card, struct fw_node *root) | |||
510 | static void update_topology_map(struct fw_card *card, | 510 | static void update_topology_map(struct fw_card *card, |
511 | u32 *self_ids, int self_id_count) | 511 | u32 *self_ids, int self_id_count) |
512 | { | 512 | { |
513 | int node_count; | 513 | int node_count = (card->root_node->node_id & 0x3f) + 1; |
514 | __be32 *map = card->topology_map; | ||
515 | |||
516 | *map++ = cpu_to_be32((self_id_count + 2) << 16); | ||
517 | *map++ = cpu_to_be32(be32_to_cpu(card->topology_map[1]) + 1); | ||
518 | *map++ = cpu_to_be32((node_count << 16) | self_id_count); | ||
519 | |||
520 | while (self_id_count--) | ||
521 | *map++ = cpu_to_be32p(self_ids++); | ||
514 | 522 | ||
515 | card->topology_map[1]++; | ||
516 | node_count = (card->root_node->node_id & 0x3f) + 1; | ||
517 | card->topology_map[2] = (node_count << 16) | self_id_count; | ||
518 | card->topology_map[0] = (self_id_count + 2) << 16; | ||
519 | memcpy(&card->topology_map[3], self_ids, self_id_count * 4); | ||
520 | fw_compute_block_crc(card->topology_map); | 523 | fw_compute_block_crc(card->topology_map); |
521 | } | 524 | } |
522 | 525 | ||
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index da628c72a462..673b03f8b4ec 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -218,12 +218,15 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, | |||
218 | packet->header_length = 16; | 218 | packet->header_length = 16; |
219 | packet->payload_length = 0; | 219 | packet->payload_length = 0; |
220 | break; | 220 | break; |
221 | |||
222 | default: | ||
223 | WARN(1, KERN_ERR "wrong tcode %d", tcode); | ||
221 | } | 224 | } |
222 | common: | 225 | common: |
223 | packet->speed = speed; | 226 | packet->speed = speed; |
224 | packet->generation = generation; | 227 | packet->generation = generation; |
225 | packet->ack = 0; | 228 | packet->ack = 0; |
226 | packet->payload_bus = 0; | 229 | packet->payload_mapped = false; |
227 | } | 230 | } |
228 | 231 | ||
229 | /** | 232 | /** |
@@ -429,14 +432,20 @@ static struct fw_address_handler *lookup_overlapping_address_handler( | |||
429 | return NULL; | 432 | return NULL; |
430 | } | 433 | } |
431 | 434 | ||
435 | static bool is_enclosing_handler(struct fw_address_handler *handler, | ||
436 | unsigned long long offset, size_t length) | ||
437 | { | ||
438 | return handler->offset <= offset && | ||
439 | offset + length <= handler->offset + handler->length; | ||
440 | } | ||
441 | |||
432 | static struct fw_address_handler *lookup_enclosing_address_handler( | 442 | static struct fw_address_handler *lookup_enclosing_address_handler( |
433 | struct list_head *list, unsigned long long offset, size_t length) | 443 | struct list_head *list, unsigned long long offset, size_t length) |
434 | { | 444 | { |
435 | struct fw_address_handler *handler; | 445 | struct fw_address_handler *handler; |
436 | 446 | ||
437 | list_for_each_entry(handler, list, link) { | 447 | list_for_each_entry(handler, list, link) { |
438 | if (handler->offset <= offset && | 448 | if (is_enclosing_handler(handler, offset, length)) |
439 | offset + length <= handler->offset + handler->length) | ||
440 | return handler; | 449 | return handler; |
441 | } | 450 | } |
442 | 451 | ||
@@ -462,6 +471,12 @@ const struct fw_address_region fw_unit_space_region = | |||
462 | { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; | 471 | { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; |
463 | #endif /* 0 */ | 472 | #endif /* 0 */ |
464 | 473 | ||
474 | static bool is_in_fcp_region(u64 offset, size_t length) | ||
475 | { | ||
476 | return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) && | ||
477 | offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END); | ||
478 | } | ||
479 | |||
465 | /** | 480 | /** |
466 | * fw_core_add_address_handler - register for incoming requests | 481 | * fw_core_add_address_handler - register for incoming requests |
467 | * @handler: callback | 482 | * @handler: callback |
@@ -474,8 +489,11 @@ const struct fw_address_region fw_unit_space_region = | |||
474 | * give the details of the particular request. | 489 | * give the details of the particular request. |
475 | * | 490 | * |
476 | * Return value: 0 on success, non-zero otherwise. | 491 | * Return value: 0 on success, non-zero otherwise. |
492 | * | ||
477 | * The start offset of the handler's address region is determined by | 493 | * The start offset of the handler's address region is determined by |
478 | * fw_core_add_address_handler() and is returned in handler->offset. | 494 | * fw_core_add_address_handler() and is returned in handler->offset. |
495 | * | ||
496 | * Address allocations are exclusive, except for the FCP registers. | ||
479 | */ | 497 | */ |
480 | int fw_core_add_address_handler(struct fw_address_handler *handler, | 498 | int fw_core_add_address_handler(struct fw_address_handler *handler, |
481 | const struct fw_address_region *region) | 499 | const struct fw_address_region *region) |
@@ -495,10 +513,12 @@ int fw_core_add_address_handler(struct fw_address_handler *handler, | |||
495 | 513 | ||
496 | handler->offset = region->start; | 514 | handler->offset = region->start; |
497 | while (handler->offset + handler->length <= region->end) { | 515 | while (handler->offset + handler->length <= region->end) { |
498 | other = | 516 | if (is_in_fcp_region(handler->offset, handler->length)) |
499 | lookup_overlapping_address_handler(&address_handler_list, | 517 | other = NULL; |
500 | handler->offset, | 518 | else |
501 | handler->length); | 519 | other = lookup_overlapping_address_handler |
520 | (&address_handler_list, | ||
521 | handler->offset, handler->length); | ||
502 | if (other != NULL) { | 522 | if (other != NULL) { |
503 | handler->offset += other->length; | 523 | handler->offset += other->length; |
504 | } else { | 524 | } else { |
@@ -595,11 +615,10 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header, | |||
595 | break; | 615 | break; |
596 | 616 | ||
597 | default: | 617 | default: |
598 | BUG(); | 618 | WARN(1, KERN_ERR "wrong tcode %d", tcode); |
599 | return; | ||
600 | } | 619 | } |
601 | 620 | ||
602 | response->payload_bus = 0; | 621 | response->payload_mapped = false; |
603 | } | 622 | } |
604 | EXPORT_SYMBOL(fw_fill_response); | 623 | EXPORT_SYMBOL(fw_fill_response); |
605 | 624 | ||
@@ -666,6 +685,9 @@ static struct fw_request *allocate_request(struct fw_packet *p) | |||
666 | void fw_send_response(struct fw_card *card, | 685 | void fw_send_response(struct fw_card *card, |
667 | struct fw_request *request, int rcode) | 686 | struct fw_request *request, int rcode) |
668 | { | 687 | { |
688 | if (WARN_ONCE(!request, "invalid for FCP address handlers")) | ||
689 | return; | ||
690 | |||
669 | /* unified transaction or broadcast transaction: don't respond */ | 691 | /* unified transaction or broadcast transaction: don't respond */ |
670 | if (request->ack != ACK_PENDING || | 692 | if (request->ack != ACK_PENDING || |
671 | HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { | 693 | HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { |
@@ -684,26 +706,15 @@ void fw_send_response(struct fw_card *card, | |||
684 | } | 706 | } |
685 | EXPORT_SYMBOL(fw_send_response); | 707 | EXPORT_SYMBOL(fw_send_response); |
686 | 708 | ||
687 | void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) | 709 | static void handle_exclusive_region_request(struct fw_card *card, |
710 | struct fw_packet *p, | ||
711 | struct fw_request *request, | ||
712 | unsigned long long offset) | ||
688 | { | 713 | { |
689 | struct fw_address_handler *handler; | 714 | struct fw_address_handler *handler; |
690 | struct fw_request *request; | ||
691 | unsigned long long offset; | ||
692 | unsigned long flags; | 715 | unsigned long flags; |
693 | int tcode, destination, source; | 716 | int tcode, destination, source; |
694 | 717 | ||
695 | if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) | ||
696 | return; | ||
697 | |||
698 | request = allocate_request(p); | ||
699 | if (request == NULL) { | ||
700 | /* FIXME: send statically allocated busy packet. */ | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | offset = | ||
705 | ((unsigned long long) | ||
706 | HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2]; | ||
707 | tcode = HEADER_GET_TCODE(p->header[0]); | 718 | tcode = HEADER_GET_TCODE(p->header[0]); |
708 | destination = HEADER_GET_DESTINATION(p->header[0]); | 719 | destination = HEADER_GET_DESTINATION(p->header[0]); |
709 | source = HEADER_GET_SOURCE(p->header[1]); | 720 | source = HEADER_GET_SOURCE(p->header[1]); |
@@ -730,6 +741,73 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) | |||
730 | request->data, request->length, | 741 | request->data, request->length, |
731 | handler->callback_data); | 742 | handler->callback_data); |
732 | } | 743 | } |
744 | |||
745 | static void handle_fcp_region_request(struct fw_card *card, | ||
746 | struct fw_packet *p, | ||
747 | struct fw_request *request, | ||
748 | unsigned long long offset) | ||
749 | { | ||
750 | struct fw_address_handler *handler; | ||
751 | unsigned long flags; | ||
752 | int tcode, destination, source; | ||
753 | |||
754 | if ((offset != (CSR_REGISTER_BASE | CSR_FCP_COMMAND) && | ||
755 | offset != (CSR_REGISTER_BASE | CSR_FCP_RESPONSE)) || | ||
756 | request->length > 0x200) { | ||
757 | fw_send_response(card, request, RCODE_ADDRESS_ERROR); | ||
758 | |||
759 | return; | ||
760 | } | ||
761 | |||
762 | tcode = HEADER_GET_TCODE(p->header[0]); | ||
763 | destination = HEADER_GET_DESTINATION(p->header[0]); | ||
764 | source = HEADER_GET_SOURCE(p->header[1]); | ||
765 | |||
766 | if (tcode != TCODE_WRITE_QUADLET_REQUEST && | ||
767 | tcode != TCODE_WRITE_BLOCK_REQUEST) { | ||
768 | fw_send_response(card, request, RCODE_TYPE_ERROR); | ||
769 | |||
770 | return; | ||
771 | } | ||
772 | |||
773 | spin_lock_irqsave(&address_handler_lock, flags); | ||
774 | list_for_each_entry(handler, &address_handler_list, link) { | ||
775 | if (is_enclosing_handler(handler, offset, request->length)) | ||
776 | handler->address_callback(card, NULL, tcode, | ||
777 | destination, source, | ||
778 | p->generation, p->speed, | ||
779 | offset, request->data, | ||
780 | request->length, | ||
781 | handler->callback_data); | ||
782 | } | ||
783 | spin_unlock_irqrestore(&address_handler_lock, flags); | ||
784 | |||
785 | fw_send_response(card, request, RCODE_COMPLETE); | ||
786 | } | ||
787 | |||
788 | void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) | ||
789 | { | ||
790 | struct fw_request *request; | ||
791 | unsigned long long offset; | ||
792 | |||
793 | if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) | ||
794 | return; | ||
795 | |||
796 | request = allocate_request(p); | ||
797 | if (request == NULL) { | ||
798 | /* FIXME: send statically allocated busy packet. */ | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | | ||
803 | p->header[2]; | ||
804 | |||
805 | if (!is_in_fcp_region(offset, request->length)) | ||
806 | handle_exclusive_region_request(card, p, request, offset); | ||
807 | else | ||
808 | handle_fcp_region_request(card, p, request, offset); | ||
809 | |||
810 | } | ||
733 | EXPORT_SYMBOL(fw_core_handle_request); | 811 | EXPORT_SYMBOL(fw_core_handle_request); |
734 | 812 | ||
735 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | 813 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) |
@@ -810,8 +888,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request | |||
810 | int speed, unsigned long long offset, | 888 | int speed, unsigned long long offset, |
811 | void *payload, size_t length, void *callback_data) | 889 | void *payload, size_t length, void *callback_data) |
812 | { | 890 | { |
813 | int i, start, end; | 891 | int start; |
814 | __be32 *map; | ||
815 | 892 | ||
816 | if (!TCODE_IS_READ_REQUEST(tcode)) { | 893 | if (!TCODE_IS_READ_REQUEST(tcode)) { |
817 | fw_send_response(card, request, RCODE_TYPE_ERROR); | 894 | fw_send_response(card, request, RCODE_TYPE_ERROR); |
@@ -824,11 +901,7 @@ static void handle_topology_map(struct fw_card *card, struct fw_request *request | |||
824 | } | 901 | } |
825 | 902 | ||
826 | start = (offset - topology_map_region.start) / 4; | 903 | start = (offset - topology_map_region.start) / 4; |
827 | end = start + length / 4; | 904 | memcpy(payload, &card->topology_map[start], length); |
828 | map = payload; | ||
829 | |||
830 | for (i = 0; i < length / 4; i++) | ||
831 | map[i] = cpu_to_be32(card->topology_map[start + i]); | ||
832 | 905 | ||
833 | fw_send_response(card, request, RCODE_COMPLETE); | 906 | fw_send_response(card, request, RCODE_COMPLETE); |
834 | } | 907 | } |
@@ -848,23 +921,15 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
848 | void *payload, size_t length, void *callback_data) | 921 | void *payload, size_t length, void *callback_data) |
849 | { | 922 | { |
850 | int reg = offset & ~CSR_REGISTER_BASE; | 923 | int reg = offset & ~CSR_REGISTER_BASE; |
851 | unsigned long long bus_time; | ||
852 | __be32 *data = payload; | 924 | __be32 *data = payload; |
853 | int rcode = RCODE_COMPLETE; | 925 | int rcode = RCODE_COMPLETE; |
854 | 926 | ||
855 | switch (reg) { | 927 | switch (reg) { |
856 | case CSR_CYCLE_TIME: | 928 | case CSR_CYCLE_TIME: |
857 | case CSR_BUS_TIME: | 929 | if (TCODE_IS_READ_REQUEST(tcode) && length == 4) |
858 | if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { | 930 | *data = cpu_to_be32(card->driver->get_cycle_time(card)); |
859 | rcode = RCODE_TYPE_ERROR; | ||
860 | break; | ||
861 | } | ||
862 | |||
863 | bus_time = card->driver->get_bus_time(card); | ||
864 | if (reg == CSR_CYCLE_TIME) | ||
865 | *data = cpu_to_be32(bus_time); | ||
866 | else | 931 | else |
867 | *data = cpu_to_be32(bus_time >> 25); | 932 | rcode = RCODE_TYPE_ERROR; |
868 | break; | 933 | break; |
869 | 934 | ||
870 | case CSR_BROADCAST_CHANNEL: | 935 | case CSR_BROADCAST_CHANNEL: |
@@ -895,6 +960,9 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
895 | case CSR_BUSY_TIMEOUT: | 960 | case CSR_BUSY_TIMEOUT: |
896 | /* FIXME: Implement this. */ | 961 | /* FIXME: Implement this. */ |
897 | 962 | ||
963 | case CSR_BUS_TIME: | ||
964 | /* Useless without initialization by the bus manager. */ | ||
965 | |||
898 | default: | 966 | default: |
899 | rcode = RCODE_ADDRESS_ERROR; | 967 | rcode = RCODE_ADDRESS_ERROR; |
900 | break; | 968 | break; |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 7ff6e7585152..fb0321300cce 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -40,7 +40,8 @@ struct fw_card_driver { | |||
40 | * enable the PHY or set the link_on bit and initiate a bus | 40 | * enable the PHY or set the link_on bit and initiate a bus |
41 | * reset. | 41 | * reset. |
42 | */ | 42 | */ |
43 | int (*enable)(struct fw_card *card, u32 *config_rom, size_t length); | 43 | int (*enable)(struct fw_card *card, |
44 | const __be32 *config_rom, size_t length); | ||
44 | 45 | ||
45 | int (*update_phy_reg)(struct fw_card *card, int address, | 46 | int (*update_phy_reg)(struct fw_card *card, int address, |
46 | int clear_bits, int set_bits); | 47 | int clear_bits, int set_bits); |
@@ -48,10 +49,10 @@ struct fw_card_driver { | |||
48 | /* | 49 | /* |
49 | * Update the config rom for an enabled card. This function | 50 | * Update the config rom for an enabled card. This function |
50 | * should change the config rom that is presented on the bus | 51 | * should change the config rom that is presented on the bus |
51 | * an initiate a bus reset. | 52 | * and initiate a bus reset. |
52 | */ | 53 | */ |
53 | int (*set_config_rom)(struct fw_card *card, | 54 | int (*set_config_rom)(struct fw_card *card, |
54 | u32 *config_rom, size_t length); | 55 | const __be32 *config_rom, size_t length); |
55 | 56 | ||
56 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); | 57 | void (*send_request)(struct fw_card *card, struct fw_packet *packet); |
57 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); | 58 | void (*send_response)(struct fw_card *card, struct fw_packet *packet); |
@@ -69,7 +70,7 @@ struct fw_card_driver { | |||
69 | int (*enable_phys_dma)(struct fw_card *card, | 70 | int (*enable_phys_dma)(struct fw_card *card, |
70 | int node_id, int generation); | 71 | int node_id, int generation); |
71 | 72 | ||
72 | u64 (*get_bus_time)(struct fw_card *card); | 73 | u32 (*get_cycle_time)(struct fw_card *card); |
73 | 74 | ||
74 | struct fw_iso_context * | 75 | struct fw_iso_context * |
75 | (*allocate_iso_context)(struct fw_card *card, | 76 | (*allocate_iso_context)(struct fw_card *card, |
@@ -93,7 +94,7 @@ int fw_card_add(struct fw_card *card, | |||
93 | u32 max_receive, u32 link_speed, u64 guid); | 94 | u32 max_receive, u32 link_speed, u64 guid); |
94 | void fw_core_remove_card(struct fw_card *card); | 95 | void fw_core_remove_card(struct fw_card *card); |
95 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); | 96 | int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset); |
96 | int fw_compute_block_crc(u32 *block); | 97 | int fw_compute_block_crc(__be32 *block); |
97 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | 98 | void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); |
98 | 99 | ||
99 | static inline struct fw_card *fw_card_get(struct fw_card *card) | 100 | static inline struct fw_card *fw_card_get(struct fw_card *card) |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index cbaf420c36c5..7142eeec8074 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
25 | 26 | ||
26 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
@@ -893,20 +894,31 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, | |||
893 | 894 | ||
894 | static struct kmem_cache *fwnet_packet_task_cache; | 895 | static struct kmem_cache *fwnet_packet_task_cache; |
895 | 896 | ||
897 | static void fwnet_free_ptask(struct fwnet_packet_task *ptask) | ||
898 | { | ||
899 | dev_kfree_skb_any(ptask->skb); | ||
900 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
901 | } | ||
902 | |||
896 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); | 903 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); |
897 | 904 | ||
898 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | 905 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) |
899 | { | 906 | { |
900 | struct fwnet_device *dev; | 907 | struct fwnet_device *dev = ptask->dev; |
901 | unsigned long flags; | 908 | unsigned long flags; |
902 | 909 | bool free; | |
903 | dev = ptask->dev; | ||
904 | 910 | ||
905 | spin_lock_irqsave(&dev->lock, flags); | 911 | spin_lock_irqsave(&dev->lock, flags); |
906 | list_del(&ptask->pt_link); | ||
907 | spin_unlock_irqrestore(&dev->lock, flags); | ||
908 | 912 | ||
909 | ptask->outstanding_pkts--; /* FIXME access inside lock */ | 913 | ptask->outstanding_pkts--; |
914 | |||
915 | /* Check whether we or the networking TX soft-IRQ is last user. */ | ||
916 | free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); | ||
917 | |||
918 | if (ptask->outstanding_pkts == 0) | ||
919 | list_del(&ptask->pt_link); | ||
920 | |||
921 | spin_unlock_irqrestore(&dev->lock, flags); | ||
910 | 922 | ||
911 | if (ptask->outstanding_pkts > 0) { | 923 | if (ptask->outstanding_pkts > 0) { |
912 | u16 dg_size; | 924 | u16 dg_size; |
@@ -951,10 +963,10 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
951 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; | 963 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; |
952 | } | 964 | } |
953 | fwnet_send_packet(ptask); | 965 | fwnet_send_packet(ptask); |
954 | } else { | ||
955 | dev_kfree_skb_any(ptask->skb); | ||
956 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
957 | } | 966 | } |
967 | |||
968 | if (free) | ||
969 | fwnet_free_ptask(ptask); | ||
958 | } | 970 | } |
959 | 971 | ||
960 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 972 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
@@ -977,6 +989,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
977 | unsigned tx_len; | 989 | unsigned tx_len; |
978 | struct rfc2734_header *bufhdr; | 990 | struct rfc2734_header *bufhdr; |
979 | unsigned long flags; | 991 | unsigned long flags; |
992 | bool free; | ||
980 | 993 | ||
981 | dev = ptask->dev; | 994 | dev = ptask->dev; |
982 | tx_len = ptask->max_payload; | 995 | tx_len = ptask->max_payload; |
@@ -1022,12 +1035,16 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1022 | generation, SCODE_100, 0ULL, ptask->skb->data, | 1035 | generation, SCODE_100, 0ULL, ptask->skb->data, |
1023 | tx_len + 8, fwnet_write_complete, ptask); | 1036 | tx_len + 8, fwnet_write_complete, ptask); |
1024 | 1037 | ||
1025 | /* FIXME race? */ | ||
1026 | spin_lock_irqsave(&dev->lock, flags); | 1038 | spin_lock_irqsave(&dev->lock, flags); |
1027 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | 1039 | |
1040 | /* If the AT tasklet already ran, we may be last user. */ | ||
1041 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
1042 | if (!free) | ||
1043 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | ||
1044 | |||
1028 | spin_unlock_irqrestore(&dev->lock, flags); | 1045 | spin_unlock_irqrestore(&dev->lock, flags); |
1029 | 1046 | ||
1030 | return 0; | 1047 | goto out; |
1031 | } | 1048 | } |
1032 | 1049 | ||
1033 | fw_send_request(dev->card, &ptask->transaction, | 1050 | fw_send_request(dev->card, &ptask->transaction, |
@@ -1035,12 +1052,19 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1035 | ptask->generation, ptask->speed, ptask->fifo_addr, | 1052 | ptask->generation, ptask->speed, ptask->fifo_addr, |
1036 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); | 1053 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); |
1037 | 1054 | ||
1038 | /* FIXME race? */ | ||
1039 | spin_lock_irqsave(&dev->lock, flags); | 1055 | spin_lock_irqsave(&dev->lock, flags); |
1040 | list_add_tail(&ptask->pt_link, &dev->sent_list); | 1056 | |
1057 | /* If the AT tasklet already ran, we may be last user. */ | ||
1058 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
1059 | if (!free) | ||
1060 | list_add_tail(&ptask->pt_link, &dev->sent_list); | ||
1061 | |||
1041 | spin_unlock_irqrestore(&dev->lock, flags); | 1062 | spin_unlock_irqrestore(&dev->lock, flags); |
1042 | 1063 | ||
1043 | dev->netdev->trans_start = jiffies; | 1064 | dev->netdev->trans_start = jiffies; |
1065 | out: | ||
1066 | if (free) | ||
1067 | fwnet_free_ptask(ptask); | ||
1044 | 1068 | ||
1045 | return 0; | 1069 | return 0; |
1046 | } | 1070 | } |
@@ -1298,6 +1322,8 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1298 | spin_unlock_irqrestore(&dev->lock, flags); | 1322 | spin_unlock_irqrestore(&dev->lock, flags); |
1299 | 1323 | ||
1300 | ptask->max_payload = max_payload; | 1324 | ptask->max_payload = max_payload; |
1325 | INIT_LIST_HEAD(&ptask->pt_link); | ||
1326 | |||
1301 | fwnet_send_packet(ptask); | 1327 | fwnet_send_packet(ptask); |
1302 | 1328 | ||
1303 | return NETDEV_TX_OK; | 1329 | return NETDEV_TX_OK; |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 94260aa76aa3..94b16e0340ae 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
25 | #include <linux/firewire.h> | 25 | #include <linux/firewire.h> |
26 | #include <linux/firewire-constants.h> | 26 | #include <linux/firewire-constants.h> |
27 | #include <linux/gfp.h> | ||
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
30 | #include <linux/io.h> | 29 | #include <linux/io.h> |
@@ -35,10 +34,10 @@ | |||
35 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
36 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
37 | #include <linux/pci_ids.h> | 36 | #include <linux/pci_ids.h> |
37 | #include <linux/slab.h> | ||
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | 40 | ||
41 | #include <asm/atomic.h> | ||
42 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
43 | #include <asm/page.h> | 42 | #include <asm/page.h> |
44 | #include <asm/system.h> | 43 | #include <asm/system.h> |
@@ -73,20 +72,6 @@ struct descriptor { | |||
73 | __le16 transfer_status; | 72 | __le16 transfer_status; |
74 | } __attribute__((aligned(16))); | 73 | } __attribute__((aligned(16))); |
75 | 74 | ||
76 | struct db_descriptor { | ||
77 | __le16 first_size; | ||
78 | __le16 control; | ||
79 | __le16 second_req_count; | ||
80 | __le16 first_req_count; | ||
81 | __le32 branch_address; | ||
82 | __le16 second_res_count; | ||
83 | __le16 first_res_count; | ||
84 | __le32 reserved0; | ||
85 | __le32 first_buffer; | ||
86 | __le32 second_buffer; | ||
87 | __le32 reserved1; | ||
88 | } __attribute__((aligned(16))); | ||
89 | |||
90 | #define CONTROL_SET(regs) (regs) | 75 | #define CONTROL_SET(regs) (regs) |
91 | #define CONTROL_CLEAR(regs) ((regs) + 4) | 76 | #define CONTROL_CLEAR(regs) ((regs) + 4) |
92 | #define COMMAND_PTR(regs) ((regs) + 12) | 77 | #define COMMAND_PTR(regs) ((regs) + 12) |
@@ -181,31 +166,16 @@ struct fw_ohci { | |||
181 | struct fw_card card; | 166 | struct fw_card card; |
182 | 167 | ||
183 | __iomem char *registers; | 168 | __iomem char *registers; |
184 | dma_addr_t self_id_bus; | ||
185 | __le32 *self_id_cpu; | ||
186 | struct tasklet_struct bus_reset_tasklet; | ||
187 | int node_id; | 169 | int node_id; |
188 | int generation; | 170 | int generation; |
189 | int request_generation; /* for timestamping incoming requests */ | 171 | int request_generation; /* for timestamping incoming requests */ |
190 | atomic_t bus_seconds; | 172 | unsigned quirks; |
191 | |||
192 | bool use_dualbuffer; | ||
193 | bool old_uninorth; | ||
194 | bool bus_reset_packet_quirk; | ||
195 | 173 | ||
196 | /* | 174 | /* |
197 | * Spinlock for accessing fw_ohci data. Never call out of | 175 | * Spinlock for accessing fw_ohci data. Never call out of |
198 | * this driver with this lock held. | 176 | * this driver with this lock held. |
199 | */ | 177 | */ |
200 | spinlock_t lock; | 178 | spinlock_t lock; |
201 | u32 self_id_buffer[512]; | ||
202 | |||
203 | /* Config rom buffers */ | ||
204 | __be32 *config_rom; | ||
205 | dma_addr_t config_rom_bus; | ||
206 | __be32 *next_config_rom; | ||
207 | dma_addr_t next_config_rom_bus; | ||
208 | u32 next_header; | ||
209 | 179 | ||
210 | struct ar_context ar_request_ctx; | 180 | struct ar_context ar_request_ctx; |
211 | struct ar_context ar_response_ctx; | 181 | struct ar_context ar_response_ctx; |
@@ -217,6 +187,18 @@ struct fw_ohci { | |||
217 | u64 ir_context_channels; | 187 | u64 ir_context_channels; |
218 | u32 ir_context_mask; | 188 | u32 ir_context_mask; |
219 | struct iso_context *ir_context_list; | 189 | struct iso_context *ir_context_list; |
190 | |||
191 | __be32 *config_rom; | ||
192 | dma_addr_t config_rom_bus; | ||
193 | __be32 *next_config_rom; | ||
194 | dma_addr_t next_config_rom_bus; | ||
195 | __be32 next_header; | ||
196 | |||
197 | __le32 *self_id_cpu; | ||
198 | dma_addr_t self_id_bus; | ||
199 | struct tasklet_struct bus_reset_tasklet; | ||
200 | |||
201 | u32 self_id_buffer[512]; | ||
220 | }; | 202 | }; |
221 | 203 | ||
222 | static inline struct fw_ohci *fw_ohci(struct fw_card *card) | 204 | static inline struct fw_ohci *fw_ohci(struct fw_card *card) |
@@ -249,6 +231,34 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
249 | 231 | ||
250 | static char ohci_driver_name[] = KBUILD_MODNAME; | 232 | static char ohci_driver_name[] = KBUILD_MODNAME; |
251 | 233 | ||
234 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | ||
235 | |||
236 | #define QUIRK_CYCLE_TIMER 1 | ||
237 | #define QUIRK_RESET_PACKET 2 | ||
238 | #define QUIRK_BE_HEADERS 4 | ||
239 | |||
240 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | ||
241 | static const struct { | ||
242 | unsigned short vendor, device, flags; | ||
243 | } ohci_quirks[] = { | ||
244 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | ||
245 | QUIRK_RESET_PACKET}, | ||
246 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | ||
247 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
248 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
249 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
250 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | ||
251 | }; | ||
252 | |||
253 | /* This overrides anything that was found in ohci_quirks[]. */ | ||
254 | static int param_quirks; | ||
255 | module_param_named(quirks, param_quirks, int, 0644); | ||
256 | MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" | ||
257 | ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) | ||
258 | ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) | ||
259 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) | ||
260 | ")"); | ||
261 | |||
252 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG | 262 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG |
253 | 263 | ||
254 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 264 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
@@ -275,7 +285,7 @@ static void log_irqs(u32 evt) | |||
275 | !(evt & OHCI1394_busReset)) | 285 | !(evt & OHCI1394_busReset)) |
276 | return; | 286 | return; |
277 | 287 | ||
278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 288 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 289 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 290 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 291 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
@@ -285,7 +295,6 @@ static void log_irqs(u32 evt) | |||
285 | evt & OHCI1394_isochTx ? " IT" : "", | 295 | evt & OHCI1394_isochTx ? " IT" : "", |
286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 296 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 297 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | ||
289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | 298 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", |
290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 299 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
291 | evt & OHCI1394_busReset ? " busReset" : "", | 300 | evt & OHCI1394_busReset ? " busReset" : "", |
@@ -293,8 +302,7 @@ static void log_irqs(u32 evt) | |||
293 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | | 302 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | |
294 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 303 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 304 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 305 | OHCI1394_cycleTooLong | OHCI1394_cycleInconsistent | |
297 | OHCI1394_cycleInconsistent | | ||
298 | OHCI1394_regAccessFail | OHCI1394_busReset) | 306 | OHCI1394_regAccessFail | OHCI1394_busReset) |
299 | ? " ?" : ""); | 307 | ? " ?" : ""); |
300 | } | 308 | } |
@@ -524,7 +532,7 @@ static void ar_context_release(struct ar_context *ctx) | |||
524 | 532 | ||
525 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | 533 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) |
526 | #define cond_le32_to_cpu(v) \ | 534 | #define cond_le32_to_cpu(v) \ |
527 | (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) | 535 | (ohci->quirks & QUIRK_BE_HEADERS ? (__force __u32)(v) : le32_to_cpu(v)) |
528 | #else | 536 | #else |
529 | #define cond_le32_to_cpu(v) le32_to_cpu(v) | 537 | #define cond_le32_to_cpu(v) le32_to_cpu(v) |
530 | #endif | 538 | #endif |
@@ -605,7 +613,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
605 | * at a slightly incorrect time (in bus_reset_tasklet). | 613 | * at a slightly incorrect time (in bus_reset_tasklet). |
606 | */ | 614 | */ |
607 | if (evt == OHCI1394_evt_bus_reset) { | 615 | if (evt == OHCI1394_evt_bus_reset) { |
608 | if (!ohci->bus_reset_packet_quirk) | 616 | if (!(ohci->quirks & QUIRK_RESET_PACKET)) |
609 | ohci->request_generation = (p.header[2] >> 16) & 0xff; | 617 | ohci->request_generation = (p.header[2] >> 16) & 0xff; |
610 | } else if (ctx == &ohci->ar_request_ctx) { | 618 | } else if (ctx == &ohci->ar_request_ctx) { |
611 | fw_core_handle_request(&ohci->card, &p); | 619 | fw_core_handle_request(&ohci->card, &p); |
@@ -997,7 +1005,8 @@ static int at_context_queue_packet(struct context *ctx, | |||
997 | packet->ack = RCODE_SEND_ERROR; | 1005 | packet->ack = RCODE_SEND_ERROR; |
998 | return -1; | 1006 | return -1; |
999 | } | 1007 | } |
1000 | packet->payload_bus = payload_bus; | 1008 | packet->payload_bus = payload_bus; |
1009 | packet->payload_mapped = true; | ||
1001 | 1010 | ||
1002 | d[2].req_count = cpu_to_le16(packet->payload_length); | 1011 | d[2].req_count = cpu_to_le16(packet->payload_length); |
1003 | d[2].data_address = cpu_to_le32(payload_bus); | 1012 | d[2].data_address = cpu_to_le32(payload_bus); |
@@ -1025,7 +1034,7 @@ static int at_context_queue_packet(struct context *ctx, | |||
1025 | */ | 1034 | */ |
1026 | if (ohci->generation != packet->generation || | 1035 | if (ohci->generation != packet->generation || |
1027 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { | 1036 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { |
1028 | if (packet->payload_length > 0) | 1037 | if (packet->payload_mapped) |
1029 | dma_unmap_single(ohci->card.device, payload_bus, | 1038 | dma_unmap_single(ohci->card.device, payload_bus, |
1030 | packet->payload_length, DMA_TO_DEVICE); | 1039 | packet->payload_length, DMA_TO_DEVICE); |
1031 | packet->ack = RCODE_GENERATION; | 1040 | packet->ack = RCODE_GENERATION; |
@@ -1061,7 +1070,7 @@ static int handle_at_packet(struct context *context, | |||
1061 | /* This packet was cancelled, just continue. */ | 1070 | /* This packet was cancelled, just continue. */ |
1062 | return 1; | 1071 | return 1; |
1063 | 1072 | ||
1064 | if (packet->payload_bus) | 1073 | if (packet->payload_mapped) |
1065 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1074 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1066 | packet->payload_length, DMA_TO_DEVICE); | 1075 | packet->payload_length, DMA_TO_DEVICE); |
1067 | 1076 | ||
@@ -1149,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci, | |||
1149 | struct fw_packet *packet, u32 csr) | 1158 | struct fw_packet *packet, u32 csr) |
1150 | { | 1159 | { |
1151 | struct fw_packet response; | 1160 | struct fw_packet response; |
1152 | int tcode, length, ext_tcode, sel; | 1161 | int tcode, length, ext_tcode, sel, try; |
1153 | __be32 *payload, lock_old; | 1162 | __be32 *payload, lock_old; |
1154 | u32 lock_arg, lock_data; | 1163 | u32 lock_arg, lock_data; |
1155 | 1164 | ||
@@ -1176,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci, | |||
1176 | reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); | 1185 | reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); |
1177 | reg_write(ohci, OHCI1394_CSRControl, sel); | 1186 | reg_write(ohci, OHCI1394_CSRControl, sel); |
1178 | 1187 | ||
1179 | if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) | 1188 | for (try = 0; try < 20; try++) |
1180 | lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData)); | 1189 | if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) { |
1181 | else | 1190 | lock_old = cpu_to_be32(reg_read(ohci, |
1182 | fw_notify("swap not done yet\n"); | 1191 | OHCI1394_CSRData)); |
1192 | fw_fill_response(&response, packet->header, | ||
1193 | RCODE_COMPLETE, | ||
1194 | &lock_old, sizeof(lock_old)); | ||
1195 | goto out; | ||
1196 | } | ||
1197 | |||
1198 | fw_error("swap not done (CSR lock timeout)\n"); | ||
1199 | fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); | ||
1183 | 1200 | ||
1184 | fw_fill_response(&response, packet->header, | ||
1185 | RCODE_COMPLETE, &lock_old, sizeof(lock_old)); | ||
1186 | out: | 1201 | out: |
1187 | fw_core_handle_response(&ohci->card, &response); | 1202 | fw_core_handle_response(&ohci->card, &response); |
1188 | } | 1203 | } |
1189 | 1204 | ||
1190 | static void handle_local_request(struct context *ctx, struct fw_packet *packet) | 1205 | static void handle_local_request(struct context *ctx, struct fw_packet *packet) |
1191 | { | 1206 | { |
1192 | u64 offset; | 1207 | u64 offset, csr; |
1193 | u32 csr; | ||
1194 | 1208 | ||
1195 | if (ctx == &ctx->ohci->at_request_ctx) { | 1209 | if (ctx == &ctx->ohci->at_request_ctx) { |
1196 | packet->ack = ACK_PENDING; | 1210 | packet->ack = ACK_PENDING; |
@@ -1328,7 +1342,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
1328 | context_stop(&ohci->at_response_ctx); | 1342 | context_stop(&ohci->at_response_ctx); |
1329 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); | 1343 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
1330 | 1344 | ||
1331 | if (ohci->bus_reset_packet_quirk) | 1345 | if (ohci->quirks & QUIRK_RESET_PACKET) |
1332 | ohci->request_generation = generation; | 1346 | ohci->request_generation = generation; |
1333 | 1347 | ||
1334 | /* | 1348 | /* |
@@ -1357,8 +1371,9 @@ static void bus_reset_tasklet(unsigned long data) | |||
1357 | */ | 1371 | */ |
1358 | reg_write(ohci, OHCI1394_BusOptions, | 1372 | reg_write(ohci, OHCI1394_BusOptions, |
1359 | be32_to_cpu(ohci->config_rom[2])); | 1373 | be32_to_cpu(ohci->config_rom[2])); |
1360 | ohci->config_rom[0] = cpu_to_be32(ohci->next_header); | 1374 | ohci->config_rom[0] = ohci->next_header; |
1361 | reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header); | 1375 | reg_write(ohci, OHCI1394_ConfigROMhdr, |
1376 | be32_to_cpu(ohci->next_header)); | ||
1362 | } | 1377 | } |
1363 | 1378 | ||
1364 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA | 1379 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA |
@@ -1382,7 +1397,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
1382 | static irqreturn_t irq_handler(int irq, void *data) | 1397 | static irqreturn_t irq_handler(int irq, void *data) |
1383 | { | 1398 | { |
1384 | struct fw_ohci *ohci = data; | 1399 | struct fw_ohci *ohci = data; |
1385 | u32 event, iso_event, cycle_time; | 1400 | u32 event, iso_event; |
1386 | int i; | 1401 | int i; |
1387 | 1402 | ||
1388 | event = reg_read(ohci, OHCI1394_IntEventClear); | 1403 | event = reg_read(ohci, OHCI1394_IntEventClear); |
@@ -1452,12 +1467,6 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1452 | fw_notify("isochronous cycle inconsistent\n"); | 1467 | fw_notify("isochronous cycle inconsistent\n"); |
1453 | } | 1468 | } |
1454 | 1469 | ||
1455 | if (event & OHCI1394_cycle64Seconds) { | ||
1456 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1457 | if ((cycle_time & 0x80000000) == 0) | ||
1458 | atomic_inc(&ohci->bus_seconds); | ||
1459 | } | ||
1460 | |||
1461 | return IRQ_HANDLED; | 1470 | return IRQ_HANDLED; |
1462 | } | 1471 | } |
1463 | 1472 | ||
@@ -1477,7 +1486,17 @@ static int software_reset(struct fw_ohci *ohci) | |||
1477 | return -EBUSY; | 1486 | return -EBUSY; |
1478 | } | 1487 | } |
1479 | 1488 | ||
1480 | static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | 1489 | static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) |
1490 | { | ||
1491 | size_t size = length * 4; | ||
1492 | |||
1493 | memcpy(dest, src, size); | ||
1494 | if (size < CONFIG_ROM_SIZE) | ||
1495 | memset(&dest[length], 0, CONFIG_ROM_SIZE - size); | ||
1496 | } | ||
1497 | |||
1498 | static int ohci_enable(struct fw_card *card, | ||
1499 | const __be32 *config_rom, size_t length) | ||
1481 | { | 1500 | { |
1482 | struct fw_ohci *ohci = fw_ohci(card); | 1501 | struct fw_ohci *ohci = fw_ohci(card); |
1483 | struct pci_dev *dev = to_pci_dev(card->device); | 1502 | struct pci_dev *dev = to_pci_dev(card->device); |
@@ -1541,8 +1560,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1541 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1560 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
1542 | OHCI1394_isochRx | OHCI1394_isochTx | | 1561 | OHCI1394_isochRx | OHCI1394_isochTx | |
1543 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1562 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
1544 | OHCI1394_cycleInconsistent | | 1563 | OHCI1394_cycleInconsistent | OHCI1394_regAccessFail | |
1545 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | ||
1546 | OHCI1394_masterIntEnable); | 1564 | OHCI1394_masterIntEnable); |
1547 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1565 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
1548 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); | 1566 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); |
@@ -1579,8 +1597,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1579 | if (ohci->next_config_rom == NULL) | 1597 | if (ohci->next_config_rom == NULL) |
1580 | return -ENOMEM; | 1598 | return -ENOMEM; |
1581 | 1599 | ||
1582 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1600 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1583 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4); | ||
1584 | } else { | 1601 | } else { |
1585 | /* | 1602 | /* |
1586 | * In the suspend case, config_rom is NULL, which | 1603 | * In the suspend case, config_rom is NULL, which |
@@ -1590,7 +1607,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1590 | ohci->next_config_rom_bus = ohci->config_rom_bus; | 1607 | ohci->next_config_rom_bus = ohci->config_rom_bus; |
1591 | } | 1608 | } |
1592 | 1609 | ||
1593 | ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]); | 1610 | ohci->next_header = ohci->next_config_rom[0]; |
1594 | ohci->next_config_rom[0] = 0; | 1611 | ohci->next_config_rom[0] = 0; |
1595 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); | 1612 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); |
1596 | reg_write(ohci, OHCI1394_BusOptions, | 1613 | reg_write(ohci, OHCI1394_BusOptions, |
@@ -1624,7 +1641,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1624 | } | 1641 | } |
1625 | 1642 | ||
1626 | static int ohci_set_config_rom(struct fw_card *card, | 1643 | static int ohci_set_config_rom(struct fw_card *card, |
1627 | u32 *config_rom, size_t length) | 1644 | const __be32 *config_rom, size_t length) |
1628 | { | 1645 | { |
1629 | struct fw_ohci *ohci; | 1646 | struct fw_ohci *ohci; |
1630 | unsigned long flags; | 1647 | unsigned long flags; |
@@ -1673,9 +1690,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
1673 | ohci->next_config_rom = next_config_rom; | 1690 | ohci->next_config_rom = next_config_rom; |
1674 | ohci->next_config_rom_bus = next_config_rom_bus; | 1691 | ohci->next_config_rom_bus = next_config_rom_bus; |
1675 | 1692 | ||
1676 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1693 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1677 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, | ||
1678 | length * 4); | ||
1679 | 1694 | ||
1680 | ohci->next_header = config_rom[0]; | 1695 | ohci->next_header = config_rom[0]; |
1681 | ohci->next_config_rom[0] = 0; | 1696 | ohci->next_config_rom[0] = 0; |
@@ -1729,7 +1744,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) | |||
1729 | if (packet->ack != 0) | 1744 | if (packet->ack != 0) |
1730 | goto out; | 1745 | goto out; |
1731 | 1746 | ||
1732 | if (packet->payload_bus) | 1747 | if (packet->payload_mapped) |
1733 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1748 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1734 | packet->payload_length, DMA_TO_DEVICE); | 1749 | packet->payload_length, DMA_TO_DEVICE); |
1735 | 1750 | ||
@@ -1785,16 +1800,61 @@ static int ohci_enable_phys_dma(struct fw_card *card, | |||
1785 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ | 1800 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ |
1786 | } | 1801 | } |
1787 | 1802 | ||
1788 | static u64 ohci_get_bus_time(struct fw_card *card) | 1803 | static u32 cycle_timer_ticks(u32 cycle_timer) |
1789 | { | 1804 | { |
1790 | struct fw_ohci *ohci = fw_ohci(card); | 1805 | u32 ticks; |
1791 | u32 cycle_time; | ||
1792 | u64 bus_time; | ||
1793 | 1806 | ||
1794 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1807 | ticks = cycle_timer & 0xfff; |
1795 | bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time; | 1808 | ticks += 3072 * ((cycle_timer >> 12) & 0x1fff); |
1809 | ticks += (3072 * 8000) * (cycle_timer >> 25); | ||
1796 | 1810 | ||
1797 | return bus_time; | 1811 | return ticks; |
1812 | } | ||
1813 | |||
1814 | /* | ||
1815 | * Some controllers exhibit one or more of the following bugs when updating the | ||
1816 | * iso cycle timer register: | ||
1817 | * - When the lowest six bits are wrapping around to zero, a read that happens | ||
1818 | * at the same time will return garbage in the lowest ten bits. | ||
1819 | * - When the cycleOffset field wraps around to zero, the cycleCount field is | ||
1820 | * not incremented for about 60 ns. | ||
1821 | * - Occasionally, the entire register reads zero. | ||
1822 | * | ||
1823 | * To catch these, we read the register three times and ensure that the | ||
1824 | * difference between each two consecutive reads is approximately the same, i.e. | ||
1825 | * less than twice the other. Furthermore, any negative difference indicates an | ||
1826 | * error. (A PCI read should take at least 20 ticks of the 24.576 MHz timer to | ||
1827 | * execute, so we have enough precision to compute the ratio of the differences.) | ||
1828 | */ | ||
1829 | static u32 ohci_get_cycle_time(struct fw_card *card) | ||
1830 | { | ||
1831 | struct fw_ohci *ohci = fw_ohci(card); | ||
1832 | u32 c0, c1, c2; | ||
1833 | u32 t0, t1, t2; | ||
1834 | s32 diff01, diff12; | ||
1835 | int i; | ||
1836 | |||
1837 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1838 | |||
1839 | if (ohci->quirks & QUIRK_CYCLE_TIMER) { | ||
1840 | i = 0; | ||
1841 | c1 = c2; | ||
1842 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1843 | do { | ||
1844 | c0 = c1; | ||
1845 | c1 = c2; | ||
1846 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1847 | t0 = cycle_timer_ticks(c0); | ||
1848 | t1 = cycle_timer_ticks(c1); | ||
1849 | t2 = cycle_timer_ticks(c2); | ||
1850 | diff01 = t1 - t0; | ||
1851 | diff12 = t2 - t1; | ||
1852 | } while ((diff01 <= 0 || diff12 <= 0 || | ||
1853 | diff01 / diff12 >= 2 || diff12 / diff01 >= 2) | ||
1854 | && i++ < 20); | ||
1855 | } | ||
1856 | |||
1857 | return c2; | ||
1798 | } | 1858 | } |
1799 | 1859 | ||
1800 | static void copy_iso_headers(struct iso_context *ctx, void *p) | 1860 | static void copy_iso_headers(struct iso_context *ctx, void *p) |
@@ -1819,52 +1879,6 @@ static void copy_iso_headers(struct iso_context *ctx, void *p) | |||
1819 | ctx->header_length += ctx->base.header_size; | 1879 | ctx->header_length += ctx->base.header_size; |
1820 | } | 1880 | } |
1821 | 1881 | ||
1822 | static int handle_ir_dualbuffer_packet(struct context *context, | ||
1823 | struct descriptor *d, | ||
1824 | struct descriptor *last) | ||
1825 | { | ||
1826 | struct iso_context *ctx = | ||
1827 | container_of(context, struct iso_context, context); | ||
1828 | struct db_descriptor *db = (struct db_descriptor *) d; | ||
1829 | __le32 *ir_header; | ||
1830 | size_t header_length; | ||
1831 | void *p, *end; | ||
1832 | |||
1833 | if (db->first_res_count != 0 && db->second_res_count != 0) { | ||
1834 | if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) { | ||
1835 | /* This descriptor isn't done yet, stop iteration. */ | ||
1836 | return 0; | ||
1837 | } | ||
1838 | ctx->excess_bytes -= le16_to_cpu(db->second_req_count); | ||
1839 | } | ||
1840 | |||
1841 | header_length = le16_to_cpu(db->first_req_count) - | ||
1842 | le16_to_cpu(db->first_res_count); | ||
1843 | |||
1844 | p = db + 1; | ||
1845 | end = p + header_length; | ||
1846 | while (p < end) { | ||
1847 | copy_iso_headers(ctx, p); | ||
1848 | ctx->excess_bytes += | ||
1849 | (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff; | ||
1850 | p += max(ctx->base.header_size, (size_t)8); | ||
1851 | } | ||
1852 | |||
1853 | ctx->excess_bytes -= le16_to_cpu(db->second_req_count) - | ||
1854 | le16_to_cpu(db->second_res_count); | ||
1855 | |||
1856 | if (le16_to_cpu(db->control) & DESCRIPTOR_IRQ_ALWAYS) { | ||
1857 | ir_header = (__le32 *) (db + 1); | ||
1858 | ctx->base.callback(&ctx->base, | ||
1859 | le32_to_cpu(ir_header[0]) & 0xffff, | ||
1860 | ctx->header_length, ctx->header, | ||
1861 | ctx->base.callback_data); | ||
1862 | ctx->header_length = 0; | ||
1863 | } | ||
1864 | |||
1865 | return 1; | ||
1866 | } | ||
1867 | |||
1868 | static int handle_ir_packet_per_buffer(struct context *context, | 1882 | static int handle_ir_packet_per_buffer(struct context *context, |
1869 | struct descriptor *d, | 1883 | struct descriptor *d, |
1870 | struct descriptor *last) | 1884 | struct descriptor *last) |
@@ -1951,10 +1965,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
1951 | channels = &ohci->ir_context_channels; | 1965 | channels = &ohci->ir_context_channels; |
1952 | mask = &ohci->ir_context_mask; | 1966 | mask = &ohci->ir_context_mask; |
1953 | list = ohci->ir_context_list; | 1967 | list = ohci->ir_context_list; |
1954 | if (ohci->use_dualbuffer) | 1968 | callback = handle_ir_packet_per_buffer; |
1955 | callback = handle_ir_dualbuffer_packet; | ||
1956 | else | ||
1957 | callback = handle_ir_packet_per_buffer; | ||
1958 | } | 1969 | } |
1959 | 1970 | ||
1960 | spin_lock_irqsave(&ohci->lock, flags); | 1971 | spin_lock_irqsave(&ohci->lock, flags); |
@@ -2017,8 +2028,6 @@ static int ohci_start_iso(struct fw_iso_context *base, | |||
2017 | } else { | 2028 | } else { |
2018 | index = ctx - ohci->ir_context_list; | 2029 | index = ctx - ohci->ir_context_list; |
2019 | control = IR_CONTEXT_ISOCH_HEADER; | 2030 | control = IR_CONTEXT_ISOCH_HEADER; |
2020 | if (ohci->use_dualbuffer) | ||
2021 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; | ||
2022 | match = (tags << 28) | (sync << 8) | ctx->base.channel; | 2031 | match = (tags << 28) | (sync << 8) | ctx->base.channel; |
2023 | if (cycle >= 0) { | 2032 | if (cycle >= 0) { |
2024 | match |= (cycle & 0x07fff) << 12; | 2033 | match |= (cycle & 0x07fff) << 12; |
@@ -2092,11 +2101,6 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2092 | u32 payload_index, payload_end_index, next_page_index; | 2101 | u32 payload_index, payload_end_index, next_page_index; |
2093 | int page, end_page, i, length, offset; | 2102 | int page, end_page, i, length, offset; |
2094 | 2103 | ||
2095 | /* | ||
2096 | * FIXME: Cycle lost behavior should be configurable: lose | ||
2097 | * packet, retransmit or terminate.. | ||
2098 | */ | ||
2099 | |||
2100 | p = packet; | 2104 | p = packet; |
2101 | payload_index = payload; | 2105 | payload_index = payload; |
2102 | 2106 | ||
@@ -2126,6 +2130,14 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2126 | if (!p->skip) { | 2130 | if (!p->skip) { |
2127 | d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE); | 2131 | d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE); |
2128 | d[0].req_count = cpu_to_le16(8); | 2132 | d[0].req_count = cpu_to_le16(8); |
2133 | /* | ||
2134 | * Link the skip address to this descriptor itself. This causes | ||
2135 | * a context to skip a cycle whenever lost cycles or FIFO | ||
2136 | * overruns occur, without dropping the data. The application | ||
2137 | * should then decide whether this is an error condition or not. | ||
2138 | * FIXME: Make the context's cycle-lost behaviour configurable? | ||
2139 | */ | ||
2140 | d[0].branch_address = cpu_to_le32(d_bus | z); | ||
2129 | 2141 | ||
2130 | header = (__le32 *) &d[1]; | 2142 | header = (__le32 *) &d[1]; |
2131 | header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) | | 2143 | header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) | |
@@ -2176,93 +2188,13 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2176 | return 0; | 2188 | return 0; |
2177 | } | 2189 | } |
2178 | 2190 | ||
2179 | static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, | ||
2180 | struct fw_iso_packet *packet, | ||
2181 | struct fw_iso_buffer *buffer, | ||
2182 | unsigned long payload) | ||
2183 | { | ||
2184 | struct iso_context *ctx = container_of(base, struct iso_context, base); | ||
2185 | struct db_descriptor *db = NULL; | ||
2186 | struct descriptor *d; | ||
2187 | struct fw_iso_packet *p; | ||
2188 | dma_addr_t d_bus, page_bus; | ||
2189 | u32 z, header_z, length, rest; | ||
2190 | int page, offset, packet_count, header_size; | ||
2191 | |||
2192 | /* | ||
2193 | * FIXME: Cycle lost behavior should be configurable: lose | ||
2194 | * packet, retransmit or terminate.. | ||
2195 | */ | ||
2196 | |||
2197 | p = packet; | ||
2198 | z = 2; | ||
2199 | |||
2200 | /* | ||
2201 | * The OHCI controller puts the isochronous header and trailer in the | ||
2202 | * buffer, so we need at least 8 bytes. | ||
2203 | */ | ||
2204 | packet_count = p->header_length / ctx->base.header_size; | ||
2205 | header_size = packet_count * max(ctx->base.header_size, (size_t)8); | ||
2206 | |||
2207 | /* Get header size in number of descriptors. */ | ||
2208 | header_z = DIV_ROUND_UP(header_size, sizeof(*d)); | ||
2209 | page = payload >> PAGE_SHIFT; | ||
2210 | offset = payload & ~PAGE_MASK; | ||
2211 | rest = p->payload_length; | ||
2212 | |||
2213 | /* FIXME: make packet-per-buffer/dual-buffer a context option */ | ||
2214 | while (rest > 0) { | ||
2215 | d = context_get_descriptors(&ctx->context, | ||
2216 | z + header_z, &d_bus); | ||
2217 | if (d == NULL) | ||
2218 | return -ENOMEM; | ||
2219 | |||
2220 | db = (struct db_descriptor *) d; | ||
2221 | db->control = cpu_to_le16(DESCRIPTOR_STATUS | | ||
2222 | DESCRIPTOR_BRANCH_ALWAYS); | ||
2223 | db->first_size = | ||
2224 | cpu_to_le16(max(ctx->base.header_size, (size_t)8)); | ||
2225 | if (p->skip && rest == p->payload_length) { | ||
2226 | db->control |= cpu_to_le16(DESCRIPTOR_WAIT); | ||
2227 | db->first_req_count = db->first_size; | ||
2228 | } else { | ||
2229 | db->first_req_count = cpu_to_le16(header_size); | ||
2230 | } | ||
2231 | db->first_res_count = db->first_req_count; | ||
2232 | db->first_buffer = cpu_to_le32(d_bus + sizeof(*db)); | ||
2233 | |||
2234 | if (p->skip && rest == p->payload_length) | ||
2235 | length = 4; | ||
2236 | else if (offset + rest < PAGE_SIZE) | ||
2237 | length = rest; | ||
2238 | else | ||
2239 | length = PAGE_SIZE - offset; | ||
2240 | |||
2241 | db->second_req_count = cpu_to_le16(length); | ||
2242 | db->second_res_count = db->second_req_count; | ||
2243 | page_bus = page_private(buffer->pages[page]); | ||
2244 | db->second_buffer = cpu_to_le32(page_bus + offset); | ||
2245 | |||
2246 | if (p->interrupt && length == rest) | ||
2247 | db->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS); | ||
2248 | |||
2249 | context_append(&ctx->context, d, z, header_z); | ||
2250 | offset = (offset + length) & ~PAGE_MASK; | ||
2251 | rest -= length; | ||
2252 | if (offset == 0) | ||
2253 | page++; | ||
2254 | } | ||
2255 | |||
2256 | return 0; | ||
2257 | } | ||
2258 | |||
2259 | static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, | 2191 | static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, |
2260 | struct fw_iso_packet *packet, | 2192 | struct fw_iso_packet *packet, |
2261 | struct fw_iso_buffer *buffer, | 2193 | struct fw_iso_buffer *buffer, |
2262 | unsigned long payload) | 2194 | unsigned long payload) |
2263 | { | 2195 | { |
2264 | struct iso_context *ctx = container_of(base, struct iso_context, base); | 2196 | struct iso_context *ctx = container_of(base, struct iso_context, base); |
2265 | struct descriptor *d = NULL, *pd = NULL; | 2197 | struct descriptor *d, *pd; |
2266 | struct fw_iso_packet *p = packet; | 2198 | struct fw_iso_packet *p = packet; |
2267 | dma_addr_t d_bus, page_bus; | 2199 | dma_addr_t d_bus, page_bus; |
2268 | u32 z, header_z, rest; | 2200 | u32 z, header_z, rest; |
@@ -2300,8 +2232,9 @@ static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, | |||
2300 | d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); | 2232 | d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); |
2301 | 2233 | ||
2302 | rest = payload_per_buffer; | 2234 | rest = payload_per_buffer; |
2235 | pd = d; | ||
2303 | for (j = 1; j < z; j++) { | 2236 | for (j = 1; j < z; j++) { |
2304 | pd = d + j; | 2237 | pd++; |
2305 | pd->control = cpu_to_le16(DESCRIPTOR_STATUS | | 2238 | pd->control = cpu_to_le16(DESCRIPTOR_STATUS | |
2306 | DESCRIPTOR_INPUT_MORE); | 2239 | DESCRIPTOR_INPUT_MORE); |
2307 | 2240 | ||
@@ -2345,9 +2278,6 @@ static int ohci_queue_iso(struct fw_iso_context *base, | |||
2345 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); | 2278 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); |
2346 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) | 2279 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
2347 | ret = ohci_queue_iso_transmit(base, packet, buffer, payload); | 2280 | ret = ohci_queue_iso_transmit(base, packet, buffer, payload); |
2348 | else if (ctx->context.ohci->use_dualbuffer) | ||
2349 | ret = ohci_queue_iso_receive_dualbuffer(base, packet, | ||
2350 | buffer, payload); | ||
2351 | else | 2281 | else |
2352 | ret = ohci_queue_iso_receive_packet_per_buffer(base, packet, | 2282 | ret = ohci_queue_iso_receive_packet_per_buffer(base, packet, |
2353 | buffer, payload); | 2283 | buffer, payload); |
@@ -2364,7 +2294,7 @@ static const struct fw_card_driver ohci_driver = { | |||
2364 | .send_response = ohci_send_response, | 2294 | .send_response = ohci_send_response, |
2365 | .cancel_packet = ohci_cancel_packet, | 2295 | .cancel_packet = ohci_cancel_packet, |
2366 | .enable_phys_dma = ohci_enable_phys_dma, | 2296 | .enable_phys_dma = ohci_enable_phys_dma, |
2367 | .get_bus_time = ohci_get_bus_time, | 2297 | .get_cycle_time = ohci_get_cycle_time, |
2368 | 2298 | ||
2369 | .allocate_iso_context = ohci_allocate_iso_context, | 2299 | .allocate_iso_context = ohci_allocate_iso_context, |
2370 | .free_iso_context = ohci_free_iso_context, | 2300 | .free_iso_context = ohci_free_iso_context, |
@@ -2402,16 +2332,13 @@ static void ohci_pmac_off(struct pci_dev *dev) | |||
2402 | #define ohci_pmac_off(dev) | 2332 | #define ohci_pmac_off(dev) |
2403 | #endif /* CONFIG_PPC_PMAC */ | 2333 | #endif /* CONFIG_PPC_PMAC */ |
2404 | 2334 | ||
2405 | #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT | ||
2406 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
2407 | |||
2408 | static int __devinit pci_probe(struct pci_dev *dev, | 2335 | static int __devinit pci_probe(struct pci_dev *dev, |
2409 | const struct pci_device_id *ent) | 2336 | const struct pci_device_id *ent) |
2410 | { | 2337 | { |
2411 | struct fw_ohci *ohci; | 2338 | struct fw_ohci *ohci; |
2412 | u32 bus_options, max_receive, link_speed, version; | 2339 | u32 bus_options, max_receive, link_speed, version; |
2413 | u64 guid; | 2340 | u64 guid; |
2414 | int err; | 2341 | int i, err, n_ir, n_it; |
2415 | size_t size; | 2342 | size_t size; |
2416 | 2343 | ||
2417 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 2344 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
@@ -2452,32 +2379,15 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2452 | goto fail_iomem; | 2379 | goto fail_iomem; |
2453 | } | 2380 | } |
2454 | 2381 | ||
2455 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | 2382 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2456 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | 2383 | if (ohci_quirks[i].vendor == dev->vendor && |
2457 | 2384 | (ohci_quirks[i].device == dev->device || | |
2458 | /* dual-buffer mode is broken if more than one IR context is active */ | 2385 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { |
2459 | if (dev->vendor == PCI_VENDOR_ID_AGERE && | 2386 | ohci->quirks = ohci_quirks[i].flags; |
2460 | dev->device == PCI_DEVICE_ID_AGERE_FW643) | 2387 | break; |
2461 | ohci->use_dualbuffer = false; | 2388 | } |
2462 | 2389 | if (param_quirks) | |
2463 | /* dual-buffer mode is broken */ | 2390 | ohci->quirks = param_quirks; |
2464 | if (dev->vendor == PCI_VENDOR_ID_RICOH && | ||
2465 | dev->device == PCI_DEVICE_ID_RICOH_R5C832) | ||
2466 | ohci->use_dualbuffer = false; | ||
2467 | |||
2468 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | ||
2469 | #if !defined(CONFIG_X86_32) | ||
2470 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | ||
2471 | if (dev->vendor == PCI_VENDOR_ID_TI && | ||
2472 | dev->device == PCI_DEVICE_ID_TI_TSB43AB22) | ||
2473 | ohci->use_dualbuffer = false; | ||
2474 | #endif | ||
2475 | |||
2476 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2477 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2478 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2479 | #endif | ||
2480 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2481 | 2391 | ||
2482 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2392 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2483 | OHCI1394_AsReqRcvContextControlSet); | 2393 | OHCI1394_AsReqRcvContextControlSet); |
@@ -2492,17 +2402,19 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2492 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); | 2402 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); |
2493 | 2403 | ||
2494 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); | 2404 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); |
2495 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | 2405 | ohci->ir_context_channels = ~0ULL; |
2406 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | ||
2496 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); | 2407 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); |
2497 | size = sizeof(struct iso_context) * hweight32(ohci->it_context_mask); | 2408 | n_ir = hweight32(ohci->ir_context_mask); |
2498 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | 2409 | size = sizeof(struct iso_context) * n_ir; |
2410 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | ||
2499 | 2411 | ||
2500 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); | 2412 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); |
2501 | ohci->ir_context_channels = ~0ULL; | 2413 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); |
2502 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); | ||
2503 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); | 2414 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); |
2504 | size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask); | 2415 | n_it = hweight32(ohci->it_context_mask); |
2505 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | 2416 | size = sizeof(struct iso_context) * n_it; |
2417 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | ||
2506 | 2418 | ||
2507 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { | 2419 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { |
2508 | err = -ENOMEM; | 2420 | err = -ENOMEM; |
@@ -2529,8 +2441,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2529 | if (err) | 2441 | if (err) |
2530 | goto fail_self_id; | 2442 | goto fail_self_id; |
2531 | 2443 | ||
2532 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2444 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
2533 | dev_name(&dev->dev), version >> 16, version & 0xff); | 2445 | fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " |
2446 | "%d IR + %d IT contexts, quirks 0x%x\n", | ||
2447 | dev_name(&dev->dev), version >> 16, version & 0xff, | ||
2448 | n_ir, n_it, ohci->quirks); | ||
2534 | 2449 | ||
2535 | return 0; | 2450 | return 0; |
2536 | 2451 | ||
@@ -2638,7 +2553,7 @@ static int pci_resume(struct pci_dev *dev) | |||
2638 | } | 2553 | } |
2639 | #endif | 2554 | #endif |
2640 | 2555 | ||
2641 | static struct pci_device_id pci_table[] = { | 2556 | static const struct pci_device_id pci_table[] = { |
2642 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, | 2557 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, |
2643 | { } | 2558 | { } |
2644 | }; | 2559 | }; |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 98dbbda3ad41..ca264f2fdf0c 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -820,20 +820,25 @@ static void sbp2_release_target(struct kref *kref) | |||
820 | fw_device_put(device); | 820 | fw_device_put(device); |
821 | } | 821 | } |
822 | 822 | ||
823 | static struct workqueue_struct *sbp2_wq; | 823 | static void sbp2_target_get(struct sbp2_target *tgt) |
824 | { | ||
825 | kref_get(&tgt->kref); | ||
826 | } | ||
824 | 827 | ||
825 | static void sbp2_target_put(struct sbp2_target *tgt) | 828 | static void sbp2_target_put(struct sbp2_target *tgt) |
826 | { | 829 | { |
827 | kref_put(&tgt->kref, sbp2_release_target); | 830 | kref_put(&tgt->kref, sbp2_release_target); |
828 | } | 831 | } |
829 | 832 | ||
833 | static struct workqueue_struct *sbp2_wq; | ||
834 | |||
830 | /* | 835 | /* |
831 | * Always get the target's kref when scheduling work on one its units. | 836 | * Always get the target's kref when scheduling work on one its units. |
832 | * Each workqueue job is responsible to call sbp2_target_put() upon return. | 837 | * Each workqueue job is responsible to call sbp2_target_put() upon return. |
833 | */ | 838 | */ |
834 | static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) | 839 | static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) |
835 | { | 840 | { |
836 | kref_get(&lu->tgt->kref); | 841 | sbp2_target_get(lu->tgt); |
837 | if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) | 842 | if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) |
838 | sbp2_target_put(lu->tgt); | 843 | sbp2_target_put(lu->tgt); |
839 | } | 844 | } |
@@ -1009,7 +1014,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | |||
1009 | return 0; | 1014 | return 0; |
1010 | } | 1015 | } |
1011 | 1016 | ||
1012 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | 1017 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, |
1018 | const u32 *directory) | ||
1013 | { | 1019 | { |
1014 | struct fw_csr_iterator ci; | 1020 | struct fw_csr_iterator ci; |
1015 | int key, value; | 1021 | int key, value; |
@@ -1022,7 +1028,7 @@ static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | |||
1022 | return 0; | 1028 | return 0; |
1023 | } | 1029 | } |
1024 | 1030 | ||
1025 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, | 1031 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, const u32 *directory, |
1026 | u32 *model, u32 *firmware_revision) | 1032 | u32 *model, u32 *firmware_revision) |
1027 | { | 1033 | { |
1028 | struct fw_csr_iterator ci; | 1034 | struct fw_csr_iterator ci; |
@@ -1566,7 +1572,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
1566 | sdev->start_stop_pwr_cond = 1; | 1572 | sdev->start_stop_pwr_cond = 1; |
1567 | 1573 | ||
1568 | if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) | 1574 | if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) |
1569 | blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); | 1575 | blk_queue_max_hw_sectors(sdev->request_queue, 128 * 1024 / 512); |
1570 | 1576 | ||
1571 | blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); | 1577 | blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE); |
1572 | 1578 | ||