@@ -107,10 +107,10 @@ static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card)
107107 * Spin lock is needed because this can be called in atomic/interrupt
108108 * context.
109109 */
110- spin_lock_bh (& card -> creg_ctrl .pop_lock );
110+ spin_lock_bh (& card -> creg_ctrl .lock );
111111 cmd = card -> creg_ctrl .active_cmd ;
112112 card -> creg_ctrl .active_cmd = NULL ;
113- spin_unlock_bh (& card -> creg_ctrl .pop_lock );
113+ spin_unlock_bh (& card -> creg_ctrl .lock );
114114
115115 return cmd ;
116116}
@@ -126,7 +126,11 @@ static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd)
126126 cmd -> buf , cmd -> stream );
127127 }
128128
129- /* Data copy must complete before initiating the command. */
129+ /*
130+ * Data copy must complete before initiating the command. This is
131+ * needed for weakly ordered processors (i.e. PowerPC), so that all
132+ * neccessary registers are written before we kick the hardware.
133+ */
130134 wmb ();
131135
132136 /* Setting the valid bit will kick off the command. */
@@ -192,11 +196,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card,
192196 cmd -> cb_private = cb_private ;
193197 cmd -> status = 0 ;
194198
195- mutex_lock (& card -> creg_ctrl .lock );
199+ spin_lock (& card -> creg_ctrl .lock );
196200 list_add_tail (& cmd -> list , & card -> creg_ctrl .queue );
197201 card -> creg_ctrl .q_depth ++ ;
198202 creg_kick_queue (card );
199- mutex_unlock (& card -> creg_ctrl .lock );
203+ spin_unlock (& card -> creg_ctrl .lock );
200204
201205 return 0 ;
202206}
@@ -219,10 +223,11 @@ static void creg_cmd_timed_out(unsigned long data)
219223
220224 kmem_cache_free (creg_cmd_pool , cmd );
221225
222- spin_lock (& card -> creg_ctrl .pop_lock );
226+
227+ spin_lock (& card -> creg_ctrl .lock );
223228 card -> creg_ctrl .active = 0 ;
224229 creg_kick_queue (card );
225- spin_unlock (& card -> creg_ctrl .pop_lock );
230+ spin_unlock (& card -> creg_ctrl .lock );
226231}
227232
228233
@@ -291,10 +296,10 @@ static void creg_cmd_done(struct work_struct *work)
291296
292297 kmem_cache_free (creg_cmd_pool , cmd );
293298
294- mutex_lock (& card -> creg_ctrl .lock );
299+ spin_lock (& card -> creg_ctrl .lock );
295300 card -> creg_ctrl .active = 0 ;
296301 creg_kick_queue (card );
297- mutex_unlock (& card -> creg_ctrl .lock );
302+ spin_unlock (& card -> creg_ctrl .lock );
298303}
299304
300305static void creg_reset (struct rsxx_cardinfo * card )
@@ -303,6 +308,10 @@ static void creg_reset(struct rsxx_cardinfo *card)
303308 struct creg_cmd * tmp ;
304309 unsigned long flags ;
305310
311+ /*
312+ * mutex_trylock is used here because if reset_lock is taken then a
313+ * reset is already happening. So, we can just go ahead and return.
314+ */
306315 if (!mutex_trylock (& card -> creg_ctrl .reset_lock ))
307316 return ;
308317
@@ -315,7 +324,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
315324 "Resetting creg interface for recovery\n" );
316325
317326 /* Cancel outstanding commands */
318- mutex_lock (& card -> creg_ctrl .lock );
327+ spin_lock (& card -> creg_ctrl .lock );
319328 list_for_each_entry_safe (cmd , tmp , & card -> creg_ctrl .queue , list ) {
320329 list_del (& cmd -> list );
321330 card -> creg_ctrl .q_depth -- ;
@@ -336,7 +345,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
336345
337346 card -> creg_ctrl .active = 0 ;
338347 }
339- mutex_unlock (& card -> creg_ctrl .lock );
348+ spin_unlock (& card -> creg_ctrl .lock );
340349
341350 card -> creg_ctrl .reset = 0 ;
342351 spin_lock_irqsave (& card -> irq_lock , flags );
@@ -359,7 +368,7 @@ static void creg_cmd_done_cb(struct rsxx_cardinfo *card,
359368{
360369 struct creg_completion * cmd_completion ;
361370
362- cmd_completion = ( struct creg_completion * ) cmd -> cb_private ;
371+ cmd_completion = cmd -> cb_private ;
363372 BUG_ON (!cmd_completion );
364373
365374 cmd_completion -> st = st ;
@@ -380,7 +389,6 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card,
380389 unsigned long timeout ;
381390 int st ;
382391
383- INIT_COMPLETION (cmd_done );
384392 completion .cmd_done = & cmd_done ;
385393 completion .st = 0 ;
386394 completion .creg_status = 0 ;
@@ -390,8 +398,13 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card,
390398 if (st )
391399 return st ;
392400
401+ /*
402+ * This timeout is neccessary for unresponsive hardware. The additional
403+ * 20 seconds to used to guarantee that each cregs requests has time to
404+ * complete.
405+ */
393406 timeout = msecs_to_jiffies ((CREG_TIMEOUT_MSEC *
394- card -> creg_ctrl .q_depth ) + 20000 );
407+ card -> creg_ctrl .q_depth ) + 20000 );
395408
396409 /*
397410 * The creg interface is guaranteed to complete. It has a timeout
@@ -443,7 +456,7 @@ static int issue_creg_rw(struct rsxx_cardinfo *card,
443456 if (st )
444457 return st ;
445458
446- data = (void * )(( char * )data + xfer ) ;
459+ data = (char * )data + xfer ;
447460 addr += xfer ;
448461 size8 -= xfer ;
449462 } while (size8 );
@@ -558,9 +571,9 @@ static void hw_log_msg(struct rsxx_cardinfo *card, const char *str, int len)
558571}
559572
560573/*
561- * The substrncpy() function copies to string(up to count bytes) point to by src
562- * (including the terminating '\0' character) to dest. Returns the number of
563- * bytes copied to dest.
574+ * The substrncpy function copies the src string (which includes the
575+ * terminating '\0' character), up to the count into the dest pointer.
576+ * Returns the number of bytes copied to dest.
564577 */
565578static int substrncpy (char * dest , const char * src , int count )
566579{
@@ -657,6 +670,9 @@ int rsxx_reg_access(struct rsxx_cardinfo *card,
657670 if (st )
658671 return - EFAULT ;
659672
673+ if (cmd .cnt > RSXX_MAX_REG_CNT )
674+ return - EFAULT ;
675+
660676 st = issue_reg_cmd (card , & cmd , read );
661677 if (st )
662678 return st ;
@@ -682,8 +698,7 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card)
682698 INIT_WORK (& card -> creg_ctrl .done_work , creg_cmd_done );
683699 mutex_init (& card -> creg_ctrl .reset_lock );
684700 INIT_LIST_HEAD (& card -> creg_ctrl .queue );
685- mutex_init (& card -> creg_ctrl .lock );
686- spin_lock_init (& card -> creg_ctrl .pop_lock );
701+ spin_lock_init (& card -> creg_ctrl .lock );
687702 setup_timer (& card -> creg_ctrl .cmd_timer , creg_cmd_timed_out ,
688703 (unsigned long ) card );
689704
@@ -697,7 +712,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
697712 int cnt = 0 ;
698713
699714 /* Cancel outstanding commands */
700- mutex_lock (& card -> creg_ctrl .lock );
715+ spin_lock (& card -> creg_ctrl .lock );
701716 list_for_each_entry_safe (cmd , tmp , & card -> creg_ctrl .queue , list ) {
702717 list_del (& cmd -> list );
703718 if (cmd -> cb )
@@ -722,7 +737,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
722737 "Canceled active creg command\n" );
723738 kmem_cache_free (creg_cmd_pool , cmd );
724739 }
725- mutex_unlock (& card -> creg_ctrl .lock );
740+ spin_unlock (& card -> creg_ctrl .lock );
726741
727742 cancel_work_sync (& card -> creg_ctrl .done_work );
728743}
0 commit comments