#include "ioasm.h"
#include "chsc.h"
-#define VERSION_QDIO_C "$Revision: 1.86 $"
+#define VERSION_QDIO_C "$Revision: 1.98 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
/* iQDIO stuff: */
static volatile struct qdio_q *tiq_list=NULL; /* volatile as it could change
during a while loop */
-static spinlock_t ttiq_list_lock=SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ttiq_list_lock);
static int register_thinint_result;
static void tiqdio_tl(unsigned long);
static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0);
sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
atomic_read(&q->busy_siga_counter));
QDIO_DBF_TEXT3(0,trace,dbf_text);
- q->timing.busy_start=0;
#endif /* CONFIG_QDIO_DEBUG */
+ q->timing.busy_start=0;
break;
case (2|QDIO_SIGA_ERROR_B_BIT_SET):
/* cc=2 and busy bit: */
#endif /* QDIO_USE_PROCESSING_STATE */
/*
* not needed, as the inbound queue will be synced on the next
- * siga-r
+ * siga-r, resp. tiqdio_is_inbound_q_done will do the siga-s
*/
/*SYNC_MEMORY;*/
f++;
/* means, no more buffers to be filled */
inline static int
-iqdio_is_inbound_q_done(struct qdio_q *q)
+tiqdio_is_inbound_q_done(struct qdio_q *q)
{
int no_used;
#ifdef CONFIG_QDIO_DEBUG
goto out;
qdio_kick_inbound_handler(q);
- if (iqdio_is_inbound_q_done(q))
+ if (tiqdio_is_inbound_q_done(q))
if (!qdio_stop_polling(q)) {
/*
* we set the flags to get into the stuff next time,
"installed.\n");
return -ENOENT;
}
+
/* Check for bits 107 and 108. */
if (!css_chsc_characteristics.scssc ||
!css_chsc_characteristics.scsscf) {
u32 kc:4;
u32 reserved4:21;
u32 isc:3;
- u32 reserved5[2];
+ u32 word_with_d_bit;
+ /* set to 0x10000000 to enable
+ * time delay disablement facility */
+ u32 reserved5;
u32 subsystem_id;
u32 reserved6[1004];
struct chsc_header response;
scssc_area->kc = QDIO_STORAGE_KEY;
scssc_area->isc = TIQDIO_THININT_ISC;
scssc_area->subsystem_id = (1<<16) + irq_ptr->irq;
+ /* enables the time delay disablement facility. Don't care
+ * whether it is really there (i.e. we haven't checked for
+ * it) */
+ if (css_general_characteristics.aif_tdd)
+ scssc_area->word_with_d_bit = 0x10000000;
+ else
+ QDIO_PRINT_WARN("Time delay disablement facility " \
+ "not available\n");
+
+
result = chsc(scssc_area);
if (result) {
/* No need to wait for device no longer present. */
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
+ } else if (((void *)cdev->handler != (void *)qdio_handler) && rc == 0) {
+ /*
+ * Whoever put another handler there, has to cope with the
+ * interrupt theirself. Might happen if qdio_shutdown was
+ * called on already shutdown queues, but this shouldn't have
+ * bad side effects.
+ */
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
+ spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
} else if (rc == 0) {
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
ccw_device_set_timeout(cdev, timeout);
init_MUTEX(&irq_ptr->setting_up_sema);
+ /* QDR must be in DMA area since CCW data address is only 32 bit */
irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA);
if (!(irq_ptr->qdr)) {
kfree(irq_ptr);