@ -90,6 +90,8 @@ module_param(tubxcorrect, bool, 0);
*/
DECLARE_WAIT_QUEUE_HEAD ( raw3270_wait_queue ) ;
static void __raw3270_disconnect ( struct raw3270 * rp ) ;
/*
* Encode array for 12 bit 3270 addresses .
*/
@ -336,8 +338,11 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
set_bit ( RAW3270_FLAGS_BUSY , & rp - > flags ) ;
/* Handle disconnected devices */
if ( ( irb - > scsw . cmd . dstat & DEV_STAT_UNIT_CHECK ) & &
( irb - > ecw [ 0 ] & SNS0_INTERVENTION_REQ ) )
( irb - > ecw [ 0 ] & SNS0_INTERVENTION_REQ ) ) {
set_bit ( RAW3270_FLAGS_BUSY , & rp - > flags ) ;
if ( rp - > state > RAW3270_STATE_RESET )
__raw3270_disconnect ( rp ) ;
}
/* Call interrupt handler of the view */
if ( view )
view - > fn - > intv ( view , rq , irb ) ;
@ -347,8 +352,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* Device busy, do not start I/O */
return ;
if ( rq ) {
BUG_ON ( list_empty ( & rq - > list ) ) ;
if ( rq & & ! list_empty ( & rq - > list ) ) {
/* The request completed, remove from queue and do callback. */
list_del_init ( & rq - > list ) ;
if ( rq - > callback )
@ -634,6 +638,28 @@ raw3270_reset(struct raw3270_view *view)
return rc ;
}
static void
__raw3270_disconnect ( struct raw3270 * rp )
{
struct raw3270_request * rq ;
struct raw3270_view * view ;
rp - > state = RAW3270_STATE_INIT ;
rp - > view = & rp - > init_view ;
/* Cancel all queued requests */
while ( ! list_empty ( & rp - > req_queue ) ) {
rq = list_entry ( rp - > req_queue . next , struct raw3270_request , list ) ;
view = rq - > view ;
rq - > rc = - EACCES ;
list_del_init ( & rq - > list ) ;
if ( rq - > callback )
rq - > callback ( rq , rq - > callback_data ) ;
raw3270_put_view ( view ) ;
}
/* Start from scratch */
__raw3270_reset_device ( rp ) ;
}
static void
raw3270_init_irq ( struct raw3270_view * view , struct raw3270_request * rq ,
struct irb * irb )