diff options
Diffstat (limited to 'drivers/firewire/core-device.c')
-rw-r--r-- | drivers/firewire/core-device.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 6113b896e790..95a471401892 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -725,6 +725,15 @@ struct fw_device *fw_device_get_by_devt(dev_t devt) | |||
725 | return device; | 725 | return device; |
726 | } | 726 | } |
727 | 727 | ||
728 | struct workqueue_struct *fw_workqueue; | ||
729 | EXPORT_SYMBOL(fw_workqueue); | ||
730 | |||
731 | static void fw_schedule_device_work(struct fw_device *device, | ||
732 | unsigned long delay) | ||
733 | { | ||
734 | queue_delayed_work(fw_workqueue, &device->work, delay); | ||
735 | } | ||
736 | |||
728 | /* | 737 | /* |
729 | * These defines control the retry behavior for reading the config | 738 | * These defines control the retry behavior for reading the config |
730 | * rom. It shouldn't be necessary to tweak these; if the device | 739 | * rom. It shouldn't be necessary to tweak these; if the device |
@@ -747,9 +756,10 @@ static void fw_device_shutdown(struct work_struct *work) | |||
747 | container_of(work, struct fw_device, work.work); | 756 | container_of(work, struct fw_device, work.work); |
748 | int minor = MINOR(device->device.devt); | 757 | int minor = MINOR(device->device.devt); |
749 | 758 | ||
750 | if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY) | 759 | if (time_before64(get_jiffies_64(), |
760 | device->card->reset_jiffies + SHUTDOWN_DELAY) | ||
751 | && !list_empty(&device->card->link)) { | 761 | && !list_empty(&device->card->link)) { |
752 | schedule_delayed_work(&device->work, SHUTDOWN_DELAY); | 762 | fw_schedule_device_work(device, SHUTDOWN_DELAY); |
753 | return; | 763 | return; |
754 | } | 764 | } |
755 | 765 | ||
@@ -861,7 +871,7 @@ static int lookup_existing_device(struct device *dev, void *data) | |||
861 | fw_notify("rediscovered device %s\n", dev_name(dev)); | 871 | fw_notify("rediscovered device %s\n", dev_name(dev)); |
862 | 872 | ||
863 | PREPARE_DELAYED_WORK(&old->work, fw_device_update); | 873 | PREPARE_DELAYED_WORK(&old->work, fw_device_update); |
864 | schedule_delayed_work(&old->work, 0); | 874 | fw_schedule_device_work(old, 0); |
865 | 875 | ||
866 | if (current_node == card->root_node) | 876 | if (current_node == card->root_node) |
867 | fw_schedule_bm_work(card, 0); | 877 | fw_schedule_bm_work(card, 0); |
@@ -952,10 +962,11 @@ static void fw_device_init(struct work_struct *work) | |||
952 | if (device->config_rom_retries < MAX_RETRIES && | 962 | if (device->config_rom_retries < MAX_RETRIES && |
953 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 963 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
954 | device->config_rom_retries++; | 964 | device->config_rom_retries++; |
955 | schedule_delayed_work(&device->work, RETRY_DELAY); | 965 | fw_schedule_device_work(device, RETRY_DELAY); |
956 | } else { | 966 | } else { |
957 | fw_notify("giving up on config rom for node id %x\n", | 967 | if (device->node->link_on) |
958 | device->node_id); | 968 | fw_notify("giving up on config rom for node id %x\n", |
969 | device->node_id); | ||
959 | if (device->node == device->card->root_node) | 970 | if (device->node == device->card->root_node) |
960 | fw_schedule_bm_work(device->card, 0); | 971 | fw_schedule_bm_work(device->card, 0); |
961 | fw_device_release(&device->device); | 972 | fw_device_release(&device->device); |
@@ -1017,7 +1028,7 @@ static void fw_device_init(struct work_struct *work) | |||
1017 | FW_DEVICE_INITIALIZING, | 1028 | FW_DEVICE_INITIALIZING, |
1018 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { | 1029 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { |
1019 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1030 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); |
1020 | schedule_delayed_work(&device->work, SHUTDOWN_DELAY); | 1031 | fw_schedule_device_work(device, SHUTDOWN_DELAY); |
1021 | } else { | 1032 | } else { |
1022 | if (device->config_rom_retries) | 1033 | if (device->config_rom_retries) |
1023 | fw_notify("created device %s: GUID %08x%08x, S%d00, " | 1034 | fw_notify("created device %s: GUID %08x%08x, S%d00, " |
@@ -1096,7 +1107,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1096 | if (device->config_rom_retries < MAX_RETRIES / 2 && | 1107 | if (device->config_rom_retries < MAX_RETRIES / 2 && |
1097 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1108 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
1098 | device->config_rom_retries++; | 1109 | device->config_rom_retries++; |
1099 | schedule_delayed_work(&device->work, RETRY_DELAY / 2); | 1110 | fw_schedule_device_work(device, RETRY_DELAY / 2); |
1100 | 1111 | ||
1101 | return; | 1112 | return; |
1102 | } | 1113 | } |
@@ -1129,7 +1140,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1129 | if (device->config_rom_retries < MAX_RETRIES && | 1140 | if (device->config_rom_retries < MAX_RETRIES && |
1130 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1141 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
1131 | device->config_rom_retries++; | 1142 | device->config_rom_retries++; |
1132 | schedule_delayed_work(&device->work, RETRY_DELAY); | 1143 | fw_schedule_device_work(device, RETRY_DELAY); |
1133 | 1144 | ||
1134 | return; | 1145 | return; |
1135 | } | 1146 | } |
@@ -1156,7 +1167,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1156 | gone: | 1167 | gone: |
1157 | atomic_set(&device->state, FW_DEVICE_GONE); | 1168 | atomic_set(&device->state, FW_DEVICE_GONE); |
1158 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1169 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); |
1159 | schedule_delayed_work(&device->work, SHUTDOWN_DELAY); | 1170 | fw_schedule_device_work(device, SHUTDOWN_DELAY); |
1160 | out: | 1171 | out: |
1161 | if (node_id == card->root_node->node_id) | 1172 | if (node_id == card->root_node->node_id) |
1162 | fw_schedule_bm_work(card, 0); | 1173 | fw_schedule_bm_work(card, 0); |
@@ -1168,9 +1179,12 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1168 | 1179 | ||
1169 | switch (event) { | 1180 | switch (event) { |
1170 | case FW_NODE_CREATED: | 1181 | case FW_NODE_CREATED: |
1171 | case FW_NODE_LINK_ON: | 1182 | /* |
1172 | if (!node->link_on) | 1183 | * Attempt to scan the node, regardless whether its self ID has |
1173 | break; | 1184 | * the L (link active) flag set or not. Some broken devices |
1185 | * send L=0 but have an up-and-running link; others send L=1 | ||
1186 | * without actually having a link. | ||
1187 | */ | ||
1174 | create: | 1188 | create: |
1175 | device = kzalloc(sizeof(*device), GFP_ATOMIC); | 1189 | device = kzalloc(sizeof(*device), GFP_ATOMIC); |
1176 | if (device == NULL) | 1190 | if (device == NULL) |
@@ -1209,10 +1223,11 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1209 | * first config rom scan half a second after bus reset. | 1223 | * first config rom scan half a second after bus reset. |
1210 | */ | 1224 | */ |
1211 | INIT_DELAYED_WORK(&device->work, fw_device_init); | 1225 | INIT_DELAYED_WORK(&device->work, fw_device_init); |
1212 | schedule_delayed_work(&device->work, INITIAL_DELAY); | 1226 | fw_schedule_device_work(device, INITIAL_DELAY); |
1213 | break; | 1227 | break; |
1214 | 1228 | ||
1215 | case FW_NODE_INITIATED_RESET: | 1229 | case FW_NODE_INITIATED_RESET: |
1230 | case FW_NODE_LINK_ON: | ||
1216 | device = node->data; | 1231 | device = node->data; |
1217 | if (device == NULL) | 1232 | if (device == NULL) |
1218 | goto create; | 1233 | goto create; |
@@ -1224,22 +1239,22 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1224 | FW_DEVICE_RUNNING, | 1239 | FW_DEVICE_RUNNING, |
1225 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { | 1240 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { |
1226 | PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); | 1241 | PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); |
1227 | schedule_delayed_work(&device->work, | 1242 | fw_schedule_device_work(device, |
1228 | device->is_local ? 0 : INITIAL_DELAY); | 1243 | device->is_local ? 0 : INITIAL_DELAY); |
1229 | } | 1244 | } |
1230 | break; | 1245 | break; |
1231 | 1246 | ||
1232 | case FW_NODE_UPDATED: | 1247 | case FW_NODE_UPDATED: |
1233 | if (!node->link_on || node->data == NULL) | 1248 | device = node->data; |
1249 | if (device == NULL) | ||
1234 | break; | 1250 | break; |
1235 | 1251 | ||
1236 | device = node->data; | ||
1237 | device->node_id = node->node_id; | 1252 | device->node_id = node->node_id; |
1238 | smp_wmb(); /* update node_id before generation */ | 1253 | smp_wmb(); /* update node_id before generation */ |
1239 | device->generation = card->generation; | 1254 | device->generation = card->generation; |
1240 | if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { | 1255 | if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { |
1241 | PREPARE_DELAYED_WORK(&device->work, fw_device_update); | 1256 | PREPARE_DELAYED_WORK(&device->work, fw_device_update); |
1242 | schedule_delayed_work(&device->work, 0); | 1257 | fw_schedule_device_work(device, 0); |
1243 | } | 1258 | } |
1244 | break; | 1259 | break; |
1245 | 1260 | ||
@@ -1264,7 +1279,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1264 | if (atomic_xchg(&device->state, | 1279 | if (atomic_xchg(&device->state, |
1265 | FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { | 1280 | FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { |
1266 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1281 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); |
1267 | schedule_delayed_work(&device->work, | 1282 | fw_schedule_device_work(device, |
1268 | list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); | 1283 | list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); |
1269 | } | 1284 | } |
1270 | break; | 1285 | break; |