diff options
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 14 | ||||
-rw-r--r-- | drivers/firewire/core-cdev.c | 4 | ||||
-rw-r--r-- | drivers/firewire/core-iso.c | 28 | ||||
-rw-r--r-- | drivers/firewire/core.h | 3 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 14 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 18 |
6 files changed, 54 insertions, 27 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 543fccac81bb..f74edae5cb4c 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -196,8 +196,8 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) | |||
196 | { | 196 | { |
197 | int channel, bandwidth = 0; | 197 | int channel, bandwidth = 0; |
198 | 198 | ||
199 | fw_iso_resource_manage(card, generation, 1ULL << 31, | 199 | fw_iso_resource_manage(card, generation, 1ULL << 31, &channel, |
200 | &channel, &bandwidth, true); | 200 | &bandwidth, true, card->bm_transaction_data); |
201 | if (channel == 31) { | 201 | if (channel == 31) { |
202 | card->broadcast_channel_allocated = true; | 202 | card->broadcast_channel_allocated = true; |
203 | device_for_each_child(card->device, (void *)(long)generation, | 203 | device_for_each_child(card->device, (void *)(long)generation, |
@@ -230,7 +230,6 @@ static void fw_card_bm_work(struct work_struct *work) | |||
230 | bool do_reset = false; | 230 | bool do_reset = false; |
231 | bool root_device_is_running; | 231 | bool root_device_is_running; |
232 | bool root_device_is_cmc; | 232 | bool root_device_is_cmc; |
233 | __be32 lock_data[2]; | ||
234 | 233 | ||
235 | spin_lock_irqsave(&card->lock, flags); | 234 | spin_lock_irqsave(&card->lock, flags); |
236 | 235 | ||
@@ -273,22 +272,23 @@ static void fw_card_bm_work(struct work_struct *work) | |||
273 | goto pick_me; | 272 | goto pick_me; |
274 | } | 273 | } |
275 | 274 | ||
276 | lock_data[0] = cpu_to_be32(0x3f); | 275 | card->bm_transaction_data[0] = cpu_to_be32(0x3f); |
277 | lock_data[1] = cpu_to_be32(local_id); | 276 | card->bm_transaction_data[1] = cpu_to_be32(local_id); |
278 | 277 | ||
279 | spin_unlock_irqrestore(&card->lock, flags); | 278 | spin_unlock_irqrestore(&card->lock, flags); |
280 | 279 | ||
281 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, | 280 | rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
282 | irm_id, generation, SCODE_100, | 281 | irm_id, generation, SCODE_100, |
283 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, | 282 | CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, |
284 | lock_data, sizeof(lock_data)); | 283 | card->bm_transaction_data, |
284 | sizeof(card->bm_transaction_data)); | ||
285 | 285 | ||
286 | if (rcode == RCODE_GENERATION) | 286 | if (rcode == RCODE_GENERATION) |
287 | /* Another bus reset, BM work has been rescheduled. */ | 287 | /* Another bus reset, BM work has been rescheduled. */ |
288 | goto out; | 288 | goto out; |
289 | 289 | ||
290 | if (rcode == RCODE_COMPLETE && | 290 | if (rcode == RCODE_COMPLETE && |
291 | lock_data[0] != cpu_to_be32(0x3f)) { | 291 | card->bm_transaction_data[0] != cpu_to_be32(0x3f)) { |
292 | 292 | ||
293 | /* Somebody else is BM. Only act as IRM. */ | 293 | /* Somebody else is BM. Only act as IRM. */ |
294 | if (local_id == irm_id) | 294 | if (local_id == irm_id) |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index d1d30c615b0f..ced186d7e9a9 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -125,6 +125,7 @@ struct iso_resource { | |||
125 | int generation; | 125 | int generation; |
126 | u64 channels; | 126 | u64 channels; |
127 | s32 bandwidth; | 127 | s32 bandwidth; |
128 | __be32 transaction_data[2]; | ||
128 | struct iso_resource_event *e_alloc, *e_dealloc; | 129 | struct iso_resource_event *e_alloc, *e_dealloc; |
129 | }; | 130 | }; |
130 | 131 | ||
@@ -1049,7 +1050,8 @@ static void iso_resource_work(struct work_struct *work) | |||
1049 | r->channels, &channel, &bandwidth, | 1050 | r->channels, &channel, &bandwidth, |
1050 | todo == ISO_RES_ALLOC || | 1051 | todo == ISO_RES_ALLOC || |
1051 | todo == ISO_RES_REALLOC || | 1052 | todo == ISO_RES_REALLOC || |
1052 | todo == ISO_RES_ALLOC_ONCE); | 1053 | todo == ISO_RES_ALLOC_ONCE, |
1054 | r->transaction_data); | ||
1053 | /* | 1055 | /* |
1054 | * Is this generation outdated already? As long as this resource sticks | 1056 | * Is this generation outdated already? As long as this resource sticks |
1055 | * in the idr, it will be scheduled again for a newer generation or at | 1057 | * in the idr, it will be scheduled again for a newer generation or at |
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 166f19c6d38d..1c0b504a42f3 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c | |||
@@ -177,9 +177,8 @@ EXPORT_SYMBOL(fw_iso_context_stop); | |||
177 | */ | 177 | */ |
178 | 178 | ||
179 | static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | 179 | static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, |
180 | int bandwidth, bool allocate) | 180 | int bandwidth, bool allocate, __be32 data[2]) |
181 | { | 181 | { |
182 | __be32 data[2]; | ||
183 | int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; | 182 | int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; |
184 | 183 | ||
185 | /* | 184 | /* |
@@ -197,7 +196,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | |||
197 | switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, | 196 | switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
198 | irm_id, generation, SCODE_100, | 197 | irm_id, generation, SCODE_100, |
199 | CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, | 198 | CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, |
200 | data, sizeof(data))) { | 199 | data, 8)) { |
201 | case RCODE_GENERATION: | 200 | case RCODE_GENERATION: |
202 | /* A generation change frees all bandwidth. */ | 201 | /* A generation change frees all bandwidth. */ |
203 | return allocate ? -EAGAIN : bandwidth; | 202 | return allocate ? -EAGAIN : bandwidth; |
@@ -215,9 +214,9 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, | |||
215 | } | 214 | } |
216 | 215 | ||
217 | static int manage_channel(struct fw_card *card, int irm_id, int generation, | 216 | static int manage_channel(struct fw_card *card, int irm_id, int generation, |
218 | u32 channels_mask, u64 offset, bool allocate) | 217 | u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) |
219 | { | 218 | { |
220 | __be32 data[2], c, all, old; | 219 | __be32 c, all, old; |
221 | int i, retry = 5; | 220 | int i, retry = 5; |
222 | 221 | ||
223 | old = all = allocate ? cpu_to_be32(~0) : 0; | 222 | old = all = allocate ? cpu_to_be32(~0) : 0; |
@@ -234,7 +233,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
234 | data[1] = old ^ c; | 233 | data[1] = old ^ c; |
235 | switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, | 234 | switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, |
236 | irm_id, generation, SCODE_100, | 235 | irm_id, generation, SCODE_100, |
237 | offset, data, sizeof(data))) { | 236 | offset, data, 8)) { |
238 | case RCODE_GENERATION: | 237 | case RCODE_GENERATION: |
239 | /* A generation change frees all channels. */ | 238 | /* A generation change frees all channels. */ |
240 | return allocate ? -EAGAIN : i; | 239 | return allocate ? -EAGAIN : i; |
@@ -260,7 +259,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, | |||
260 | } | 259 | } |
261 | 260 | ||
262 | static void deallocate_channel(struct fw_card *card, int irm_id, | 261 | static void deallocate_channel(struct fw_card *card, int irm_id, |
263 | int generation, int channel) | 262 | int generation, int channel, __be32 buffer[2]) |
264 | { | 263 | { |
265 | u32 mask; | 264 | u32 mask; |
266 | u64 offset; | 265 | u64 offset; |
@@ -269,7 +268,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, | |||
269 | offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : | 268 | offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : |
270 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; | 269 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; |
271 | 270 | ||
272 | manage_channel(card, irm_id, generation, mask, offset, false); | 271 | manage_channel(card, irm_id, generation, mask, offset, false, buffer); |
273 | } | 272 | } |
274 | 273 | ||
275 | /** | 274 | /** |
@@ -298,7 +297,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, | |||
298 | */ | 297 | */ |
299 | void fw_iso_resource_manage(struct fw_card *card, int generation, | 298 | void fw_iso_resource_manage(struct fw_card *card, int generation, |
300 | u64 channels_mask, int *channel, int *bandwidth, | 299 | u64 channels_mask, int *channel, int *bandwidth, |
301 | bool allocate) | 300 | bool allocate, __be32 buffer[2]) |
302 | { | 301 | { |
303 | u32 channels_hi = channels_mask; /* channels 31...0 */ | 302 | u32 channels_hi = channels_mask; /* channels 31...0 */ |
304 | u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ | 303 | u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ |
@@ -310,10 +309,12 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, | |||
310 | 309 | ||
311 | if (channels_hi) | 310 | if (channels_hi) |
312 | c = manage_channel(card, irm_id, generation, channels_hi, | 311 | c = manage_channel(card, irm_id, generation, channels_hi, |
313 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate); | 312 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, |
313 | allocate, buffer); | ||
314 | if (channels_lo && c < 0) { | 314 | if (channels_lo && c < 0) { |
315 | c = manage_channel(card, irm_id, generation, channels_lo, | 315 | c = manage_channel(card, irm_id, generation, channels_lo, |
316 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate); | 316 | CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, |
317 | allocate, buffer); | ||
317 | if (c >= 0) | 318 | if (c >= 0) |
318 | c += 32; | 319 | c += 32; |
319 | } | 320 | } |
@@ -325,12 +326,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, | |||
325 | if (*bandwidth == 0) | 326 | if (*bandwidth == 0) |
326 | return; | 327 | return; |
327 | 328 | ||
328 | ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate); | 329 | ret = manage_bandwidth(card, irm_id, generation, *bandwidth, |
330 | allocate, buffer); | ||
329 | if (ret < 0) | 331 | if (ret < 0) |
330 | *bandwidth = 0; | 332 | *bandwidth = 0; |
331 | 333 | ||
332 | if (allocate && ret < 0 && c >= 0) { | 334 | if (allocate && ret < 0 && c >= 0) { |
333 | deallocate_channel(card, irm_id, generation, c); | 335 | deallocate_channel(card, irm_id, generation, c, buffer); |
334 | *channel = ret; | 336 | *channel = ret; |
335 | } | 337 | } |
336 | } | 338 | } |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index c3cfc647e5e3..6052816be353 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -120,7 +120,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event); | |||
120 | 120 | ||
121 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); | 121 | int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma); |
122 | void fw_iso_resource_manage(struct fw_card *card, int generation, | 122 | void fw_iso_resource_manage(struct fw_card *card, int generation, |
123 | u64 channels_mask, int *channel, int *bandwidth, bool allocate); | 123 | u64 channels_mask, int *channel, int *bandwidth, |
124 | bool allocate, __be32 buffer[2]); | ||
124 | 125 | ||
125 | 126 | ||
126 | /* -topology */ | 127 | /* -topology */ |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index ecddd11b797a..76b321bb73f9 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/pci_ids.h> | ||
37 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
38 | #include <linux/string.h> | 39 | #include <linux/string.h> |
39 | 40 | ||
@@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev) | |||
2372 | #define ohci_pmac_off(dev) | 2373 | #define ohci_pmac_off(dev) |
2373 | #endif /* CONFIG_PPC_PMAC */ | 2374 | #endif /* CONFIG_PPC_PMAC */ |
2374 | 2375 | ||
2376 | #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT | ||
2377 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
2378 | |||
2375 | static int __devinit pci_probe(struct pci_dev *dev, | 2379 | static int __devinit pci_probe(struct pci_dev *dev, |
2376 | const struct pci_device_id *ent) | 2380 | const struct pci_device_id *ent) |
2377 | { | 2381 | { |
@@ -2422,6 +2426,16 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2422 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | 2426 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
2423 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | 2427 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; |
2424 | 2428 | ||
2429 | /* dual-buffer mode is broken if more than one IR context is active */ | ||
2430 | if (dev->vendor == PCI_VENDOR_ID_AGERE && | ||
2431 | dev->device == PCI_DEVICE_ID_AGERE_FW643) | ||
2432 | ohci->use_dualbuffer = false; | ||
2433 | |||
2434 | /* dual-buffer mode is broken */ | ||
2435 | if (dev->vendor == PCI_VENDOR_ID_RICOH && | ||
2436 | dev->device == PCI_DEVICE_ID_RICOH_R5C832) | ||
2437 | ohci->use_dualbuffer = false; | ||
2438 | |||
2425 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | 2439 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ |
2426 | #if !defined(CONFIG_X86_32) | 2440 | #if !defined(CONFIG_X86_32) |
2427 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | 2441 | /* dual-buffer mode is broken with descriptor addresses above 2G */ |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 24c45635376a..e5df822a8130 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -201,6 +201,12 @@ static struct fw_device *target_device(struct sbp2_target *tgt) | |||
201 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ | 201 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * There is no transport protocol limit to the CDB length, but we implement | ||
205 | * a fixed length only. 16 bytes is enough for disks larger than 2 TB. | ||
206 | */ | ||
207 | #define SBP2_MAX_CDB_SIZE 16 | ||
208 | |||
209 | /* | ||
204 | * The default maximum s/g segment size of a FireWire controller is | 210 | * The default maximum s/g segment size of a FireWire controller is |
205 | * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to | 211 | * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to |
206 | * be quadlet-aligned, we set the length limit to 0xffff & ~3. | 212 | * be quadlet-aligned, we set the length limit to 0xffff & ~3. |
@@ -312,7 +318,7 @@ struct sbp2_command_orb { | |||
312 | struct sbp2_pointer next; | 318 | struct sbp2_pointer next; |
313 | struct sbp2_pointer data_descriptor; | 319 | struct sbp2_pointer data_descriptor; |
314 | __be32 misc; | 320 | __be32 misc; |
315 | u8 command_block[12]; | 321 | u8 command_block[SBP2_MAX_CDB_SIZE]; |
316 | } request; | 322 | } request; |
317 | struct scsi_cmnd *cmd; | 323 | struct scsi_cmnd *cmd; |
318 | scsi_done_fn_t done; | 324 | scsi_done_fn_t done; |
@@ -450,12 +456,12 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
450 | } | 456 | } |
451 | spin_unlock_irqrestore(&card->lock, flags); | 457 | spin_unlock_irqrestore(&card->lock, flags); |
452 | 458 | ||
453 | if (&orb->link != &lu->orb_list) | 459 | if (&orb->link != &lu->orb_list) { |
454 | orb->callback(orb, &status); | 460 | orb->callback(orb, &status); |
455 | else | 461 | kref_put(&orb->kref, free_orb); |
462 | } else { | ||
456 | fw_error("status write for unknown orb\n"); | 463 | fw_error("status write for unknown orb\n"); |
457 | 464 | } | |
458 | kref_put(&orb->kref, free_orb); | ||
459 | 465 | ||
460 | fw_send_response(card, request, RCODE_COMPLETE); | 466 | fw_send_response(card, request, RCODE_COMPLETE); |
461 | } | 467 | } |
@@ -1146,6 +1152,8 @@ static int sbp2_probe(struct device *dev) | |||
1146 | if (fw_device_enable_phys_dma(device) < 0) | 1152 | if (fw_device_enable_phys_dma(device) < 0) |
1147 | goto fail_shost_put; | 1153 | goto fail_shost_put; |
1148 | 1154 | ||
1155 | shost->max_cmd_len = SBP2_MAX_CDB_SIZE; | ||
1156 | |||
1149 | if (scsi_add_host(shost, &unit->device) < 0) | 1157 | if (scsi_add_host(shost, &unit->device) < 0) |
1150 | goto fail_shost_put; | 1158 | goto fail_shost_put; |
1151 | 1159 | ||