diff options
-rw-r--r-- | drivers/firewire/fw-cdev.c | 2 | ||||
-rw-r--r-- | drivers/firewire/fw-device.c | 38 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 1 | ||||
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 7 | ||||
-rw-r--r-- | drivers/firewire/fw-topology.h | 13 |
5 files changed, 45 insertions, 16 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dbb76427d529..75388641a7d3 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
@@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer) | |||
397 | request->tcode & 0x1f, | 397 | request->tcode & 0x1f, |
398 | device->node->node_id, | 398 | device->node->node_id, |
399 | request->generation, | 399 | request->generation, |
400 | device->node->max_speed, | 400 | device->max_speed, |
401 | request->offset, | 401 | request->offset, |
402 | response->response.data, request->length, | 402 | response->response.data, request->length, |
403 | complete_transaction, response); | 403 | complete_transaction, response); |
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index c1ce465d9710..2b6586341635 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data) | |||
401 | 401 | ||
402 | offset = 0xfffff0000400ULL + index * 4; | 402 | offset = 0xfffff0000400ULL + index * 4; |
403 | fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, | 403 | fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, |
404 | device->node_id, | 404 | device->node_id, device->generation, device->max_speed, |
405 | device->generation, SCODE_100, | ||
406 | offset, NULL, 4, complete_transaction, &callback_data); | 405 | offset, NULL, 4, complete_transaction, &callback_data); |
407 | 406 | ||
408 | wait_for_completion(&callback_data.done); | 407 | wait_for_completion(&callback_data.done); |
@@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device) | |||
418 | u32 stack[16], sp, key; | 417 | u32 stack[16], sp, key; |
419 | int i, end, length; | 418 | int i, end, length; |
420 | 419 | ||
420 | device->max_speed = SCODE_100; | ||
421 | |||
421 | /* First read the bus info block. */ | 422 | /* First read the bus info block. */ |
422 | for (i = 0; i < 5; i++) { | 423 | for (i = 0; i < 5; i++) { |
423 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) | 424 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) |
@@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device) | |||
434 | return -1; | 435 | return -1; |
435 | } | 436 | } |
436 | 437 | ||
438 | device->max_speed = device->node->max_speed; | ||
439 | |||
440 | /* | ||
441 | * Determine the speed of | ||
442 | * - devices with link speed less than PHY speed, | ||
443 | * - devices with 1394b PHY (unless only connected to 1394a PHYs), | ||
444 | * - all devices if there are 1394b repeaters. | ||
445 | * Note, we cannot use the bus info block's link_spd as starting point | ||
446 | * because some buggy firmwares set it lower than necessary and because | ||
447 | * 1394-1995 nodes do not have the field. | ||
448 | */ | ||
449 | if ((rom[2] & 0x7) < device->max_speed || | ||
450 | device->max_speed == SCODE_BETA || | ||
451 | device->card->beta_repeaters_present) { | ||
452 | u32 dummy; | ||
453 | |||
454 | /* for S1600 and S3200 */ | ||
455 | if (device->max_speed == SCODE_BETA) | ||
456 | device->max_speed = device->card->link_speed; | ||
457 | |||
458 | while (device->max_speed > SCODE_100) { | ||
459 | if (read_rom(device, 0, &dummy) == RCODE_COMPLETE) | ||
460 | break; | ||
461 | device->max_speed--; | ||
462 | } | ||
463 | } | ||
464 | |||
437 | /* | 465 | /* |
438 | * Now parse the config rom. The config rom is a recursive | 466 | * Now parse the config rom. The config rom is a recursive |
439 | * directory structure so we parse it using a stack of | 467 | * directory structure so we parse it using a stack of |
@@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work) | |||
680 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 708 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) |
681 | fw_device_shutdown(&device->work.work); | 709 | fw_device_shutdown(&device->work.work); |
682 | else | 710 | else |
683 | fw_notify("created new fw device %s (%d config rom retries)\n", | 711 | fw_notify("created new fw device %s " |
684 | device->device.bus_id, device->config_rom_retries); | 712 | "(%d config rom retries, S%d00)\n", |
713 | device->device.bus_id, device->config_rom_retries, | ||
714 | 1 << device->max_speed); | ||
685 | 715 | ||
686 | /* | 716 | /* |
687 | * Reschedule the IRM work if we just finished reading the | 717 | * Reschedule the IRM work if we just finished reading the |
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index af1723eae4ba..d13e6a69707f 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h | |||
@@ -40,6 +40,7 @@ struct fw_device { | |||
40 | struct fw_node *node; | 40 | struct fw_node *node; |
41 | int node_id; | 41 | int node_id; |
42 | int generation; | 42 | int generation; |
43 | unsigned max_speed; | ||
43 | struct fw_card *card; | 44 | struct fw_card *card; |
44 | struct device device; | 45 | struct device device; |
45 | struct list_head link; | 46 | struct list_head link; |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 16e942f72e48..851c2da060d2 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -346,8 +346,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, | |||
346 | spin_unlock_irqrestore(&device->card->lock, flags); | 346 | spin_unlock_irqrestore(&device->card->lock, flags); |
347 | 347 | ||
348 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 348 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
349 | node_id, generation, | 349 | node_id, generation, device->max_speed, offset, |
350 | device->node->max_speed, offset, | ||
351 | &orb->pointer, sizeof(orb->pointer), | 350 | &orb->pointer, sizeof(orb->pointer), |
352 | complete_transaction, orb); | 351 | complete_transaction, orb); |
353 | } | 352 | } |
@@ -1018,8 +1017,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1018 | * if we set this to max_speed + 7, we get the right value. | 1017 | * if we set this to max_speed + 7, we get the right value. |
1019 | */ | 1018 | */ |
1020 | orb->request.misc = | 1019 | orb->request.misc = |
1021 | COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | | 1020 | COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) | |
1022 | COMMAND_ORB_SPEED(device->node->max_speed) | | 1021 | COMMAND_ORB_SPEED(device->max_speed) | |
1023 | COMMAND_ORB_NOTIFY; | 1022 | COMMAND_ORB_NOTIFY; |
1024 | 1023 | ||
1025 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) | 1024 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) |
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index aced9f7db358..da61ec09183e 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h | |||
@@ -29,19 +29,18 @@ enum { | |||
29 | 29 | ||
30 | struct fw_port { | 30 | struct fw_port { |
31 | struct fw_node *node; | 31 | struct fw_node *node; |
32 | unsigned speed : 3; /* S100, S200, ... S3200 */ | ||
33 | }; | 32 | }; |
34 | 33 | ||
35 | struct fw_node { | 34 | struct fw_node { |
36 | u16 node_id; | 35 | u16 node_id; |
37 | u8 color; | 36 | u8 color; |
38 | u8 port_count; | 37 | u8 port_count; |
39 | unsigned link_on : 1; | 38 | u8 link_on : 1; |
40 | unsigned initiated_reset : 1; | 39 | u8 initiated_reset : 1; |
41 | unsigned b_path : 1; | 40 | u8 b_path : 1; |
42 | u8 phy_speed : 3; /* As in the self ID packet. */ | 41 | u8 phy_speed : 2; /* As in the self ID packet. */ |
43 | u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on | 42 | u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the |
44 | * the path from the local node to this node. */ | 43 | * local node to this node. */ |
45 | u8 max_depth : 4; /* Maximum depth to any leaf node */ | 44 | u8 max_depth : 4; /* Maximum depth to any leaf node */ |
46 | u8 max_hops : 4; /* Max hops in this sub tree */ | 45 | u8 max_hops : 4; /* Max hops in this sub tree */ |
47 | atomic_t ref_count; | 46 | atomic_t ref_count; |