aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2011-01-05 06:47:54 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 06:47:28 -0500
commit90adac58d1a4daf3560739ff5b76497d5ece16c4 (patch)
tree6304b54c5b8200de91f3c151051a412a3536d0f4 /drivers/s390
parent110da31709023de61735f2d8a3e52c20c23bb570 (diff)
[S390] qdio: cleanup SIGA sync
Simplify the SIGA sync code and add unlikely annotations. In polling mode SBALs may be accessed without interrupt, so call SIGA sync before every scan. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio.h16
-rw-r--r--drivers/s390/cio/qdio_main.c64
-rw-r--r--drivers/s390/cio/qdio_setup.c19
3 files changed, 44 insertions, 55 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 1b40a92fec14..7bc643f3f5ab 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -148,10 +148,9 @@ struct siga_flag {
148 u8 input:1; 148 u8 input:1;
149 u8 output:1; 149 u8 output:1;
150 u8 sync:1; 150 u8 sync:1;
151 u8 no_sync_ti:1; 151 u8 sync_after_ai:1;
152 u8 no_sync_out_ti:1; 152 u8 sync_out_after_pci:1;
153 u8 no_sync_out_pci:1; 153 u8:3;
154 u8:2;
155} __attribute__ ((packed)); 154} __attribute__ ((packed));
156 155
157struct chsc_ssqd_area { 156struct chsc_ssqd_area {
@@ -390,12 +389,13 @@ static inline int multicast_outbound(struct qdio_q *q)
390 (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) 389 (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)
391#define is_qebsm(q) (q->irq_ptr->sch_token != 0) 390#define is_qebsm(q) (q->irq_ptr->sch_token != 0)
392 391
393#define need_siga_sync_thinint(q) (!q->irq_ptr->siga_flag.no_sync_ti)
394#define need_siga_sync_out_thinint(q) (!q->irq_ptr->siga_flag.no_sync_out_ti)
395#define need_siga_in(q) (q->irq_ptr->siga_flag.input) 392#define need_siga_in(q) (q->irq_ptr->siga_flag.input)
396#define need_siga_out(q) (q->irq_ptr->siga_flag.output) 393#define need_siga_out(q) (q->irq_ptr->siga_flag.output)
397#define need_siga_sync(q) (q->irq_ptr->siga_flag.sync) 394#define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync))
398#define siga_syncs_out_pci(q) (q->irq_ptr->siga_flag.no_sync_out_pci) 395#define need_siga_sync_after_ai(q) \
396 (unlikely(q->irq_ptr->siga_flag.sync_after_ai))
397#define need_siga_sync_out_after_pci(q) \
398 (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci))
399 399
400#define for_each_input_queue(irq_ptr, q, i) \ 400#define for_each_input_queue(irq_ptr, q, i) \
401 for (i = 0, q = irq_ptr->input_qs[0]; \ 401 for (i = 0, q = irq_ptr->input_qs[0]; \
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 8a722f208325..e9fff2b9bce2 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -286,9 +286,6 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
286 unsigned int fc = QDIO_SIGA_SYNC; 286 unsigned int fc = QDIO_SIGA_SYNC;
287 int cc; 287 int cc;
288 288
289 if (!need_siga_sync(q))
290 return 0;
291
292 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); 289 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr);
293 qperf_inc(q, siga_sync); 290 qperf_inc(q, siga_sync);
294 291
@@ -311,16 +308,6 @@ static inline int qdio_siga_sync_q(struct qdio_q *q)
311 return qdio_siga_sync(q, q->mask, 0); 308 return qdio_siga_sync(q, q->mask, 0);
312} 309}
313 310
314static inline int qdio_siga_sync_out(struct qdio_q *q)
315{
316 return qdio_siga_sync(q, ~0U, 0);
317}
318
319static inline int qdio_siga_sync_all(struct qdio_q *q)
320{
321 return qdio_siga_sync(q, ~0U, ~0U);
322}
323
324static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit) 311static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit)
325{ 312{
326 unsigned long schid = *((u32 *) &q->irq_ptr->schid); 313 unsigned long schid = *((u32 *) &q->irq_ptr->schid);
@@ -369,21 +356,23 @@ static inline int qdio_siga_input(struct qdio_q *q)
369 return cc; 356 return cc;
370} 357}
371 358
372static inline void qdio_sync_after_thinint(struct qdio_q *q) 359#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
360#define qdio_siga_sync_all(q) qdio_siga_sync(q, ~0U, ~0U)
361
362static inline void qdio_sync_queues(struct qdio_q *q)
373{ 363{
374 if (pci_out_supported(q)) { 364 /* PCI capable outbound queues will also be scanned so sync them too */
375 if (need_siga_sync_thinint(q)) 365 if (pci_out_supported(q))
376 qdio_siga_sync_all(q); 366 qdio_siga_sync_all(q);
377 else if (need_siga_sync_out_thinint(q)) 367 else
378 qdio_siga_sync_out(q);
379 } else
380 qdio_siga_sync_q(q); 368 qdio_siga_sync_q(q);
381} 369}
382 370
383int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, 371int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
384 unsigned char *state) 372 unsigned char *state)
385{ 373{
386 qdio_siga_sync_q(q); 374 if (need_siga_sync(q))
375 qdio_siga_sync_q(q);
387 return get_buf_states(q, bufnr, state, 1, 0); 376 return get_buf_states(q, bufnr, state, 1, 0);
388} 377}
389 378
@@ -560,7 +549,8 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
560 if (!atomic_read(&q->nr_buf_used)) 549 if (!atomic_read(&q->nr_buf_used))
561 return 1; 550 return 1;
562 551
563 qdio_siga_sync_q(q); 552 if (need_siga_sync(q))
553 qdio_siga_sync_q(q);
564 get_buf_state(q, q->first_to_check, &state, 0); 554 get_buf_state(q, q->first_to_check, &state, 0);
565 555
566 if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR) 556 if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
@@ -655,9 +645,12 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
655 int count, stop; 645 int count, stop;
656 unsigned char state; 646 unsigned char state;
657 647
658 if (((queue_type(q) != QDIO_IQDIO_QFMT) && !pci_out_supported(q)) || 648 if (need_siga_sync(q))
659 (queue_type(q) == QDIO_IQDIO_QFMT && multicast_outbound(q))) 649 if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
660 qdio_siga_sync_q(q); 650 !pci_out_supported(q)) ||
651 (queue_type(q) == QDIO_IQDIO_QFMT &&
652 multicast_outbound(q)))
653 qdio_siga_sync_q(q);
661 654
662 /* 655 /*
663 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 656 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -829,7 +822,8 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
829static void __tiqdio_inbound_processing(struct qdio_q *q) 822static void __tiqdio_inbound_processing(struct qdio_q *q)
830{ 823{
831 qperf_inc(q, tasklet_inbound); 824 qperf_inc(q, tasklet_inbound);
832 qdio_sync_after_thinint(q); 825 if (need_siga_sync(q) && need_siga_sync_after_ai(q))
826 qdio_sync_queues(q);
833 827
834 /* 828 /*
835 * The interrupt could be caused by a PCI request. Check the 829 * The interrupt could be caused by a PCI request. Check the
@@ -909,16 +903,14 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
909 tasklet_schedule(&q->tasklet); 903 tasklet_schedule(&q->tasklet);
910 } 904 }
911 905
912 if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) 906 if (!pci_out_supported(q))
913 return; 907 return;
914 908
915 for_each_output_queue(irq_ptr, q, i) { 909 for_each_output_queue(irq_ptr, q, i) {
916 if (qdio_outbound_q_done(q)) 910 if (qdio_outbound_q_done(q))
917 continue; 911 continue;
918 912 if (need_siga_sync(q) && need_siga_sync_out_after_pci(q))
919 if (!siga_syncs_out_pci(q))
920 qdio_siga_sync_q(q); 913 qdio_siga_sync_q(q);
921
922 tasklet_schedule(&q->tasklet); 914 tasklet_schedule(&q->tasklet);
923 } 915 }
924} 916}
@@ -1470,7 +1462,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1470 WARN_ON_ONCE(count > 1 && !multicast_outbound(q)); 1462 WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
1471 1463
1472 rc = qdio_kick_outbound_q(q); 1464 rc = qdio_kick_outbound_q(q);
1473 } else if (unlikely(need_siga_sync(q))) { 1465 } else if (need_siga_sync(q)) {
1474 rc = qdio_siga_sync_q(q); 1466 rc = qdio_siga_sync_q(q);
1475 } else { 1467 } else {
1476 /* try to fast requeue buffers */ 1468 /* try to fast requeue buffers */
@@ -1597,12 +1589,14 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
1597 q = irq_ptr->input_qs[nr]; 1589 q = irq_ptr->input_qs[nr];
1598 WARN_ON(queue_irqs_enabled(q)); 1590 WARN_ON(queue_irqs_enabled(q));
1599 1591
1600 qdio_sync_after_thinint(q);
1601
1602 /* 1592 /*
1603 * The interrupt could be caused by a PCI request. Check the 1593 * Cannot rely on automatic sync after interrupt since queues may
1604 * PCI capable outbound queues. 1594 * also be examined without interrupt.
1605 */ 1595 */
1596 if (need_siga_sync(q))
1597 qdio_sync_queues(q);
1598
1599 /* check the PCI capable outbound queues. */
1606 qdio_check_outbound_after_thinint(q); 1600 qdio_check_outbound_after_thinint(q);
1607 1601
1608 if (!qdio_inbound_q_moved(q)) 1602 if (!qdio_inbound_q_moved(q))
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 635f35dc8466..89107d0938c4 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -197,14 +197,10 @@ static void process_ac_flags(struct qdio_irq *irq_ptr, unsigned char qdioac)
197 irq_ptr->siga_flag.output = 1; 197 irq_ptr->siga_flag.output = 1;
198 if (qdioac & AC1_SIGA_SYNC_NEEDED) 198 if (qdioac & AC1_SIGA_SYNC_NEEDED)
199 irq_ptr->siga_flag.sync = 1; 199 irq_ptr->siga_flag.sync = 1;
200 if (qdioac & AC1_AUTOMATIC_SYNC_ON_THININT) 200 if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_THININT))
201 irq_ptr->siga_flag.no_sync_ti = 1; 201 irq_ptr->siga_flag.sync_after_ai = 1;
202 if (qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI) 202 if (!(qdioac & AC1_AUTOMATIC_SYNC_ON_OUT_PCI))
203 irq_ptr->siga_flag.no_sync_out_pci = 1; 203 irq_ptr->siga_flag.sync_out_after_pci = 1;
204
205 if (irq_ptr->siga_flag.no_sync_out_pci &&
206 irq_ptr->siga_flag.no_sync_ti)
207 irq_ptr->siga_flag.no_sync_out_ti = 1;
208} 204}
209 205
210static void check_and_setup_qebsm(struct qdio_irq *irq_ptr, 206static void check_and_setup_qebsm(struct qdio_irq *irq_ptr,
@@ -452,7 +448,7 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
452 char s[80]; 448 char s[80];
453 449
454 snprintf(s, 80, "qdio: %s %s on SC %x using " 450 snprintf(s, 80, "qdio: %s %s on SC %x using "
455 "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s%s\n", 451 "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s\n",
456 dev_name(&cdev->dev), 452 dev_name(&cdev->dev),
457 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" : 453 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" :
458 ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"), 454 ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"),
@@ -464,9 +460,8 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
464 (irq_ptr->siga_flag.input) ? "R" : " ", 460 (irq_ptr->siga_flag.input) ? "R" : " ",
465 (irq_ptr->siga_flag.output) ? "W" : " ", 461 (irq_ptr->siga_flag.output) ? "W" : " ",
466 (irq_ptr->siga_flag.sync) ? "S" : " ", 462 (irq_ptr->siga_flag.sync) ? "S" : " ",
467 (!irq_ptr->siga_flag.no_sync_ti) ? "A" : " ", 463 (irq_ptr->siga_flag.sync_after_ai) ? "A" : " ",
468 (!irq_ptr->siga_flag.no_sync_out_ti) ? "O" : " ", 464 (irq_ptr->siga_flag.sync_out_after_pci) ? "P" : " ");
469 (!irq_ptr->siga_flag.no_sync_out_pci) ? "P" : " ");
470 printk(KERN_INFO "%s", s); 465 printk(KERN_INFO "%s", s);
471} 466}
472 467