aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-iso.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/firewire/core-iso.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/firewire/core-iso.c')
-rw-r--r--drivers/firewire/core-iso.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index c003fa4e2db1..57c3973093ad 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -185,6 +185,12 @@ int fw_iso_context_queue(struct fw_iso_context *ctx,
185} 185}
186EXPORT_SYMBOL(fw_iso_context_queue); 186EXPORT_SYMBOL(fw_iso_context_queue);
187 187
188void fw_iso_context_queue_flush(struct fw_iso_context *ctx)
189{
190 ctx->card->driver->flush_queue_iso(ctx);
191}
192EXPORT_SYMBOL(fw_iso_context_queue_flush);
193
188int fw_iso_context_stop(struct fw_iso_context *ctx) 194int fw_iso_context_stop(struct fw_iso_context *ctx)
189{ 195{
190 return ctx->card->driver->stop_iso(ctx); 196 return ctx->card->driver->stop_iso(ctx);
@@ -196,9 +202,10 @@ EXPORT_SYMBOL(fw_iso_context_stop);
196 */ 202 */
197 203
198static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, 204static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
199 int bandwidth, bool allocate, __be32 data[2]) 205 int bandwidth, bool allocate)
200{ 206{
201 int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; 207 int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
208 __be32 data[2];
202 209
203 /* 210 /*
204 * On a 1394a IRM with low contention, try < 1 is enough. 211 * On a 1394a IRM with low contention, try < 1 is enough.
@@ -233,47 +240,48 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
233} 240}
234 241
235static int manage_channel(struct fw_card *card, int irm_id, int generation, 242static int manage_channel(struct fw_card *card, int irm_id, int generation,
236 u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) 243 u32 channels_mask, u64 offset, bool allocate)
237{ 244{
238 __be32 c, all, old; 245 __be32 bit, all, old;
239 int i, ret = -EIO, retry = 5; 246 __be32 data[2];
247 int channel, ret = -EIO, retry = 5;
240 248
241 old = all = allocate ? cpu_to_be32(~0) : 0; 249 old = all = allocate ? cpu_to_be32(~0) : 0;
242 250
243 for (i = 0; i < 32; i++) { 251 for (channel = 0; channel < 32; channel++) {
244 if (!(channels_mask & 1 << i)) 252 if (!(channels_mask & 1 << channel))
245 continue; 253 continue;
246 254
247 ret = -EBUSY; 255 ret = -EBUSY;
248 256
249 c = cpu_to_be32(1 << (31 - i)); 257 bit = cpu_to_be32(1 << (31 - channel));
250 if ((old & c) != (all & c)) 258 if ((old & bit) != (all & bit))
251 continue; 259 continue;
252 260
253 data[0] = old; 261 data[0] = old;
254 data[1] = old ^ c; 262 data[1] = old ^ bit;
255 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, 263 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
256 irm_id, generation, SCODE_100, 264 irm_id, generation, SCODE_100,
257 offset, data, 8)) { 265 offset, data, 8)) {
258 case RCODE_GENERATION: 266 case RCODE_GENERATION:
259 /* A generation change frees all channels. */ 267 /* A generation change frees all channels. */
260 return allocate ? -EAGAIN : i; 268 return allocate ? -EAGAIN : channel;
261 269
262 case RCODE_COMPLETE: 270 case RCODE_COMPLETE:
263 if (data[0] == old) 271 if (data[0] == old)
264 return i; 272 return channel;
265 273
266 old = data[0]; 274 old = data[0];
267 275
268 /* Is the IRM 1394a-2000 compliant? */ 276 /* Is the IRM 1394a-2000 compliant? */
269 if ((data[0] & c) == (data[1] & c)) 277 if ((data[0] & bit) == (data[1] & bit))
270 continue; 278 continue;
271 279
272 /* 1394-1995 IRM, fall through to retry. */ 280 /* 1394-1995 IRM, fall through to retry. */
273 default: 281 default:
274 if (retry) { 282 if (retry) {
275 retry--; 283 retry--;
276 i--; 284 channel--;
277 } else { 285 } else {
278 ret = -EIO; 286 ret = -EIO;
279 } 287 }
@@ -284,7 +292,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
284} 292}
285 293
286static void deallocate_channel(struct fw_card *card, int irm_id, 294static void deallocate_channel(struct fw_card *card, int irm_id,
287 int generation, int channel, __be32 buffer[2]) 295 int generation, int channel)
288{ 296{
289 u32 mask; 297 u32 mask;
290 u64 offset; 298 u64 offset;
@@ -293,7 +301,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
293 offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : 301 offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
294 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; 302 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
295 303
296 manage_channel(card, irm_id, generation, mask, offset, false, buffer); 304 manage_channel(card, irm_id, generation, mask, offset, false);
297} 305}
298 306
299/** 307/**
@@ -322,7 +330,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
322 */ 330 */
323void fw_iso_resource_manage(struct fw_card *card, int generation, 331void fw_iso_resource_manage(struct fw_card *card, int generation,
324 u64 channels_mask, int *channel, int *bandwidth, 332 u64 channels_mask, int *channel, int *bandwidth,
325 bool allocate, __be32 buffer[2]) 333 bool allocate)
326{ 334{
327 u32 channels_hi = channels_mask; /* channels 31...0 */ 335 u32 channels_hi = channels_mask; /* channels 31...0 */
328 u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ 336 u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
@@ -335,11 +343,11 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
335 if (channels_hi) 343 if (channels_hi)
336 c = manage_channel(card, irm_id, generation, channels_hi, 344 c = manage_channel(card, irm_id, generation, channels_hi,
337 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, 345 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
338 allocate, buffer); 346 allocate);
339 if (channels_lo && c < 0) { 347 if (channels_lo && c < 0) {
340 c = manage_channel(card, irm_id, generation, channels_lo, 348 c = manage_channel(card, irm_id, generation, channels_lo,
341 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, 349 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
342 allocate, buffer); 350 allocate);
343 if (c >= 0) 351 if (c >= 0)
344 c += 32; 352 c += 32;
345 } 353 }
@@ -351,14 +359,14 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
351 if (*bandwidth == 0) 359 if (*bandwidth == 0)
352 return; 360 return;
353 361
354 ret = manage_bandwidth(card, irm_id, generation, *bandwidth, 362 ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
355 allocate, buffer);
356 if (ret < 0) 363 if (ret < 0)
357 *bandwidth = 0; 364 *bandwidth = 0;
358 365
359 if (allocate && ret < 0) { 366 if (allocate && ret < 0) {
360 if (c >= 0) 367 if (c >= 0)
361 deallocate_channel(card, irm_id, generation, c, buffer); 368 deallocate_channel(card, irm_id, generation, c);
362 *channel = ret; 369 *channel = ret;
363 } 370 }
364} 371}
372EXPORT_SYMBOL(fw_iso_resource_manage);