]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/firewire/fw-device.c
ACPI: thinkpad-acpi: store ThinkPad model information
[linux-2.6-omap-h63xx.git] / drivers / firewire / fw-device.c
index 8e5f17f5e98a4ef0e71bfe2c9c382d5a1cdaf095..2b6586341635b9ed57dafc5f6ebb977924177010 100644 (file)
@@ -138,7 +138,7 @@ fw_unit_uevent(struct device *dev, char **envp, int num_envp,
        int length = 0;
        int i = 0;
 
-       get_modalias(unit, modalias, sizeof modalias);
+       get_modalias(unit, modalias, sizeof(modalias));
 
        if (add_uevent_var(envp, num_envp, &i,
                           buffer, buffer_size, &length,
@@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data)
 
        offset = 0xfffff0000400ULL + index * 4;
        fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
-                       device->node_id,
-                       device->generation, SCODE_100,
+                       device->node_id, device->generation, device->max_speed,
                        offset, NULL, 4, complete_transaction, &callback_data);
 
        wait_for_completion(&callback_data.done);
@@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device)
        u32 stack[16], sp, key;
        int i, end, length;
 
+       device->max_speed = SCODE_100;
+
        /* First read the bus info block. */
        for (i = 0; i < 5; i++) {
                if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
@@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device)
                        return -1;
        }
 
+       device->max_speed = device->node->max_speed;
+
+       /*
+        * Determine the speed of
+        *   - devices with link speed less than PHY speed,
+        *   - devices with 1394b PHY (unless only connected to 1394a PHYs),
+        *   - all devices if there are 1394b repeaters.
+        * Note, we cannot use the bus info block's link_spd as starting point
+        * because some buggy firmwares set it lower than necessary and because
+        * 1394-1995 nodes do not have the field.
+        */
+       if ((rom[2] & 0x7) < device->max_speed ||
+           device->max_speed == SCODE_BETA ||
+           device->card->beta_repeaters_present) {
+               u32 dummy;
+
+               /* for S1600 and S3200 */
+               if (device->max_speed == SCODE_BETA)
+                       device->max_speed = device->card->link_speed;
+
+               while (device->max_speed > SCODE_100) {
+                       if (read_rom(device, 0, &dummy) == RCODE_COMPLETE)
+                               break;
+                       device->max_speed--;
+               }
+       }
+
        /*
         * Now parse the config rom.  The config rom is a recursive
         * directory structure so we parse it using a stack of
@@ -533,7 +561,7 @@ static void create_units(struct fw_device *device)
                 * Get the address of the unit directory and try to
                 * match the drivers id_tables against it.
                 */
-               unit = kzalloc(sizeof *unit, GFP_KERNEL);
+               unit = kzalloc(sizeof(*unit), GFP_KERNEL);
                if (unit == NULL) {
                        fw_error("failed to allocate memory for unit\n");
                        continue;
@@ -543,7 +571,7 @@ static void create_units(struct fw_device *device)
                unit->device.bus = &fw_bus_type;
                unit->device.type = &fw_unit_type;
                unit->device.parent = &device->device;
-               snprintf(unit->device.bus_id, sizeof unit->device.bus_id,
+               snprintf(unit->device.bus_id, sizeof(unit->device.bus_id),
                         "%s.%d", device->device.bus_id, i++);
 
                init_fw_attribute_group(&unit->device,
@@ -653,7 +681,7 @@ static void fw_device_init(struct work_struct *work)
        device->device.type = &fw_device_type;
        device->device.parent = device->card->device;
        device->device.devt = MKDEV(fw_cdev_major, minor);
-       snprintf(device->device.bus_id, sizeof device->device.bus_id,
+       snprintf(device->device.bus_id, sizeof(device->device.bus_id),
                 "fw%d", minor);
 
        init_fw_attribute_group(&device->device,
@@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work)
                    FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
                fw_device_shutdown(&device->work.work);
        else
-               fw_notify("created new fw device %s (%d config rom retries)\n",
-                         device->device.bus_id, device->config_rom_retries);
+               fw_notify("created new fw device %s "
+                         "(%d config rom retries, S%d00)\n",
+                         device->device.bus_id, device->config_rom_retries,
+                         1 << device->max_speed);
 
        /*
         * Reschedule the IRM work if we just finished reading the