diff options
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 144 |
1 files changed, 91 insertions, 53 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 328e31cc6854..fa385e761fe1 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -3,14 +3,15 @@ | |||
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | 5 | ||
6 | #define VERSION_CIO_QDIO_H "$Revision: 1.33 $" | 6 | #include "schid.h" |
7 | |||
8 | #define VERSION_CIO_QDIO_H "$Revision: 1.40 $" | ||
7 | 9 | ||
8 | #ifdef CONFIG_QDIO_DEBUG | 10 | #ifdef CONFIG_QDIO_DEBUG |
9 | #define QDIO_VERBOSE_LEVEL 9 | 11 | #define QDIO_VERBOSE_LEVEL 9 |
10 | #else /* CONFIG_QDIO_DEBUG */ | 12 | #else /* CONFIG_QDIO_DEBUG */ |
11 | #define QDIO_VERBOSE_LEVEL 5 | 13 | #define QDIO_VERBOSE_LEVEL 5 |
12 | #endif /* CONFIG_QDIO_DEBUG */ | 14 | #endif /* CONFIG_QDIO_DEBUG */ |
13 | |||
14 | #define QDIO_USE_PROCESSING_STATE | 15 | #define QDIO_USE_PROCESSING_STATE |
15 | 16 | ||
16 | #ifdef CONFIG_QDIO_PERF_STATS | 17 | #ifdef CONFIG_QDIO_PERF_STATS |
@@ -265,12 +266,64 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | |||
265 | /* | 266 | /* |
266 | * Some instructions as assembly | 267 | * Some instructions as assembly |
267 | */ | 268 | */ |
269 | |||
270 | static inline int | ||
271 | do_sqbs(unsigned long sch, unsigned char state, int queue, | ||
272 | unsigned int *start, unsigned int *count) | ||
273 | { | ||
274 | #ifdef CONFIG_64BIT | ||
275 | register unsigned long _ccq asm ("0") = *count; | ||
276 | register unsigned long _sch asm ("1") = sch; | ||
277 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | ||
278 | |||
279 | asm volatile ( | ||
280 | " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t" | ||
281 | : "+d" (_ccq), "+d" (_queuestart) | ||
282 | : "d" ((unsigned long)state), "d" (_sch) | ||
283 | : "memory", "cc" | ||
284 | ); | ||
285 | *count = _ccq & 0xff; | ||
286 | *start = _queuestart & 0xff; | ||
287 | |||
288 | return (_ccq >> 32) & 0xff; | ||
289 | #else | ||
290 | return 0; | ||
291 | #endif | ||
292 | } | ||
293 | |||
294 | static inline int | ||
295 | do_eqbs(unsigned long sch, unsigned char *state, int queue, | ||
296 | unsigned int *start, unsigned int *count) | ||
297 | { | ||
298 | #ifdef CONFIG_64BIT | ||
299 | register unsigned long _ccq asm ("0") = *count; | ||
300 | register unsigned long _sch asm ("1") = sch; | ||
301 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | ||
302 | unsigned long _state = 0; | ||
303 | |||
304 | asm volatile ( | ||
305 | " .insn rrf,0xB99c0000,%1,%2,0,0 \n\t" | ||
306 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) | ||
307 | : "d" (_sch) | ||
308 | : "memory", "cc" | ||
309 | ); | ||
310 | *count = _ccq & 0xff; | ||
311 | *start = _queuestart & 0xff; | ||
312 | *state = _state & 0xff; | ||
313 | |||
314 | return (_ccq >> 32) & 0xff; | ||
315 | #else | ||
316 | return 0; | ||
317 | #endif | ||
318 | } | ||
319 | |||
320 | |||
268 | static inline int | 321 | static inline int |
269 | do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) | 322 | do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) |
270 | { | 323 | { |
271 | int cc; | 324 | int cc; |
272 | 325 | ||
273 | #ifndef CONFIG_ARCH_S390X | 326 | #ifndef CONFIG_64BIT |
274 | asm volatile ( | 327 | asm volatile ( |
275 | "lhi 0,2 \n\t" | 328 | "lhi 0,2 \n\t" |
276 | "lr 1,%1 \n\t" | 329 | "lr 1,%1 \n\t" |
@@ -280,10 +333,10 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) | |||
280 | "ipm %0 \n\t" | 333 | "ipm %0 \n\t" |
281 | "srl %0,28 \n\t" | 334 | "srl %0,28 \n\t" |
282 | : "=d" (cc) | 335 | : "=d" (cc) |
283 | : "d" (0x10000|irq), "d" (mask1), "d" (mask2) | 336 | : "d" (schid), "d" (mask1), "d" (mask2) |
284 | : "cc", "0", "1", "2", "3" | 337 | : "cc", "0", "1", "2", "3" |
285 | ); | 338 | ); |
286 | #else /* CONFIG_ARCH_S390X */ | 339 | #else /* CONFIG_64BIT */ |
287 | asm volatile ( | 340 | asm volatile ( |
288 | "lghi 0,2 \n\t" | 341 | "lghi 0,2 \n\t" |
289 | "llgfr 1,%1 \n\t" | 342 | "llgfr 1,%1 \n\t" |
@@ -293,19 +346,19 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) | |||
293 | "ipm %0 \n\t" | 346 | "ipm %0 \n\t" |
294 | "srl %0,28 \n\t" | 347 | "srl %0,28 \n\t" |
295 | : "=d" (cc) | 348 | : "=d" (cc) |
296 | : "d" (0x10000|irq), "d" (mask1), "d" (mask2) | 349 | : "d" (schid), "d" (mask1), "d" (mask2) |
297 | : "cc", "0", "1", "2", "3" | 350 | : "cc", "0", "1", "2", "3" |
298 | ); | 351 | ); |
299 | #endif /* CONFIG_ARCH_S390X */ | 352 | #endif /* CONFIG_64BIT */ |
300 | return cc; | 353 | return cc; |
301 | } | 354 | } |
302 | 355 | ||
303 | static inline int | 356 | static inline int |
304 | do_siga_input(unsigned int irq, unsigned int mask) | 357 | do_siga_input(struct subchannel_id schid, unsigned int mask) |
305 | { | 358 | { |
306 | int cc; | 359 | int cc; |
307 | 360 | ||
308 | #ifndef CONFIG_ARCH_S390X | 361 | #ifndef CONFIG_64BIT |
309 | asm volatile ( | 362 | asm volatile ( |
310 | "lhi 0,1 \n\t" | 363 | "lhi 0,1 \n\t" |
311 | "lr 1,%1 \n\t" | 364 | "lr 1,%1 \n\t" |
@@ -314,10 +367,10 @@ do_siga_input(unsigned int irq, unsigned int mask) | |||
314 | "ipm %0 \n\t" | 367 | "ipm %0 \n\t" |
315 | "srl %0,28 \n\t" | 368 | "srl %0,28 \n\t" |
316 | : "=d" (cc) | 369 | : "=d" (cc) |
317 | : "d" (0x10000|irq), "d" (mask) | 370 | : "d" (schid), "d" (mask) |
318 | : "cc", "0", "1", "2", "memory" | 371 | : "cc", "0", "1", "2", "memory" |
319 | ); | 372 | ); |
320 | #else /* CONFIG_ARCH_S390X */ | 373 | #else /* CONFIG_64BIT */ |
321 | asm volatile ( | 374 | asm volatile ( |
322 | "lghi 0,1 \n\t" | 375 | "lghi 0,1 \n\t" |
323 | "llgfr 1,%1 \n\t" | 376 | "llgfr 1,%1 \n\t" |
@@ -326,21 +379,22 @@ do_siga_input(unsigned int irq, unsigned int mask) | |||
326 | "ipm %0 \n\t" | 379 | "ipm %0 \n\t" |
327 | "srl %0,28 \n\t" | 380 | "srl %0,28 \n\t" |
328 | : "=d" (cc) | 381 | : "=d" (cc) |
329 | : "d" (0x10000|irq), "d" (mask) | 382 | : "d" (schid), "d" (mask) |
330 | : "cc", "0", "1", "2", "memory" | 383 | : "cc", "0", "1", "2", "memory" |
331 | ); | 384 | ); |
332 | #endif /* CONFIG_ARCH_S390X */ | 385 | #endif /* CONFIG_64BIT */ |
333 | 386 | ||
334 | return cc; | 387 | return cc; |
335 | } | 388 | } |
336 | 389 | ||
337 | static inline int | 390 | static inline int |
338 | do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) | 391 | do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, |
392 | unsigned int fc) | ||
339 | { | 393 | { |
340 | int cc; | 394 | int cc; |
341 | __u32 busy_bit; | 395 | __u32 busy_bit; |
342 | 396 | ||
343 | #ifndef CONFIG_ARCH_S390X | 397 | #ifndef CONFIG_64BIT |
344 | asm volatile ( | 398 | asm volatile ( |
345 | "lhi 0,0 \n\t" | 399 | "lhi 0,0 \n\t" |
346 | "lr 1,%2 \n\t" | 400 | "lr 1,%2 \n\t" |
@@ -366,14 +420,14 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) | |||
366 | ".long 0b,2b \n\t" | 420 | ".long 0b,2b \n\t" |
367 | ".previous \n\t" | 421 | ".previous \n\t" |
368 | : "=d" (cc), "=d" (busy_bit) | 422 | : "=d" (cc), "=d" (busy_bit) |
369 | : "d" (0x10000|irq), "d" (mask), | 423 | : "d" (schid), "d" (mask), |
370 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) | 424 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) |
371 | : "cc", "0", "1", "2", "memory" | 425 | : "cc", "0", "1", "2", "memory" |
372 | ); | 426 | ); |
373 | #else /* CONFIG_ARCH_S390X */ | 427 | #else /* CONFIG_64BIT */ |
374 | asm volatile ( | 428 | asm volatile ( |
375 | "lghi 0,0 \n\t" | 429 | "llgfr 0,%5 \n\t" |
376 | "llgfr 1,%2 \n\t" | 430 | "lgr 1,%2 \n\t" |
377 | "llgfr 2,%3 \n\t" | 431 | "llgfr 2,%3 \n\t" |
378 | "siga 0 \n\t" | 432 | "siga 0 \n\t" |
379 | "0:" | 433 | "0:" |
@@ -391,11 +445,11 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) | |||
391 | ".quad 0b,1b \n\t" | 445 | ".quad 0b,1b \n\t" |
392 | ".previous \n\t" | 446 | ".previous \n\t" |
393 | : "=d" (cc), "=d" (busy_bit) | 447 | : "=d" (cc), "=d" (busy_bit) |
394 | : "d" (0x10000|irq), "d" (mask), | 448 | : "d" (schid), "d" (mask), |
395 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) | 449 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc) |
396 | : "cc", "0", "1", "2", "memory" | 450 | : "cc", "0", "1", "2", "memory" |
397 | ); | 451 | ); |
398 | #endif /* CONFIG_ARCH_S390X */ | 452 | #endif /* CONFIG_64BIT */ |
399 | 453 | ||
400 | (*bb) = busy_bit; | 454 | (*bb) = busy_bit; |
401 | return cc; | 455 | return cc; |
@@ -407,21 +461,21 @@ do_clear_global_summary(void) | |||
407 | 461 | ||
408 | unsigned long time; | 462 | unsigned long time; |
409 | 463 | ||
410 | #ifndef CONFIG_ARCH_S390X | 464 | #ifndef CONFIG_64BIT |
411 | asm volatile ( | 465 | asm volatile ( |
412 | "lhi 1,3 \n\t" | 466 | "lhi 1,3 \n\t" |
413 | ".insn rre,0xb2650000,2,0 \n\t" | 467 | ".insn rre,0xb2650000,2,0 \n\t" |
414 | "lr %0,3 \n\t" | 468 | "lr %0,3 \n\t" |
415 | : "=d" (time) : : "cc", "1", "2", "3" | 469 | : "=d" (time) : : "cc", "1", "2", "3" |
416 | ); | 470 | ); |
417 | #else /* CONFIG_ARCH_S390X */ | 471 | #else /* CONFIG_64BIT */ |
418 | asm volatile ( | 472 | asm volatile ( |
419 | "lghi 1,3 \n\t" | 473 | "lghi 1,3 \n\t" |
420 | ".insn rre,0xb2650000,2,0 \n\t" | 474 | ".insn rre,0xb2650000,2,0 \n\t" |
421 | "lgr %0,3 \n\t" | 475 | "lgr %0,3 \n\t" |
422 | : "=d" (time) : : "cc", "1", "2", "3" | 476 | : "=d" (time) : : "cc", "1", "2", "3" |
423 | ); | 477 | ); |
424 | #endif /* CONFIG_ARCH_S390X */ | 478 | #endif /* CONFIG_64BIT */ |
425 | 479 | ||
426 | return time; | 480 | return time; |
427 | } | 481 | } |
@@ -488,42 +542,21 @@ struct qdio_perf_stats { | |||
488 | 542 | ||
489 | #define MY_MODULE_STRING(x) #x | 543 | #define MY_MODULE_STRING(x) #x |
490 | 544 | ||
491 | #ifdef CONFIG_ARCH_S390X | 545 | #ifdef CONFIG_64BIT |
492 | #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x) | 546 | #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x) |
493 | #else /* CONFIG_ARCH_S390X */ | 547 | #else /* CONFIG_64BIT */ |
494 | #define QDIO_GET_ADDR(x) ((__u32)(long)x) | 548 | #define QDIO_GET_ADDR(x) ((__u32)(long)x) |
495 | #endif /* CONFIG_ARCH_S390X */ | 549 | #endif /* CONFIG_64BIT */ |
496 | |||
497 | #ifdef CONFIG_QDIO_DEBUG | ||
498 | #define set_slsb(x,y) \ | ||
499 | if(q->queue_type==QDIO_TRACE_QTYPE) { \ | ||
500 | if(q->is_input_q) { \ | ||
501 | QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ | ||
502 | } else { \ | ||
503 | QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ | ||
504 | } \ | ||
505 | } \ | ||
506 | qdio_set_slsb(x,y); \ | ||
507 | if(q->queue_type==QDIO_TRACE_QTYPE) { \ | ||
508 | if(q->is_input_q) { \ | ||
509 | QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ | ||
510 | } else { \ | ||
511 | QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ | ||
512 | } \ | ||
513 | } | ||
514 | #else /* CONFIG_QDIO_DEBUG */ | ||
515 | #define set_slsb(x,y) qdio_set_slsb(x,y) | ||
516 | #endif /* CONFIG_QDIO_DEBUG */ | ||
517 | 550 | ||
518 | struct qdio_q { | 551 | struct qdio_q { |
519 | volatile struct slsb slsb; | 552 | volatile struct slsb slsb; |
520 | 553 | ||
521 | char unused[QDIO_MAX_BUFFERS_PER_Q]; | 554 | char unused[QDIO_MAX_BUFFERS_PER_Q]; |
522 | 555 | ||
523 | __u32 * volatile dev_st_chg_ind; | 556 | __u32 * dev_st_chg_ind; |
524 | 557 | ||
525 | int is_input_q; | 558 | int is_input_q; |
526 | int irq; | 559 | struct subchannel_id schid; |
527 | struct ccw_device *cdev; | 560 | struct ccw_device *cdev; |
528 | 561 | ||
529 | unsigned int is_iqdio_q; | 562 | unsigned int is_iqdio_q; |
@@ -568,6 +601,7 @@ struct qdio_q { | |||
568 | struct tasklet_struct tasklet; | 601 | struct tasklet_struct tasklet; |
569 | #endif /* QDIO_USE_TIMERS_FOR_POLLING */ | 602 | #endif /* QDIO_USE_TIMERS_FOR_POLLING */ |
570 | 603 | ||
604 | |||
571 | enum qdio_irq_states state; | 605 | enum qdio_irq_states state; |
572 | 606 | ||
573 | /* used to store the error condition during a data transfer */ | 607 | /* used to store the error condition during a data transfer */ |
@@ -617,13 +651,17 @@ struct qdio_irq { | |||
617 | __u32 * volatile dev_st_chg_ind; | 651 | __u32 * volatile dev_st_chg_ind; |
618 | 652 | ||
619 | unsigned long int_parm; | 653 | unsigned long int_parm; |
620 | int irq; | 654 | struct subchannel_id schid; |
621 | 655 | ||
622 | unsigned int is_iqdio_irq; | 656 | unsigned int is_iqdio_irq; |
623 | unsigned int is_thinint_irq; | 657 | unsigned int is_thinint_irq; |
624 | unsigned int hydra_gives_outbound_pcis; | 658 | unsigned int hydra_gives_outbound_pcis; |
625 | unsigned int sync_done_on_outb_pcis; | 659 | unsigned int sync_done_on_outb_pcis; |
626 | 660 | ||
661 | /* QEBSM facility */ | ||
662 | unsigned int is_qebsm; | ||
663 | unsigned long sch_token; | ||
664 | |||
627 | enum qdio_irq_states state; | 665 | enum qdio_irq_states state; |
628 | 666 | ||
629 | unsigned int no_input_qs; | 667 | unsigned int no_input_qs; |