@@ -542,11 +542,10 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
542542{
543543 struct qeth_reply * reply ;
544544
545- reply = kzalloc (sizeof (struct qeth_reply ), GFP_ATOMIC );
545+ reply = kzalloc (sizeof (* reply ), GFP_KERNEL );
546546 if (reply ) {
547547 refcount_set (& reply -> refcnt , 1 );
548- atomic_set (& reply -> received , 0 );
549- init_waitqueue_head (& reply -> wait_q );
548+ init_completion (& reply -> received );
550549 }
551550 return reply ;
552551}
@@ -578,8 +577,7 @@ static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply)
578577
579578static void qeth_notify_reply (struct qeth_reply * reply )
580579{
581- atomic_inc (& reply -> received );
582- wake_up (& reply -> wait_q );
580+ complete (& reply -> received );
583581}
584582
585583static void qeth_issue_ipa_msg (struct qeth_ipa_cmd * cmd , int rc ,
@@ -704,6 +702,7 @@ static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel)
704702 do {
705703 if (channel -> iob [index ].state == BUF_STATE_FREE ) {
706704 channel -> iob [index ].state = BUF_STATE_LOCKED ;
705+ channel -> iob [index ].timeout = QETH_TIMEOUT ;
707706 channel -> io_buf_no = (channel -> io_buf_no + 1 ) %
708707 QETH_CMD_BUFFER_NO ;
709708 memset (channel -> iob [index ].data , 0 , QETH_BUFSIZE );
@@ -1786,8 +1785,7 @@ static int qeth_idx_activate_get_answer(struct qeth_card *card,
17861785 iob -> callback = reply_cb ;
17871786 qeth_setup_ccw (channel -> ccw , CCW_CMD_READ , QETH_BUFSIZE , iob -> data );
17881787
1789- wait_event (card -> wait_q ,
1790- atomic_cmpxchg (& channel -> irq_pending , 0 , 1 ) == 0 );
1788+ wait_event (card -> wait_q , qeth_trylock_channel (channel ));
17911789 QETH_DBF_TEXT (SETUP , 6 , "noirqpnd" );
17921790 spin_lock_irq (get_ccwdev_lock (channel -> ccwdev ));
17931791 rc = ccw_device_start_timeout (channel -> ccwdev , channel -> ccw ,
@@ -1855,8 +1853,7 @@ static int qeth_idx_activate_channel(struct qeth_card *card,
18551853 temp = (card -> info .cula << 8 ) + card -> info .unit_addr2 ;
18561854 memcpy (QETH_IDX_ACT_QDIO_DEV_REALADDR (iob -> data ), & temp , 2 );
18571855
1858- wait_event (card -> wait_q ,
1859- atomic_cmpxchg (& channel -> irq_pending , 0 , 1 ) == 0 );
1856+ wait_event (card -> wait_q , qeth_trylock_channel (channel ));
18601857 QETH_DBF_TEXT (SETUP , 6 , "noirqpnd" );
18611858 spin_lock_irq (get_ccwdev_lock (channel -> ccwdev ));
18621859 rc = ccw_device_start_timeout (channel -> ccwdev , channel -> ccw ,
@@ -2034,9 +2031,9 @@ static int qeth_send_control_data(struct qeth_card *card, int len,
20342031 void * reply_param )
20352032{
20362033 struct qeth_channel * channel = iob -> channel ;
2034+ long timeout = iob -> timeout ;
20372035 int rc ;
20382036 struct qeth_reply * reply = NULL ;
2039- unsigned long timeout , event_timeout ;
20402037 struct qeth_ipa_cmd * cmd = NULL ;
20412038
20422039 QETH_CARD_TEXT (card , 2 , "sendctl" );
@@ -2057,27 +2054,30 @@ static int qeth_send_control_data(struct qeth_card *card, int len,
20572054 qeth_get_reply (reply );
20582055 iob -> reply = reply ;
20592056
2060- while (atomic_cmpxchg (& channel -> irq_pending , 0 , 1 )) ;
2057+ timeout = wait_event_interruptible_timeout (card -> wait_q ,
2058+ qeth_trylock_channel (channel ),
2059+ timeout );
2060+ if (timeout <= 0 ) {
2061+ qeth_put_reply (reply );
2062+ qeth_release_buffer (channel , iob );
2063+ return (timeout == - ERESTARTSYS ) ? - EINTR : - ETIME ;
2064+ }
20612065
20622066 if (IS_IPA (iob -> data )) {
20632067 cmd = __ipa_cmd (iob );
20642068 cmd -> hdr .seqno = card -> seqno .ipa ++ ;
20652069 reply -> seqno = cmd -> hdr .seqno ;
2066- event_timeout = QETH_IPA_TIMEOUT ;
20672070 } else {
20682071 reply -> seqno = QETH_IDX_COMMAND_SEQNO ;
2069- event_timeout = QETH_TIMEOUT ;
20702072 }
20712073 qeth_prepare_control_data (card , len , iob );
20722074
20732075 qeth_enqueue_reply (card , reply );
20742076
2075- timeout = jiffies + event_timeout ;
2076-
20772077 QETH_CARD_TEXT (card , 6 , "noirqpnd" );
20782078 spin_lock_irq (get_ccwdev_lock (channel -> ccwdev ));
20792079 rc = ccw_device_start_timeout (channel -> ccwdev , channel -> ccw ,
2080- (addr_t ) iob , 0 , 0 , event_timeout );
2080+ (addr_t ) iob , 0 , 0 , timeout );
20812081 spin_unlock_irq (get_ccwdev_lock (channel -> ccwdev ));
20822082 if (rc ) {
20832083 QETH_DBF_MESSAGE (2 , "qeth_send_control_data on device %x: ccw_device_start rc = %i\n" ,
@@ -2091,30 +2091,16 @@ static int qeth_send_control_data(struct qeth_card *card, int len,
20912091 return rc ;
20922092 }
20932093
2094- /* we have only one long running ipassist, since we can ensure
2095- process context of this command we can sleep */
2096- if (cmd && cmd -> hdr .command == IPA_CMD_SETIP &&
2097- cmd -> hdr .prot_version == QETH_PROT_IPV4 ) {
2098- if (!wait_event_timeout (reply -> wait_q ,
2099- atomic_read (& reply -> received ), event_timeout ))
2100- goto time_err ;
2101- } else {
2102- while (!atomic_read (& reply -> received )) {
2103- if (time_after (jiffies , timeout ))
2104- goto time_err ;
2105- cpu_relax ();
2106- }
2107- }
2094+ timeout = wait_for_completion_interruptible_timeout (& reply -> received ,
2095+ timeout );
2096+ if (timeout <= 0 )
2097+ rc = (timeout == - ERESTARTSYS ) ? - EINTR : - ETIME ;
21082098
21092099 qeth_dequeue_reply (card , reply );
2110- rc = reply -> rc ;
2100+ if (!rc )
2101+ rc = reply -> rc ;
21112102 qeth_put_reply (reply );
21122103 return rc ;
2113-
2114- time_err :
2115- qeth_dequeue_reply (card , reply );
2116- qeth_put_reply (reply );
2117- return - ETIME ;
21182104}
21192105
21202106static int qeth_cm_enable_cb (struct qeth_card * card , struct qeth_reply * reply ,
@@ -2810,6 +2796,8 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
28102796 u16 total_length = IPA_PDU_HEADER_SIZE + cmd_length ;
28112797 u8 prot_type = qeth_mpc_select_prot_type (card );
28122798
2799+ iob -> timeout = QETH_IPA_TIMEOUT ;
2800+
28132801 memcpy (iob -> data , IPA_PDU_HEADER , IPA_PDU_HEADER_SIZE );
28142802 memcpy (QETH_IPA_PDU_LEN_TOTAL (iob -> data ), & total_length , 2 );
28152803 memcpy (QETH_IPA_CMD_PROT_TYPE (iob -> data ), & prot_type , 1 );
0 commit comments